re: sweep the disc for the ordinal foot-gun -- GP_TITLE was the mildest case
Last iteration I retracted three claims because `--build 10/11` on GP_TITLE are entries 12/15, and named the untested remainder in my own report: how much else in the corpus used a build ordinal as an entry index. This is that sweep. `screen --build N` indexes a predicate-filtered list, so every rejected entry shifts every later ordinal. Disc-wide: 21 of 24 build-bearing archives diverge, 18 of them at ordinal 0 -- `--build 0` is entry 108 in each GP_MAIN_GAME_*2D, 24/26 in GP_HANGAR_ARSENAL/GP_READY_ROOM. GP_TITLE is the ONLY archive whose first ten ordinals are the identity, which is the sole reason 207 of the corpus's 226 build citations are safe. Second foot-gun: `--all` swaps the predicate and renumbers 18 archives, so `--build N` and `--build N --all` are not the same object. The instrument failed its control first. A version using parse_build as the predicate reported GP_TITLE as 16 builds, ordinal == entry throughout -- it would have certified the exact bug it was built to find. The shipped version uses the same predicates screen_builds() uses and reproduces `screen list` on GP_TITLE exactly. Audited all 226 citations. One real defect: a five-row table in ui-keyframe-time-unit.md headed "declared element (build 11)" spans builds 10 and 11 -- palogo_sqex is in 10. All five placements re-verified and correct, so the linear-ramp measurement is untouched; only the label was wrong. Fixed with a per-row bundle column. GP_DIALOG --build 0 and GP_DEBRIEFING_PILOTLOG --build 10 re-run and reproduce. Refutation attempted: sylpheed-port's corrected mid-ramp test rests on ptlogo_all_eff holding a=127 from t=112 to t=246. Their quote is exact and it is a plateau. The refutation fails; their correction stands. METHOD already carried the rule I broke, and ui-splash-addressing already said the splashes need --all. The failure was not missing knowledge -- it was addressing a bundle by index without grepping for the index first. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
@@ -35,6 +35,7 @@ Promote to a prose `structures/…md` file when a format needs behavioural notes
|
||||
| Scripted input / profile traps | ✅/🟡 | [canary-scripted-input-traps](canary-scripted-input-traps.md) | Why a scripted run appears unable to press Ⓐ: **F10 opens the emulator menu bar**, and any Xenia UI makes `XamInputGetKeystrokeEx` return SUCCESS with an empty keystroke *before* any driver is asked (Canary now logs `[RE-INPUT] … swallowed by IsUIActive`); the title needs a **signed-in profile** (hence `--create_profile_if_none`); and a **FIFO trace consumer that exits stalls the emulator**, which reads exactly like a dead pad. 🟡 The main menu HAS been reached — Ⓐ works, but only intermittently (1 in ~4), which is the open question |
|
||||
| Title-screen guest crash | ✅ | [title-crash-stl-tree](title-crash-stl-tree.md) | The guest throws **`std::out_of_range`** from its cache-manager flush (`sub_823070B0`, an STL map/set erase that builds `'invalid map/set<T> iterator'`); the access violation after it is only the throw **returning**, because this build does not unwind guest EH. Trigger found and controlled: an **incomplete on-disc cache** (`~/.local/share/Xenia/cache/aab216c3`) throws ~100 s into a boot, a complete one never does — 2 runs each way. ❌ `mem_watch`, the handoff's suspect #1, is **eliminated**: cold cache + `--mem_watch=false` throws anyway |
|
||||
| Save file (`savedata`) | ✅/❔ | [savegame-format](structures/savegame-format.md) + [`tools/re-capture/savegame.py`](../../tools/re-capture/savegame.py) | `GDHA` container, zlib payload, chunk stream (`GDAA` / phase name / `GHAD` 122 B progress block / 16×20 B slot table / trailer). **Container and layout read off the title's own serializer `0x822C00E8` and verified by a byte-identical round-trip**; the whole save is 545 B. Payload offsets are also the live save object's offsets (`save+8` GHAD, `save+136` slots). A second save made in-game names **Points** (+24), **flight time in ms** (+4) and **clear ratio %** (+8) off the game's own Details panel; the payload is a **pure function of game state** (same state saved twice = byte-identical, only the header FILETIME and its uninitialised pointer padding move), and the 16 `SHAB` records are **not** the UI's 20 save slots. Difficulty vs stage is undecided — three fields hold 2. **A third save, taken after developing exactly one Arsenal weapon** (Light Machine Gun MG I, 4000 P), moves exactly three things: `+24` Points 4101→101 (which **separates it from `+28`**, that did not move), `+8` clear ratio 5→6 (so the ratio counts *collection*, not only stages), and two entries of the 54-byte blob — `2→4` for the item bought and `0→2` for the successor the game announced as newly developable, giving the blob its alphabet ✅ *0 locked / 2 developable / 4 developed* (only the `4`s are stored — `2` is re-derived at load). **Saves can also be written back**: three derived header fields (length at `+0x30`, payload length at `+0x8c`, `adler32` at `+0x8e`) are all that stand between a parse and a hand-written save that the title loads, and [`savegame_edit.py`](../../tools/re-capture/savegame_edit.py) re-wraps a real save byte-identically. That turned the blob's index space from blocked-on-story-progress into four probe saves — see the [economy note](arsenal-develop-economy.md) |
|
||||
| `--build N` addressing (ordinal vs pak entry) | ✅ | [build-ordinal-vs-entry](structures/build-ordinal-vs-entry.md) + [`data/ordinal-entry-map.txt`](data/ordinal-entry-map.txt) | `screen --build N` indexes a **predicate-filtered list**, not the pak. Disc-wide: **21 of 24** build-bearing archives diverge, **18 at ordinal 0** — `--build 0` is entry **108** in each `GP_MAIN_GAME_*2D`, entry 24/26 in `GP_HANGAR_ARSENAL`/`GP_READY_ROOM`. `GP_TITLE` is the **only** archive whose ordinals 0–9 are the identity, which is the sole reason 207 of the corpus's 226 build citations are safe. ⚠️ `--all` swaps the predicate and **renumbers 18 archives**, so `--build N` and `--build N --all` differ. Instrument controlled against the CLI's own `screen list` on `GP_TITLE` (12 builds, `[10]→12`, `[11]→15`) — a first version using `parse_build` as the predicate **failed** that control, reporting ordinal==entry throughout. Audit of all 226 citations: 1 defect found and fixed (a five-row table in `ui-keyframe-time-unit.md` labelled "build 11" spanned builds 10 and 11 — placements all correct, only the label wrong); `GP_DIALOG --build 0` and `GP_DEBRIEFING_PILOTLOG --build 10` re-run and reproduce |
|
||||
|
||||
## Runtime / dynamic-capture technique
|
||||
|
||||
|
||||
Reference in New Issue
Block a user