re: the unit loader was already in the corpus (sub_82341A20), and 0-xref does not mean no reader

Item "what loads the 114 unit Maneuver records" -- the corpus already answers it,
and I should have found that before framing it as new.  My own error, corrected:
I claimed live-unit-definitions.md did not exist.  It does, at docs/re/, not under
structures/.  Looking in one directory is not looking.

sub_82341A20 is the unit-definition loader, documented in unit-struct-runtime.md
with a checked-in 177-line layout at
crates/sylpheed-formats/data/unit_definition_layout.txt.  Verified independently:
3969 instructions, 227 of its 236 "addi rX, r30, -N" displacements resolve to
strings -- the unit schema in order, Generic, UncertainName, IsDestructible,
NamePlate, Size_X/Y/Z ...  Maneuver sits at exactly 0x82088F94 - 13404.

Record keys are tag_hash, confirmed on the data side: the Maneuver record's key is
0x43FAA517 = tag_hash("Maneuver"), not name_hash (0x63A248D7), x114 records.

That explains the 0-xref phenomenon and softens my own verdict from last
iteration.  Maneuver's string has 0 xrefs AND a known reader: the loader takes its
address as a register-passed base plus a displacement, which no static xref can
see.  So the AnalogRevice/Tweak verdict goes from RED to AMBER -- a
base-plus-displacement sweep over the 2283 functions forming the 0x820A high half
reaches it 0 times, but run against the unit block as a control the same sweep
recovers only 5 references and misses sub_82341A20 itself.  The measurement
stands; "the reader is unreachable" does not.

Also fixed: player-tuning-tables.md credited live-unit-definitions.md with
documenting sub_822F9498.  It documents sub_82341A20, a different function.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
This commit is contained in:
Claude (auto)
2026-08-27 21:02:58 +00:00
parent 909408f00d
commit 5400f5e7b5
3 changed files with 60 additions and 6 deletions

View File

@@ -103,7 +103,7 @@ files, which is how the same ground got covered twice.
| [`structures/stage-settings-table.md`](structures/stage-settings-table.md) | The per-stage settings object — Camera rigs, Player limits, Difficulty_* damage record | ✅ CONFIRMED, 24 settings objects vs 29 resource objects both using Phase_1/2/3; Camera is 13/14 fields constant; GravityFactor non-zero in 4 stages; IsBoss16Enable identifies one object; the Phase block is 94 fields of which 68 never vary between phases; all 24 objects named StageParameter_S<NN> |
| [`structures/isl-mission-timer.md`](structures/isl-mission-timer.md) | The mission timer — two sequential countdowns, not a limit and a warning | ✅ CONFIRMED — read from `sub_822639B8`; the threshold reading is |
| [`structures/archive-naming.md`](structures/archive-naming.md) | Which archives the disc can name — 100% for menu paks, **0.0%** for the six 2D paks and `GP_READY_ROOM` | ✅ CONFIRMED — 6027 names × 16 prefixes, bimodal; unnamed entries split by content — three UI paks have ZERO unnamed IDXD (artwork only), DefTables is the only real data gap (1295 LOD/motion tables); **route 2 = the `Enumerate` declaration tables** closes DefTables to 1413/1425 IDXD (99.2 %), 12 left; XPR2 manifests refuted as a naming source |
| [`structures/player-tuning-tables.md`](structures/player-tuning-tables.md) | **`PlayerParams`** — the player parameter table: `Booster` flight model, special attacks, 8 analog curves, the S16 boss | ✅✅ `sub_822F9498` is `PlayerParams`'s loader, NOT the unit loader (90/90 strings); all 5 player craft fly identically and `Booster` differs on 10 fields; 🟡 nothing selects it and the measured flight tracks the unit `Maneuver` instead |
| [`structures/player-tuning-tables.md`](structures/player-tuning-tables.md) | **`PlayerParams`** — the player parameter table: `Booster` flight model, special attacks, 8 analog curves, the S16 boss | ✅✅ `sub_822F9498` is `PlayerParams`'s loader, NOT the unit loader `sub_82341A20` (90/90 strings); all 5 player craft fly identically, `Booster` differs on 10 fields; 🟡 nothing selects it, and the analog block has no xref — but 0-xref does not mean no reader |
| [`structures/hud-config.md`](structures/hud-config.md) | The in-game HUD configuration — 16 records, 419 asset paths, and a per-stage `ResourceTable` | ✅ CONFIRMED — 0 of 419 config paths resolve as pak entries |
| [`structures/mission-script-manifest.md`](structures/mission-script-manifest.md) | `Stage\script.tbl`'s 11 non-`MISSION` fields, and the mission dialogue table they name | ✅ CONFIRMED — 1 of 7 values resolves (`message\MissionDialogMessage.tbl`, 200 records), controls in the same sweep |
| [`structures/stage-numbering-and-player-craft.md`](structures/stage-numbering-and-player-craft.md) | The disc's stage numbering (S01S16, S18S29) and the player's craft per stage | ✅✅ CONFIRMED — two independent files close on 6 + 15 + 1 + 6 = 28 |