re: the stage drift is navigation, not the save -- slot 01 is deterministically Stage 02
Refutes my own claim from the previous commit that slot 01 is an auto-save whose restored mission drifts. savedata has not been written since 2026-08-23; every run today left it untouched (only the .gpd profile files moved), and there is exactly one save, so a wandering save-list cursor cannot explain it either. Decoded the save statically (GDHA + zlib at 0x92, 545 bytes): only SHAB record 0 carries clear data, records 1-15 are zeroed. Three independent readings agree it is Stage 02 -- the 324773 ms clear time is the 05:24.77 that SESSION-2026-08-11 documents for Stage 01, the 4101 points match weapon-datasheet-runtime.md's "Stage 02, At Standby, 5% clear, 4101 P", and the GHAD block at tag+8 gives +52 = 2. Stage 02 is the Acropolis escort mission, which is exactly the roster the last run produced. So the odd run out was the S01 "Glasner Training Area" one -- a TUTORIAL, reached because the nav issued dpad-down + A from a state never confirmed to be the main menu. Fix is two guards: verify screen_id reads `menu` immediately before the dpad, and assert Acropolis is in the definition table before comparing rosters. Caveats kept: the GHAD field base was not isolated by the search (7 candidates, 3 giving stage 2 -- tag+8 chosen because it agrees with the other two readings), and the tutorial mis-selection was not demonstrated by re-running the emulator.
This commit is contained in:
85
docs/re/stage-drift-is-navigation-not-save.md
Normal file
85
docs/re/stage-drift-is-navigation-not-save.md
Normal file
@@ -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.
|
||||||
Reference in New Issue
Block a user