feat(master): watch world zone files and replace instances that loaded old ones

Master hashes each reported file on a worker, polls size and mtime every
world_watch_seconds (a change must hold still for one poll), and replaces
stale instances with the instance migration (Mythran shift, or seamless
with world_reload_seamless=1); empty ones are stopped. Also on WORLD_RELOAD.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-30 02:44:16 -05:00
parent ab395a1af9
commit 16545d573e
9 changed files with 965 additions and 1 deletions

View File

@@ -141,6 +141,8 @@ namespace {
c.Add(Unit(Int(MASTER, "live_update_warn_seconds", "Warning before moving players", "The game's Mythran maintenance warning is shown this long before players are moved. The dashboard can pick another for one update.", "10", 0, 300), "seconds"));
c.Add(Int(MASTER, "live_update_parallel_worlds", "Worlds at once", "World instances replaced at the same time.", "4", 1, 64));
c.Add(Int(MASTER, "cdclient_watch_seconds", "CDClient watch interval", "Seconds between checks of the client's cdclient.fdb for changes; a change reloads it on every server. 0 turns the check off (/reloadcdclient still works).", "5", 0, 3600));
c.Add(Int(MASTER, "world_watch_seconds", "World file watch interval", "Seconds between checks of the zone files running worlds loaded (.luz, .lvl, .lutriggers, terrain, navmesh). A change replaces the instances that loaded the old version with new ones and moves their players over. 0 turns the check off (/reloadworld and the dashboard's Reload still work).", "5", 0, 3600));
c.Add(Bool(MASTER, "world_reload_seamless", "Seamless world reloads", "Move players to a reloaded world with the experimental seamless mode (no loading screen) instead of the Mythran shift. Untested with the real client.", false));
c.Add(Unit(Int(MASTER, "live_update_player_wait", "Wait for busy players", "Players who are dead or building are moved once they are done, or after this long.", "30", 0, 600), "seconds"));
c.Add(Unit(Int(MASTER, "live_update_property_build_wait", "Wait for property builders", "A property is saved for its new instance once nobody builds there, or after this long (they leave build mode then).", "60", 0, 600), "seconds"));
c.Add(Unit(Int(MASTER, "live_update_char_select_wait", "Wait at character select", "Players picking a character get this long to go in by themselves; then they are moved to the new character select.", "60", 0, 3600), "seconds"));