diff options
| author | historia <[not public]> | 2026-09-15 15:35:52 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-15 15:35:52 -0400 |
| commit | 0b0b25222b3131ada79ff78c28eb8bf07d977deb (patch) | |
| tree | 2ceaef5203595044f66a8f00064cd8e017f8f48d /internal/game/exit_migrate.go | |
| parent | 396c3facb8287b9a34076cae8f3d7b300d366d99 (diff) | |
| download | thehouseoficarus-0b0b25222b3131ada79ff78c28eb8bf07d977deb.tar.gz | |
feat: single-owner game state, transactional lifecycle, durable money on server stop
Diffstat (limited to 'internal/game/exit_migrate.go')
| -rw-r--r-- | internal/game/exit_migrate.go | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/internal/game/exit_migrate.go b/internal/game/exit_migrate.go index ff905f6..db70c8d 100644 --- a/internal/game/exit_migrate.go +++ b/internal/game/exit_migrate.go @@ -112,11 +112,11 @@ func rekeyIntMap[V any](m map[int]V, idMap map[int]int) bool { return true } -// RewriteRoomIDs is the shared entry point called by every room-ID change path -// (the swapid command and the admin web GUI rename) to migrate room-ID-embedded +// RewriteRoomIDs is the shared entry point called by every room-ID change +// path (the swapid command and the admin web GUI rename) to migrate room-ID-embedded // state across all characters. Online players are updated in memory (and -// re-saved); offline characters are loaded, rewritten, and saved. It follows -// the same cross-goroutine mutation precedent as cmd_undig/cmd_summon. +// re-saved); offline characters are loaded, rewritten, and saved. Callers +// must be on the owner goroutine (use MigrateRoomIDs from other goroutines). func (g *Game) RewriteRoomIDs(idMap map[int]int) { if len(idMap) == 0 { return @@ -150,3 +150,34 @@ func (g *Game) RewriteRoomIDs(idMap map[int]int) { } } } + +// MigrateRoomIDs is the complete room-ID migration entry point for other +// goroutines (the admin API and swapid command): player state, Hub room +// buckets, casino room keys, world room-keyed runtime state, and live mob +// instances all move together under one owner task. This is what makes a +// live rename leave NO gameplay or broadcast attached to the old location. +func (g *Game) MigrateRoomIDs(idMap map[int]int) { + if len(idMap) == 0 { + return + } + g.RunOnOwner(func() { + g.migrateRoomIDsLocked(idMap) + }) +} + +// migrateRoomIDsLocked performs the full runtime migration; caller must +// already be on the owner goroutine. +func (g *Game) migrateRoomIDsLocked(idMap map[int]int) { + if g.Hub != nil { + g.Hub.RekeyRooms(idMap) + } + if g.Casino != nil { + g.Casino.RekeyRooms(idMap) + } + g.World.RekeyRooms(idMap) + g.MobStore.RekeyRooms(idMap) + // The file paths changed under the world: rebuild its room index so + // lookups agree with the post-migration layout. + g.World.RebuildRoomIndex(g.DataDir) + g.RewriteRoomIDs(idMap) +} |
