feat(phase-b): boot data tables — play --boot runs *INIT into session state
All 9 *INIT scripts run clean and populate the game's data tables into the global bank. play --boot prepends them before scenes so scenes see real skill/item/unit/map/stage state (23646 globals for SC0000). Test cross-checks the VM's SKINIT population against the static extraction (build/data/SKINIT.json: skill 0 '飛行'@0x23a3, G[0xa6e5b]=30) — validates both the VM and extract_init. Engine 16/16. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -66,11 +66,17 @@ if (args[0] == "gfx")
|
||||
|
||||
if (args[0] == "play")
|
||||
{
|
||||
// play <SCENE.BIN...> [0xADDR=VAL ...] — run a sequence of scenes carrying persistent global state
|
||||
// across them (optional up-front seeds). The state substrate for cross-scene flow; headless.
|
||||
// play [--boot] <SCENE.BIN...> [0xADDR=VAL ...] — run a sequence of scenes carrying persistent global
|
||||
// state across them (optional up-front seeds). --boot first runs the data-table *INIT scripts so scenes
|
||||
// see the real skill/item/unit/etc. state. The state substrate for cross-scene flow; headless.
|
||||
// The *INIT boot set — all run clean (halt: exit) and populate the game's data tables into globals.
|
||||
string[] bootScripts = { "SKINIT.BIN", "ITINIT.BIN", "EBINIT.BIN", "CGINIT.BIN", "MPINIT.BIN",
|
||||
"AFINIT.BIN", "CCINIT.BIN", "STINIT.BIN", "STINIT2.BIN" };
|
||||
var scripts = Paths.Scripts();
|
||||
var scenes = args.Skip(1).Where(a => a.ToUpperInvariant().EndsWith(".BIN")).ToList();
|
||||
if (scenes.Count == 0) { Console.WriteLine("usage: play <SCENE.BIN...> [0xADDR=VAL ...]"); return 1; }
|
||||
bool boot = args.Contains("--boot");
|
||||
var userScenes = args.Skip(1).Where(a => a.ToUpperInvariant().EndsWith(".BIN")).ToList();
|
||||
if (userScenes.Count == 0) { Console.WriteLine("usage: play [--boot] <SCENE.BIN...> [0xADDR=VAL ...]"); return 1; }
|
||||
var scenes = (boot ? bootScripts.Concat(userScenes) : userScenes).ToList();
|
||||
var session = new GameSession();
|
||||
foreach (var s in args.Skip(1).Where(a => a.Contains('=')))
|
||||
{
|
||||
|
||||
@@ -76,6 +76,20 @@ public class GameSessionTests
|
||||
Assert.Equal("exit", r.Halt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BootingSkinitPopulatesDataTableGlobals()
|
||||
{
|
||||
// Running the SKINIT data script through the session populates the real skill table into the
|
||||
// global bank (the game's boot behavior). Cross-check vs the static extraction (build/data/SKINIT.json):
|
||||
// skill 0 = "飛行" at global-string 0x23a3, field G[0xa6e5b] = 30.
|
||||
var session = new GameSession();
|
||||
var r = session.RunScene(Sys4Loader.Load(Paths.Scripts()["SKINIT.BIN"], Table), Table, new CaptureHost());
|
||||
Assert.Equal("exit", r.Halt);
|
||||
Assert.Equal("飛行", session.GlobalStrings[0x23a3]);
|
||||
Assert.Equal(30, session.Globals[0xa6e5b]);
|
||||
Assert.True(session.Globals.Count > 1000, $"SKINIT should populate the skill table (got {session.Globals.Count})");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SeedingFormFlagChangesBehavior()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user