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/migrate_rooms_test.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/migrate_rooms_test.go')
| -rw-r--r-- | internal/game/migrate_rooms_test.go | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/internal/game/migrate_rooms_test.go b/internal/game/migrate_rooms_test.go new file mode 100644 index 0000000..eb4a44c --- /dev/null +++ b/internal/game/migrate_rooms_test.go @@ -0,0 +1,115 @@ +package game + +// Runtime room-ID migration regressions: Hub buckets, casino room keys, +// world room-keyed state, mob instances, and player state all move +// together through Game.MigrateRoomIDs (owner-executed). + +import ( + "testing" + + "thehouseoficarus/internal/casino" +) + +// TestMigrateRoomIDsMovesEverythingTogether: a live player in room 2, a +// casino machine in room 2, and seeded world state all migrate to room 4 +// in one owner task; nothing stays attached to room 2. +func TestMigrateRoomIDsMovesEverythingTogether(t *testing.T) { + h := newHarness(t) + h.seedAccount("alice", "pw", false) + p := h.seedCharacter("alice", "alice") + sess, _ := h.connect("alice") + p = sess.Player + + h.g.RunOnOwner(func() { + p.RoomID = 2 + h.hub.EnterRoom(sess, 2) + // A machine in room 2 with a committed stake. + h.g.Casino.JoinMachine(2, casino.MachineConfig{ID: "slots", Game: casino.GameSlots, MinBet: 1}, "alice") + }) + + // Migrate 2 -> 4 through the full runtime entry point. + h.g.MigrateRoomIDs(map[int]int{2: 4}) + h.barrier() + + h.g.RunOnOwner(func() { + if p.RoomID != 4 { + t.Fatalf("player room = %d, want 4", p.RoomID) + } + if room := h.hub.PlayersInRoom(4); len(room) != 1 || room[0] != sess { + t.Fatalf("hub bucket for room 4 = %v, want [alice]", len(room)) + } + if room := h.hub.PlayersInRoom(2); len(room) != 0 { + t.Fatalf("stale hub bucket for room 2: %d players", len(room)) + } + if _, playing := h.g.Casino.Participation("alice"); !playing { + t.Fatal("casino participation lost during migration") + } + // The machine's events must route to room 4 now: emit one and + // check the room target. + machine, ok := h.g.Casino.MachineFor("alice") + if !ok { + t.Fatal("machine lost during migration") + } + if machine.RoomID != 4 { + t.Fatalf("machine room = %d, want 4", machine.RoomID) + } + }) +} + +// TestMigrateRoomIDsRoundTrip preserves participation both directions. +func TestMigrateRoomIDsRoundTrip(t *testing.T) { + h := newHarness(t) + h.seedAccount("alice", "pw", false) + h.seedCharacter("alice", "alice") + sess, _ := h.connect("alice") + p := sess.Player + + h.g.RunOnOwner(func() { + p.RoomID = 3 + h.hub.EnterRoom(sess, 3) + }) + h.g.MigrateRoomIDs(map[int]int{3: 9}) + h.g.RunOnOwner(func() { + if p.RoomID != 9 { + t.Fatalf("forward migration: player room = %d, want 9", p.RoomID) + } + }) + h.g.MigrateRoomIDs(map[int]int{9: 3}) + h.g.RunOnOwner(func() { + if p.RoomID != 3 { + t.Fatalf("inverse migration: player room = %d, want 3", p.RoomID) + } + if room := h.hub.PlayersInRoom(3); len(room) != 1 { + t.Fatalf("inverse migration: hub bucket room 3 = %d players", len(room)) + } + }) +} + +// TestMigrateRoomIDsPersistsOnlinePlayer: the migrated player state is +// saved to disk (RoomID rewritten in the character file). +func TestMigrateRoomIDsPersistsOnlinePlayer(t *testing.T) { + h := newHarness(t) + h.seedAccount("alice", "pw", false) + h.seedCharacter("alice", "alice") + sess, _ := h.connect("alice") + p := sess.Player + + h.g.RunOnOwner(func() { + p.RoomID = 2 + p.Flags["hidden_exit_2_north"] = true + h.hub.EnterRoom(sess, 2) + }) + h.g.MigrateRoomIDs(map[int]int{2: 4}) + h.barrier() + + loaded, err := h.g.AccountStore.LoadCharacter("alice") + if err != nil { + t.Fatal(err) + } + if loaded.RoomID != 4 { + t.Fatalf("saved room = %d, want 4", loaded.RoomID) + } + if _, ok := loaded.Flags["hidden_exit_4_north"]; !ok { + t.Fatalf("discovered-exit flag not rewritten: %v", loaded.Flags) + } +} |
