From ca277a0a0192c42d6dd3f42fac3a08c3203e63bd Mon Sep 17 00:00:00 2001 From: ReaperOfVeriod Date: Tue, 13 Oct 2026 07:33:26 +0200 Subject: [PATCH] Volumes: a candidate table found, explicitly not called volumes Volumes were the only type never located, so this is a search report rather than a result, and it is recorded as a candidate on purpose. Ruled out first: no engine-side name exists. No level file contains "Volume" outside UI text ("Music volume", "Volume de la musique") and Italian item descriptions. The format cannot be found by label and has to be structural. gameplay.bin is already-decompressed level data. Its head is a count (336 on level 0) then 16-byte records from byte 416, carrying (type, pad, offset, id). The id groups them -- each id has exactly two records pointing into two parallel offset arrays -- and those offsets resolve into a text pool, the first ones landing mid-string in dialogue ("it Megacorp Lab"). So that part of the file is dialogue and class dispatch, not geometry. The structural hit: a table of 144-byte float records. Level 0 has one at 799204, 20 records of which 19 are populated and one is an all-zero terminator, with 34-35 of each record's 36 float slots world-plausible and +0x0c holding a varying world position: (206.5, 284.1, 116.0) (265.0, 445.3, 131.7) (244.0, 407.2, 128.0) (219.3, 247.0, 107.5) (185.1, 282.6, 104.9) (260.8, 423.6, 130.9) (248.2, 198.4, 51.8) (185.8, 282.7, 102.6) (247.0, 211.5, 100.6) A 144-byte record with world positions and float radii is the shape a volume trigger region should have, and a matching table is present in every level examined (0-9), each preceded by an all-zero record, counts 23 to 612. It is NOT called volumes. Nothing ties this table to volumes. Camera bounds, spawn points and path nodes would present exactly the same thing: float records, world coordinates, no label. The discriminating evidence has not been gathered, and writing "volumes" in the roadmap because the shape fits would be the exact error this log keeps catching. Two detector bugs, both mine, both confident before they were caught: 1. The validity test accepted zero as a world-plausible float, so every zero-filled region scored perfectly and the cross-level check returned runs of 225 to 1,514 records that were obviously padding. Requiring non-zero floats (>=20 of 36) separated real tables from memory immediately. 2. The 144-byte stride came from four offsets I eyeballed as being 144 apart. Gap 144 was not in the top eight gaps of the detector that found them -- it survived because three consecutive observations agreed, not because the measurement supported it. The corrected detector then found much longer runs, which is the opposite of what the eyeball version implied. Same shape as every other correction here: a clean small plausible number read as conclusive because nothing was checked against a control that could disagree. To actually settle it, the table needs to be correlated with something known -- if a count matches a level's visible trigger regions, or if an id in the record resolves through the class table to a named object, that is the discriminator. Until then volumes remain open and the roadmap says so. --- docs/formats/core-data-regions.md | 61 +++++++++++++++++++++++++++++++ docs/roadmap.md | 12 +++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/docs/formats/core-data-regions.md b/docs/formats/core-data-regions.md index 7f88d98..c79967e 100644 --- a/docs/formats/core-data-regions.md +++ b/docs/formats/core-data-regions.md @@ -2184,3 +2184,64 @@ it in the file -- consuming bytes 4..8 and shifting everything after. The struct literal named the fields in the right order; the statements did not. It is fixed with a comment saying so, since "read the `let`s in file order" is the kind of thing that gets undone. + +## Volumes: a candidate table, and why it is not yet called one + +Volumes were the only asset type never located at all, so this is a search +report rather than a result. + +**Ruled out first: there is no engine-side name.** No level file contains the +string `Volume` outside UI text ("Music volume", "Volume de la musique") and +Italian item descriptions. So the format cannot be identified by a label and +must be found structurally. + +`gameplay.bin` on disc is the already-decompressed level gameplay data. Its head +is a count (`336` on level 0) and then 16-byte records from byte `416`. Those +records carry `(type, pad, offset, id)`; the `id` field groups them, each id +having exactly two records pointing into two parallel offset arrays. The offsets +they point at resolve into a text pool -- the first ones land mid-string in +dialogue ("it Megacorp Lab"), so this is the dialogue and class-dispatch side of +the file, not geometry. + +The structural hit is a table of **144-byte float records**. Level 0 has one at +`799204`: + + 20 records of 144 bytes, 19 populated and one all-zero terminator + 34-35 of every record's 36 float slots are world-plausible + +0x0c holds a world position, varying per record: + + [0] (206.5, 284.1, 116.0) [6] (244.0, 407.2, 128.0) + [1] (219.3, 247.0, 107.5) [7] (265.3, 443.7, 13548.6) + [2] (248.2, 198.4, 51.8) [8] (185.1, 282.6, 104.9) + [3] (247.2, 203.6, 82.4) [9] (185.8, 282.7, 102.6) + [4] (155.7, 372.7, 121.1) [10] (260.8, 423.6, 130.9) + [5] (265.0, 445.3, 131.7) [11] (247.0, 211.5, 100.6) + +A 144-byte record with world-space positions and float radii is exactly the shape +a volume trigger region should have, and a matching table exists in every level +examined (levels 0-9), each preceded by an all-zero record, with counts from 23 +to 612. + +**It is not called volumes here.** Nothing yet ties this table to volumes +specifically. It could equally be camera bounds, spawn points, or path nodes -- +all of which would present 144-byte float records with world positions and no +label. The distinguishing evidence has not been gathered, and the honest state +is *candidate*. + +### Two detector bugs worth recording + +Both were mine, and both produced confident nonsense before being caught. + +1. The first validity test accepted zero as a world-plausible float. Every + zero-filled region then scores perfectly, and the cross-level check returned + runs of 225 to 1,514 records -- obviously padding. Requiring **non-zero** + floats (>=20 of 36) immediately separated real tables from memory. +2. The stride claim rested on four eyeballed offsets 144 apart. Gap 144 was not + in the top eight gaps of the detector that found them; it survived because + three consecutive observations agreed, not because the measurement supported + it. The corrected detector then found longer runs, which is the opposite of + what the eyeball version claimed. + +The same shape as every other correction in this log: a clean, small, plausible +number read as conclusive because it was not checked against a control that +could have disagreed. diff --git a/docs/roadmap.md b/docs/roadmap.md index b71b71d..e95716e 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -407,7 +407,17 @@ Phase 1 hands over the extents; this phase works out what each one contains. `+0x20` is self-limiting: entries run while strictly inside the region. **The word at `+0x0c` is not a count** -- it disagrees with the table on most levels and reads 196,617 on level 2 against 4 sub-objects. -- [ ] `volumes` — **not located.** Nothing examined so far presents itself as a +- [~] `volumes` — **still not identified, but a candidate exists.** Every level's + `gameplay.bin` carries a table of **144-byte float records** with world + positions at `+0x0c`, preceded by an all-zero record (levels 0-9: 23 to 612 + records). That is the shape of a volume trigger region and it is not tied + to anything else in the file -- but camera bounds, spawn points and path + nodes would look identical, and there is no engine-side `Volume` string to + discriminate with. **Recorded as candidate, not volumes.** Two detector + bugs on the way are written up: a validity test that counted zero as + world-plausible scored zero-filled memory perfectly, and the 144-byte stride + rested on four eyeballed offsets that the gap histogram did not support. + Not located. Nothing examined so far presents itself as a volume: `core_data`, the chunk region and `gameplay.bin` all yield structures that are accounted for by something else. - [~] `level_overlay` — header, constant block and level data parsed