feat(phase-b): GameSession snapshot save/load (JSON)

ToJson/FromJson round-trip the persistent global bank; play --save-state <file>
persists it, --state <file> restores it — so an expensive booted state (23646
globals) is captured once and reused without re-running *INIT, and it's the
foundation for real save-file work. Tests: unit round-trip + booted-state
survives snapshot (skill data intact). Engine 18/18.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-07-07 00:26:23 -04:00
parent ec40fa1d37
commit f6d1384b00
3 changed files with 55 additions and 1 deletions

View File

@@ -90,6 +90,30 @@ public class GameSessionTests
Assert.True(session.Globals.Count > 1000, $"SKINIT should populate the skill table (got {session.Globals.Count})");
}
[Fact]
public void SnapshotRoundTripsState()
{
var s = new GameSession();
s.Seed(0x10, 42); s.Seed(0x20, -7); s.SeedString(0x30, "リリィ");
var t = GameSession.FromJson(s.ToJson());
Assert.Equal(42, t.Globals[0x10]);
Assert.Equal(-7, t.Globals[0x20]);
Assert.Equal("リリィ", t.GlobalStrings[0x30]);
Assert.Equal(s.Globals.Count, t.Globals.Count);
}
[Fact]
public void BootedStateSurvivesSnapshot()
{
var s = new GameSession();
s.RunScene(Sys4Loader.Load(Paths.Scripts()["SKINIT.BIN"], Table), Table, new CaptureHost());
var t = GameSession.FromJson(s.ToJson()); // snapshot the expensive booted state, rebuild
Assert.Equal("飛行", t.GlobalStrings[0x23a3]);
Assert.Equal(30, t.Globals[0xa6e5b]);
Assert.Equal(s.Globals.Count, t.Globals.Count);
Assert.Equal(s.GlobalStrings.Count, t.GlobalStrings.Count);
}
[Fact]
public void SeedingFormFlagChangesBehavior()
{