confirmed three ways Chasing where the event code comes from, sub_821C5580 turned out to do two things worth having. For Q6 it arms the outer gate: li r11,3 ; stw r11,16(r28) is exactly the value sub_821C7850 tests before dispatching, which answers the "what does this+16 == 3 gate on" question I left open last iteration. It then passes r5 = [r27+4], an event read out of a structure, so the vocabulary is still not enumerable. Of the four callers of sub_821C7850, three pass constants -- 0, 0 and 5 -- and this one does not. The accident is a few instructions earlier: li r5, 1103 into a sound-play call. 1103 is a BGM cue id, BGM_103. That closes a residual I had written off as undecodable: which bank the menu plays. The cue table genuinely cannot say, since its BGM entries are numeric -- but the code can, and it checks out three independent ways. The census says BGM_103.slb is two waves of 3876864 and 3930112 bytes; the XMA probe at the main menu saw two stereo streams of 3876864 and 3930112 bytes. Byte for byte on both. That also corrects me. bgm-two-stems.md said those observed sizes matched no bank's declared waves and inferred the decoder gets a window rather than a whole wave. Wrong on both counts -- I had checked only the BGM_0xx rows of the census because that was the block on screen. METHOD gets it: check a measurement against the whole reference set, not the part you happened to be reading.
295 lines
16 KiB
Markdown
295 lines
16 KiB
Markdown
# Refuted — claims that were tested and died
|
||
|
||
**Read this before proposing a hypothesis.** Every line below was believed at
|
||
some point, measured, and found false. Reviving one costs a whole iteration and
|
||
produces nothing.
|
||
|
||
This file exists because the list had been living in the autonomous agent's
|
||
*loop prompt* — the only copy, lost the moment the container was. A refuted
|
||
result is a real result; it belongs in the corpus like any other.
|
||
|
||
**Format:** each entry is the claim as it was believed. Where the true answer is
|
||
known it follows after `→`. Grouped by subject so a grep for your noun finds the
|
||
neighbourhood, not just the line.
|
||
|
||
---
|
||
|
||
## Offsets, structs and the progress singleton
|
||
|
||
* `position = instance − 0x12c` → refuted.
|
||
* `+0x29d0` → refuted.
|
||
* "an offset intersection can find a struct's consumer" → **only for LARGE or
|
||
unusual offsets.** Small ones have no power (`+184`: 301/351/115 hits).
|
||
* "a `+1956` store means a progress write" → writes go through the COPY, not
|
||
direct stores. 9 direct stores, none of them a progress write.
|
||
* "the singleton-global filter can find progress writers" → it fails its own
|
||
control.
|
||
* "the progress copy destination is an `r1`-relative stack local" → it is a
|
||
**frame register**. The `r1` assumption returned 0 for all 21 candidates
|
||
*including the known-good* — the filter was killed by its own control.
|
||
* "word B's writer also stores the Time/Points record" → it does not.
|
||
* "the debriefing records the metric with the clear bit" → 44 calls, exactly two
|
||
strings (`DEBRIEFING`, `BASE_INFO`), no `Time`, no `Points`.
|
||
* "`0x820AF030` holds live state" → all 384 words constant; it is a
|
||
spawned-entity record, not live state.
|
||
|
||
## Screens, classes and RTTI
|
||
|
||
* "`sub_821C6458` is `GamePart_Title`'s state machine" → **mine, imprecise.** It
|
||
is the machine for **phase 4** of a five-way outer dispatch at `this+132`;
|
||
phase 0 is the splash. The ten states and eighteen edges are phase 4 only.
|
||
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
|
||
* "`sub_821CC860` is the game's by-name screen factory" → **mine, and wrong.** Its
|
||
decoded arguments include `BG`, `BLACK`, `FADE`, `FILE`, `KEY`, `PAD`, `SOUND`,
|
||
`GAMMA_RGB` — it is a **generic name-keyed lookup**, mostly config.
|
||
* "`DIFFICULTY` and `EXTRA_MENU` are corroborated screen names" → **mine, and
|
||
wrong.** Neither appears in `r5` at any of the 48 call sites; they were strings
|
||
merely referenced by the same functions. Only `TUTORIAL_MENU` survives.
|
||
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
|
||
* "the `{func, func, ptr}` triples at `0x820a3b48` are a GamePart state table" →
|
||
**static-initialiser records trailing the `RegisterToFactory` strings.** The
|
||
bytes before them are the tail of a diagnostic string and the data column is
|
||
zero-filled descriptors.
|
||
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
|
||
* "the boot sequence is driven by a table the game reads" → it is **not
|
||
data-driven**; four search spaces closed, transitions are calls with an id
|
||
argument. [`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
|
||
* "`config.ini` is a GamePart settings table, so the boot order is in it" → its
|
||
`[SYSTEM]` section is **empty**; the only populated section is `[LANGUAGE]`.
|
||
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
|
||
* "the attract loop is `GP_ADVERTISE_DEMO` (GamePart 1)" → 🟡 id 1 has **no
|
||
registration site** in the shipped build; the attract is the title replaying
|
||
`ADV.wmv`.
|
||
* "the 29 id-table names are 29 distinct GameParts" → 24 register, and `3`/`4`
|
||
are the **same class** (`GamePart_SaveLoad`).
|
||
* "Ⓐ on `NEW GAME` leads to a standing black-screen hang" → it opens
|
||
**`DIFFICULTY`**, then **`SELECT DATA`**. What looked like a hang was a menu
|
||
waiting for input that nobody pressed; the crash that follows is the already
|
||
documented `sub_823070B0` cache throw.
|
||
[`menu-navigation-semantics.md`](menu-navigation-semantics.md)
|
||
* "tapping Ⓐ during the boot movie breaks the title" → **one** tap skips the
|
||
movie cleanly and the title works normally. It is *hammering* (88 presses) that
|
||
breaks it. [`movie-binding.md`](movie-binding.md)
|
||
* "the attract movie runs ~85 s, so it is not `ADV.wmv` (137 s)" → **mine, and
|
||
wrong.** Sampling began 39 s into the movie, so what was timed was its tail.
|
||
The attract movie **is** `ADV.wmv`, played in full.
|
||
[`movie-binding.md`](movie-binding.md)
|
||
* "the boot intro and the attract movie are different videos" → one asset, one
|
||
manifest slot (`ADVERTISE_MOVIE`).
|
||
* "the new-game intro is unidentified" → `MS00A` → `S00A.wmv`, decoded from the
|
||
movie manifest.
|
||
* "`GP_READY_ROOM.pak` holds the Ready Room screen" → its 317 distinct element
|
||
names contain **none** of the six visible labels; it is the briefing /
|
||
tactical-map content behind the `BRIEFINGS` item.
|
||
[`ready-room-probe.md`](ready-room-probe.md)
|
||
* "the Ready Room might be 3D with a UI overlay" → it is **2D**; the pak carries
|
||
zero 3D containers.
|
||
* "element kind `0x3002` is *the* button kind" → title-side only. All 902
|
||
`GP_READY_ROOM` bundles have **zero** `0x3002`; that pak uses `0x3000`,
|
||
`0x3004`, `0x300c`, `0x3008`. `0x3002` is one member of a `0x3000` family.
|
||
* "the transition between menu screens is a cut" → it is a **fade through
|
||
black**; a 0.5 Hz screenshot burst simply samples too slowly to see it.
|
||
[`screen-transitions.md`](screen-transitions.md)
|
||
* "the main menu's initial focus is fixed" → three boots of one script gave
|
||
`TUTORIAL`, `TUTORIAL`, `NEW GAME`.
|
||
* "the title menus drop d-pad presses shorter than ~0.3 s" → **refuted by my
|
||
own data.** The menu **wraps at both ends**; every press registered, and the
|
||
"missing" step was the wrap. See [`menu-navigation-semantics.md`](menu-navigation-semantics.md).
|
||
* "the main menu opens with `NEW GAME` focused" → it opens on **`TUTORIAL`**,
|
||
2/2 boots (🟡 a third recorded run implies `NEW GAME`, so this is reproducible,
|
||
not invariant).
|
||
* "`GP_TITLE` builds 6/8/9 are three submenus" → **8 is the JAPANESE main
|
||
menu**, and 6/9 are the English and Japanese `EXTRAS` submenu. `GP_TITLE`
|
||
holds eight screens shipped twice (EN/JP), and exactly one submenu. See
|
||
[`ui-title-build-map.md`](ui-title-build-map.md).
|
||
* "the `PRESS Ⓐ BUTTON` plate is a state of the title build" → it is **its own
|
||
build** (2/3), composited over build 4 and faded in a beat later.
|
||
* "the RTTI route can name the anonymous classes" → 1 150 vtables: 1 150
|
||
`ANON_`, 0 `rtti_present`, 0 base classes.
|
||
* "the sibling vtable methods name the class" → they cannot.
|
||
* "`xrefs` can name the callers of a vtable method" → no.
|
||
* "the `ind_call` refutation voids existing corpus claims" → damage bounded,
|
||
4/4 caller claims verify. But **`xrefs.ind_call` is a CROSS PRODUCT** — always
|
||
filter `kind='call'`.
|
||
* "`BASE_INFO` marks the 5-slot screen family" → it discriminates
|
||
screen-config from table-read, 9/9 vs 10/10.
|
||
* "a high key count means a rich screen" → `sub_82297550` / `sub_822A2F00`'s 27
|
||
"keys" are coordinate pairs, i.e. a layout table.
|
||
* "`EX_` = the CHALLENGE-mission debriefing" → `EX_` is **EXTRA**, mission-kind
|
||
3.
|
||
* "the `EX_` selection has not been shown" → it has: `[[obj+4]+184] == 3`.
|
||
|
||
## Stages, missions and the challenge set
|
||
|
||
* "the disc's stages are numbered 1..28" → S01–S16 story, S17 **cut**, S18–S23
|
||
tutorials, S24–S29 challenge.
|
||
* "S24–S29 are story missions" → they are the challenge missions.
|
||
* "the challenge missions have their own maps" → they reuse
|
||
`GP_MAIN_GAME_E.pak`'s stage records.
|
||
* "the challenge `REQUIREMENT` values are 16,25,26,27,29" → the chain is
|
||
16→24→25→26→27→28.
|
||
* "the `Extra0n` family shares one leaderboard metric" → `RECORD_TYPE` is
|
||
per-stage: 3 Time / 3 Points.
|
||
* "stage = filled SHAB count + 1" → refuted.
|
||
* "the first TRIGGER is always the point of no return" → refuted.
|
||
* "`EnumUnit_S14.tbl` might be missing" / "S14's 13 are a manifest omission" /
|
||
"asteroids are exempt from the manifest" → S14's 13 are **dangling
|
||
deployments**. NEEDS-HUMAN: fly S14.
|
||
* "`StageMessageSet_S02.tbl` is not in the pak" → it is.
|
||
* "`S28_p1` has an asteroid volume with no definition" → refuted.
|
||
* "`test_s8p1_asteroid.tbl` is test-only" → refuted.
|
||
* "the settings family has 28 or 29 objects" → 24.
|
||
|
||
## ISL / mission scripting
|
||
|
||
* "the bytecode is in the `.embsec_` sections" → refuted.
|
||
* "only 31 built-ins take a unit" → refuted.
|
||
* "`sub_8230C398` is the message pump" → refuted.
|
||
* "`bus+8216` is the subscriber registry" → refuted.
|
||
* "the ScriptPhase vtable is ≥200 slots" → 113.
|
||
|
||
## IDXD, paks and naming
|
||
|
||
* "IDXD record keys are `name_hash`" → record keys are **`tag_hash`**
|
||
(case-SENSITIVE); `name_hash` is case-INSENSITIVE and used for pak keys.
|
||
* "pak TOC order is stage order" / "TOC order is semantic order" → it is not.
|
||
* "the executable holds the asset names" → the image names **no data value at
|
||
all**; that route is powerless.
|
||
* "the image might name a data VALUE" → powerless.
|
||
* "the XPR2 manifest names hash to the DefTables tables" → refuted.
|
||
* "the `DefTables` model names are unreachable" → reachable via the `Enumerate`
|
||
declaration tables (1 413/1 425, 99.2 %).
|
||
* "the `GP_MAIN_GAME_*` unnamed block is undiscovered data" → refuted.
|
||
* "each `GP_MAIN_GAME_*` `Enumerate` object declares something" → refuted.
|
||
* "`GP_HANGAR_ARSENAL` is missing data tables" → refuted.
|
||
* "the `Enumeration` self-index can name objects" → a self-index names
|
||
**records, not files**.
|
||
* "a per-pak prefix might close the 2D blocker" → no.
|
||
* "the `+` paths might name the 2D or `GP_READY_ROOM` keys" → the `+`-dictionary
|
||
route is exhausted, 0 of 1 817.
|
||
* "the `game:\` paths are unresolved" → refuted.
|
||
* "a set-difference over file names can see reuse" → it cannot; **join per
|
||
USER**. Per-pak copies are ×6.
|
||
|
||
|
||
## Audio
|
||
|
||
* "which bank the menu plays is not on the disc" → the **cue table** cannot say
|
||
(all BGM cues are numeric), but the **code** can: `sub_821C5580` plays cue
|
||
**1103 = `BGM_103`**, and its two declared waves match the two streams the XMA
|
||
probe saw byte-for-byte.
|
||
* "the observed BGM stream sizes match no bank's declared waves, so the game hands
|
||
the decoder a window" → **mine, and wrong** — I checked only the `BGM_0xx` rows.
|
||
They are `BGM_103`'s two waves exactly; the game hands over the whole wave.
|
||
|
||
* "an individual SE cue's audio cannot be extracted" → **mine, and wrong.**
|
||
`--xma_param_probe=true` logs each stream's head bytes; searching them in
|
||
`Static.slb` locates the wave exactly. [`menu-audio-cues.md`](menu-audio-cues.md)
|
||
* "`Static.slb` has no wave boundaries, so its layout is unknown" → it is a
|
||
**packed run** of whole 2 048-byte XMA packets with no delimiters — the two
|
||
located cues are contiguous. There is nothing to scan for, by design.
|
||
|
||
* "`Pj_Silph.xgs` holds the cue→wave index, so parse XACT" → **no XACT container
|
||
exists on this disc**: 0 × `XGSF`/`SDBK`/`WBND` in all 1.08 GB of `sound.pak`,
|
||
and no `XACT`/`.xgs` string in the executable. The extensions are the authoring
|
||
tool's, not the format's. [`menu-audio-cues.md`](menu-audio-cues.md)
|
||
|
||
* "every sound cue resolves to its own `.slb` bank" → the 322 `SE_*` cues do not;
|
||
**0 of 322** are in `FILES`, and `BANK_SE` puts them all in `Static.slb`.
|
||
* "`Static.slb` can be split into waves like any other bank" → it holds **0
|
||
`RIFF`, 0 `seek`, 0 `WAVE`** across all 8 353 472 readable bytes.
|
||
[`menu-audio-cues.md`](menu-audio-cues.md)
|
||
|
||
* "`BGM_001.slb` is three sub-waves (10 KB + 4.47 MB + 4.67 MB)" → the 10 KB is
|
||
the **bank header**; a bank is **two** waves.
|
||
* "a music bank's two waves might be intro + loop, two variations, or two halves"
|
||
→ they are **two stems of one performance, played together** — equal duration
|
||
in 32/32 banks, and sample-synchronous.
|
||
[`structures/bgm-two-stems.md`](structures/bgm-two-stems.md)
|
||
* "`BGM_106`–`BGM_109` break the two-wave rule" → they are the leading-region
|
||
straddle; realigned across entry boundaries they obey it.
|
||
* "the cue table names which BGM belongs to which screen" → all 32 BGM cues are
|
||
numeric (`BGM_001`…`BGM_109`).
|
||
|
||
## Units, weapons, effects and assets
|
||
|
||
* "`Generic` (394) is the unit datasheet" → refuted.
|
||
* "a loadout's `Arm1` names an item" → it names a **hardpoint slot**
|
||
(`Turret_NNN`), 59/59.
|
||
* "`EnumUnit` and the unit datasheet share a vocabulary" → they do not.
|
||
* "the roster is the `Generic.Model` set" → roster 40, `Generic.Model` 46,
|
||
`GameResourceID` 480 — three vocabularies.
|
||
* "every unit ID is `UN_<l>###_<FACTION>_<name>`" → the grammar is
|
||
`UN_<letter>###_[<subkind>_]<FACTION>_<name>`.
|
||
* "`_EXn` is the `Extra0n` index" → three different `EX` vocabularies exist.
|
||
* "the only two `_EX5` names on the disc are the AA gun and the DeltaSaber" →
|
||
refuted.
|
||
* "running the tutorial will instantiate the `_Ttrl` weapons" → refuted.
|
||
* "the disc has exactly three `EnumWeapon` tables" → four.
|
||
* "the `wep_NN` package gaps are unshipped weapons" / "`wep_85` is the tip of a
|
||
family" → `wep_85` is the **only** declared-but-unshipped asset (59/0/1/26).
|
||
* "nothing is deployed without being declared" → refuted.
|
||
* "effects are one namespace" → refuted.
|
||
* "the 58 undeclared effect names are missing assets" → refuted.
|
||
* "all five orphan effects are unshipped" → refuted.
|
||
* "`eff_f0002` ships in `Base.xpr`" → refuted.
|
||
* "`Base.xpr` holds more bound effects than `ptc_pack`" → refuted.
|
||
* "the 34 unlocated are a scatter" → refuted.
|
||
* "the 9 unlocated might be under another prefix" → refuted.
|
||
* "`ptc_pack` has 532 names" → 727.
|
||
* "the `_e`/`_f` law is effect-FIELD-specific" → it is the **faction law**,
|
||
564/564.
|
||
* "a disc-wide `.xpr` byte search can show an effect is ABSENT" → it cannot.
|
||
* "`rot_n001` is on the disc" → refuted.
|
||
* "`rou_f004`'s mesh is in `Stage_S28.xpr`" → it is in `DeltaSaber_A.xpr`.
|
||
* "`parent` + `_all` + `_child` is the composite-model convention" → refuted.
|
||
`_hangar` **is** real (59 of 166, 59/59 with a bare twin); `_all`/`_child` is
|
||
not.
|
||
* "`Motion_guard_start` has no damage variants" → refuted.
|
||
* "`CoverArea` bits 2 and 3 are mutually exclusive" → refuted.
|
||
* "the 27 unresolved `NamePlate` values are missing objects" → refuted.
|
||
|
||
## LOD, background and misc tables
|
||
|
||
* "`EnumLODSet_*` is a per-stage family" → `EnumLODSet_test.tbl` serves 17
|
||
stages; 17+5+1 = 23.
|
||
* "there are 8 orphan LOD tables" → 6.
|
||
* "the orphans are stale copies of `_test`" → refuted.
|
||
* "S25 is absent from the `DefTables` LOD families" → refuted.
|
||
* "`BackGroundID` has no referent anywhere" → it is an **identity**.
|
||
* "`BackGroundPackage == BG_<id>.xpr`" → refuted.
|
||
* "`<X>ID` + `<X>Package` is a convention" → refuted.
|
||
* "`Placement_*` / `RouteTest_*` are unattached" → refuted.
|
||
* "the `AsteroidDefinition` join does not reproduce by hash" → it does.
|
||
* "the 8-value frame is a new finding" → it was already in the corpus.
|
||
|
||
## Loaders, config and tuning
|
||
|
||
* "the config reader is XML" → INI.
|
||
* "`sub_822F9498` is the unit-definition loader" → it is `PlayerParams`'s.
|
||
* "`sub_822AE628` reads the main-game `Tweak`" → refuted.
|
||
* "`sub_8230D1F8` is a rank table" → it is the stage-settings loader.
|
||
* "`sub_82286BC8`'s key list is new" → refuted.
|
||
* "`sub_825F2CF0` / `sub_825F2F88` read a post-processing table" → refuted.
|
||
* "`Booster` is a new schema" / "`Booster` is the player craft's flight
|
||
envelope" → refuted; nothing selects `Booster`.
|
||
* "the `AnalogRevice`/`Tweak` block is unreachable" → reachable
|
||
(`sub_821A6CF0`, base `0x820A1630`).
|
||
* "a 0-xref string block has no reader" → refuted.
|
||
* "the AI table was NEEDS-HUMAN" → refuted.
|
||
* "the `PG*` HUD names are undocumented" → they are documented.
|
||
* "a base-solver row identifies a FUNCTION" → it does not.
|
||
* "a 64K-boundary base is low confidence" → **inverted**; it is high
|
||
confidence.
|
||
* "the 0x820B0000 cluster is a false positive" → refuted.
|
||
* "a pointer to a function in the image implies a registry" → refuted.
|
||
`.pdata` is not a registry.
|
||
* "the 13 player-facing chatter tables are the WINGMAN tables" → refuted.
|
||
* "the 8 undeclared chatter tables are tutorial chatter" → refuted.
|
||
* "other datasheets ship a schema too" → refuted.
|
||
|
||
## Encoding and text
|
||
|
||
* "every IDXD string value is ASCII" → 6 non-ASCII values of 99 328.
|
||
* "`文字列` is a dev placeholder" → they are Shift-JIS **type words**.
|