extracted", and the tool was in the build all along Two iterations ago I closed Q8 by declaring the SE audio undecodable: Static.slb has no wave boundaries, there is no XACT container anywhere, and I said the index "exists only at runtime" as though that put it out of reach. The disc half of that stands. The conclusion did not. This build of Canary carries a cvar called xma_param_probe, added by this project, whose own comment says it logs each XMA stream's parameters and head bytes so raw sound.pak entries can be matched to real decode params. It has been sitting in the startup CONFIG DUMP of every log I have read this session. Run with it, driving the main menu: a d-pad move spawns a new mono 48 kHz stream of 4 packets / 8192 bytes, and B spawns a different one of 2 packets / 4096 bytes. Searching their logged head bytes in Static.slb finds each at exactly one offset -- 0x1ec0 and 0x0ec0 -- and the two are contiguous, 0x0ec0 + 4096 = 0x1ec0. So the bank is a packed run of whole 2048-byte packets with no delimiters, which is precisely why the seek scan found nothing: there is nothing to find. A wave is (offset, packet count) and nothing else. That splits Q8's binding cleanly. Event -> WAVE is now measured: the port can have the audio. Event -> cue NAME is still a name match on the authors' identifiers, and the page says so. The same run settled something for Q10 too. Sitting on the main menu, TWO stereo 48 kHz streams were decoding simultaneously. bgm-two-stems.md said that observation was what it needed and that this container could not make it; it can, and a music bank's two waves are now measured as simultaneous rather than only inferred. METHOD gets the general lesson, because it cost two iterations: check what instrumentation the local build already has before declaring a question blocked on tooling.
271 lines
15 KiB
Markdown
271 lines
15 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
|
||
|
||
* "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
|
||
|
||
* "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**.
|