diff --git a/docs/re/stage-drift-is-navigation-not-save.md b/docs/re/stage-drift-is-navigation-not-save.md new file mode 100644 index 00000000..83fea9a4 --- /dev/null +++ b/docs/re/stage-drift-is-navigation-not-save.md @@ -0,0 +1,85 @@ +# ✅ The stage drift is my NAVIGATION, not the save — slot 01 is deterministically Stage 02 + +Settled 2026-08-26, **statically** — no emulator needed. + +## ❌ Refuted: "slot 01 is the auto-save, so the restored mission moves between runs" + +[The previous note](two-entity-enumerations.md) blamed save drift for one run +loading the S01 training area (with `UN_S01_Asteroid_cmesh_*`) and another +loading a Stage-02-style escort roster. The file says otherwise: + +``` +2026-08-23 16:37 278 .../535107D4/00000001/game01/savedata +2026-08-26 22:18 26596 .../FFFE07D1/.../535107D4.gpd +``` + +**`savedata` has not been written since 23 August.** Every run today left it +untouched; only the `.gpd` profile/achievement files moved. And there is exactly +**one** save (`game01`), so a wandering save-list cursor cannot explain it either. + +## ✅ What the save actually holds: Stage 02 + +The save is `GDHA` + a zlib payload at `0x92` (545 bytes decompressed), carrying +`GDAA`, `GHAD`, `NETA`, 2 × `BUNK` and the 16-record `SHAB` table. + +``` +rec 0 (stage 1): (2, 4101, 324773, ...) +rec 1 (stage 2): (0, 0, 0, ...) +... +rec 15 (stage 16): (0, 0, 0, ...) +``` + +**Only record 0 carries clear data**; records 1–15 have zeros in all three result +fields. Three independent readings agree on what that means: + +1. `324773` ms = **05:24.77**, which + [`SESSION-2026-08-11.md`](SESSION-2026-08-11.md) documents as exactly what + MISSION SELECT displays as the Stage 01 best time. +2. `4101` matches + [`structures/weapon-datasheet-runtime.md`](structures/weapon-datasheet-runtime.md), + whose capture session is recorded as *"Stage 02, 'At Standby', 5 % clear, + **4101 P**"* — the same save, already described in the corpus. +3. Reading the `GHAD` field block at tag+8 (i.e. past the tag and its length word) + gives `+52` = **2**, the documented 1-based `Stage` field. + +So `LOAD GAME → slot 01` restores **Stage 02** every time. It is deterministic. + +🟡 One caveat, stated rather than smoothed over: brute-forcing the `GHAD` field +base gives **seven** candidate offsets whose `+52` is a plausible stage, three of +them yielding 2. I picked tag+8 because it is the natural layout and it agrees +with the two independent readings above — not because the search isolated it. + +❌ And "stage = filled `SHAB` count + 1" must not be used: all 16 records are +*present*, and the corpus already lists that rule as **refuted**. Presence is not +filledness. + +## ✅ So the S01 asteroid run was never the save + +Stage 02 is the `Acropolis` escort mission — which is precisely the roster the +most recent run produced (`UN_f101_TCAF_Acropolis`, `UN_bf001_TCAF_SchlosBase`, +cruisers, frigates). The odd run out is the earlier one, whose briefing read +**"Glasner Training Area"** — a *tutorial*, not a story stage, and +[`structures/unit-struct-runtime.md`](structures/unit-struct-runtime.md) confirms +tutorials are separately reachable ("all six tutorials **and** Stage 02"). + +The cause is in my own driving: that run's navigation log shows the menu probe +reading `other` repeatedly and the `dpad down` + Ⓐ being issued from a state that +was not confirmed to be the main menu, so the selection landed on a tutorial +entry instead of `LOAD GAME`. The nav taps a fixed sequence and never verifies +*what it selected*. + +## Consequence — the cheap fix + +Runtime rosters are reproducible after all, provided the route is verified. Two +one-line guards, neither of which needs new tooling: + +* Confirm `screen_id.py` reads `menu` **immediately before** the `dpad down`, not + merely at some point earlier in the loop. +* After reaching flight, assert the definition table contains + `UN_f101_TCAF_Acropolis` (Stage 02's signature) before trusting any comparison + against an earlier run. + +❔ Not settled: I did not re-run the emulator to demonstrate the tutorial +mis-selection directly. The evidence here is the save file plus the earlier run's +own screen log and briefing title, which is strong but circumstantial about +*which* menu entry was hit.