Region spans were being re-derived per format while probing, usually running from one known offset to the next with the last span running to core_data.len(). On level 0 that gave the final shrub class a 925,008-byte span absorbing most of the lump's tail, and every aggregate computed over it -- record counts, value distributions, "this looks random" -- was silently wrong. Nothing errored, which is what made it survive two commits and a correction. core_layout computes the layout once: each region ends where the next one begins, class regions start at the lowest non-zero geometry offset in their table, and a region whose successor is unknown gets end: None rather than a clamped guess. Zero class entries mean absent, not position zero -- the same trap occlusion and collision each fell into separately. The disc test asserts what the module is actually for: that the unknown is visible. Shrub's end is unresolved on the 24 levels that have a shrub region, and that is asserted rather than hidden. It also found that not every level has every region -- level 10 has neither occlusion nor shrub -- so the test checks ordering against the canonical sequence instead of demanding an identical set. Still open: where the shrub region ends. Texture texels cannot bound it; they sit before moby, not after shrub. See docs/formats/core-data-regions.md.
51 lines
2.1 KiB
Markdown
51 lines
2.1 KiB
Markdown
# core_data region bounds
|
|
|
|
How a level's `core_data` lump divides up, and how each region is bounded.
|
|
|
|
## The rule
|
|
|
|
A region's end is the **next region's start**, never `core_data.len()`. The
|
|
last region in a layout is the exception, and when its successor is unknown the
|
|
end is `None` rather than a guess.
|
|
|
|
This exists because region bounds were being re-derived per format during
|
|
probing, usually by running from one known offset to the next with the last
|
|
span running to the end of the lump. On level 0 that made the final shrub class
|
|
a 925,008-byte span absorbing most of the lump's tail. Every aggregate computed
|
|
over it -- record counts, value distributions, "this data looks random" -- was
|
|
silently wrong, and nothing errored.
|
|
|
|
`gc_formats::regions::core_layout` computes these once. Callers use it rather
|
|
than inventing their own.
|
|
|
|
## Layout
|
|
|
|
| region | start | end |
|
|
|------------|----------------|----------------------|
|
|
| `tfrags` | 0 | `occlusion` |
|
|
| `occlusion`| `occlusion` | `sky` |
|
|
| `sky` | `sky` | `collision` |
|
|
| `collision`| `collision` | first moby class |
|
|
| `moby` | first moby | first tie class |
|
|
| `tie` | first tie | first shrub class |
|
|
| `shrub` | first shrub | **unknown** |
|
|
|
|
Class regions start at the lowest non-zero geometry offset in their class
|
|
table. A zero entry means *absent*, not position zero -- the same trap the
|
|
occlusion and collision headers each fell into separately.
|
|
|
|
Not every level has every region: level 10 has no occlusion and no shrub.
|
|
|
|
## Open: where shrub ends
|
|
|
|
The offset ending the shrub region is not in the core index.
|
|
|
|
Texture texels do **not** bound it. They sit before moby, not after shrub: on
|
|
level 0 the texel range is 3539328..5326208 while the last shrub class starts
|
|
at 16044288, leaving ~925 KB of real, non-zero data after the last shrub class
|
|
that nothing yet accounts for.
|
|
|
|
`core_layout` reports `end: None` for shrub on the 24 levels that have one, and
|
|
the disc test asserts it, so the gap stays visible rather than being papered
|
|
over by clamping to the end of the lump.
|