diff --git a/docs/roadmap.md b/docs/roadmap.md index a3a35f7..d02582f 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -540,6 +540,52 @@ Phase 1 hands over the extents; this phase works out what each one contains. **Gate:** every parser has a golden test against bytes from the real disc, and reports mismatched header counts as failures rather than warnings. +### Gate status, checked + +Both halves verified by inspection rather than assertion: + +* **Golden tests.** Every module in `gc-formats/src` is referenced by a test or + another module's test path; none is unreferenced. `gc-extract/tests/disc.rs` + carries 50 real-disc tests, and the `overlay_reloc` mask test resolves a level-01 + function on all 26 other overlays. +* **Counts are failures, not warnings.** No parser writes warning-style output + outside `#[cfg(test)]` -- the only `eprintln!` calls in `gc-formats` are inside + test modules. Count and length problems surface as typed errors: 42 uses of + `ErrorKind::Invalid` / `InvalidLength`, including `global_wad`'s "pair table is + not a whole number of entries", which is exactly a header count disagreeing with + the data. + +**The gate is met.** + +### Blocked, and what would unblock each + +AGENTS.md requires a blocked item to say what would unblock it. These four did +not, which is itself a gap; this is that gap closed. None of these is a shortcut +or an approximation -- each is a measurement this repository currently cannot +make. + +- **Collision cell layout.** The payload is verbatim in RAM and does not walk as + fixed-stride cells; every disc-side segmentation is excluded. Needs the game's + own `Camera_CollPrimTest`, which lives in `.lit`. The route that would work: + the code addresses the assert string by something other than a `$gp`-relative + load -- a `%hi`/`%lo` split that does not straddle zero, a pointer table, or a + different section. A naive `$gp` search returns zero hits and will keep doing so. +- **Volumes.** A 144-byte float record table with world positions at `+0x0c` + exists in every level and is not referenced by any `data.bin`, so it is reached + by walking structure, and nothing ties it to volumes. Needs ground truth: a + count of level 0's trigger volumes from a map or guide, to match against a + table's population. No class name containing "volume" exists on the disc, so the + dispatch-table route is closed. +- **`moby_anim`.** The instance-table reading is disproved and nothing replaces + it. Needs the class-dispatch table for the classes that reference the animation + data, which needs `moby` class records decoded past the header -- a dependency, + not a measurement. +- **tfrag morph.** All patch bytes are rewritten by LOD-selected VU-packet + regeneration, so the morph is invisible in a savestate. Needs a frame captured + at a *known* camera distance, so the expected blend is computable and can be + compared. Requires running the game and driving the camera, not analysing a + static savestate. + **Discipline:** bound every read. Typed errors, no panics, no reads past the buffer.