# The level data extent Target: `SCUS_972.68` v1.01. Implementation: `crates/gc-formats/src/level_data.rs`. The `data` extent of each `LEVEL.WAD` is the level's own container. It holds the level's executable, the geometry directory, the Graphics Synthesizer RAM image, the HUD banks and the geometry itself, each at a byte offset declared by a table at the start of the extent. ## Header ```text offset size field 0x00 8 overlay the level's executable 0x08 8 core_index the geometry directory 0x10 8 gs_ram Graphics Synthesizer RAM image 0x18 8 hud_header 0x20 40 hud_banks[5] 0x48 8 core_data the compressed geometry 0x50 8 transition_textures ``` Every field is `{offset, size}` in **bytes** relative to the start of the extent. The table is 0x58 bytes and the first extent starts at 0x80, leaving 40 bytes unused. Level 0, measured: | Extent | Offset | Size | |---|---:|---:| | overlay | 128 | 2,751,268 | | core_index | 2,751,424 | 31,600 | | gs_ram | 2,783,040 | 518,656 | | hud_header | 3,301,696 | 4,060 | | hud_banks[0..4] | 3,305,792 … | 44,935 / 138,675 / 16 / 16 / 34,286 | | core_data | 3,523,904 | 9,738,678 | | transition_textures | 13,262,592 | 15,328 | Extents are ordered and non-overlapping but not gap-free: 28 bytes separate the end of the overlay from the start of `core_index`. The test asserts ordering rather than tiling for that reason. ## A third convention for sizes Three different meanings for a "size" field appear on this disc. All three are byte offsets; the size unit differs: | Where | Size unit | |---|---| | `LEVEL.WAD` named extents | **sectors** | | `G/*.WAD` generic pair table | **bytes** | | `data` extent header | **bytes** | The first of those was a real bug: the extractor read level extents through the generic path, taking a 6,484-sector extent as 6,484 bytes and losing 13 MB of every level. See `../plan/level-assets.md`. ## `core_data`: the geometry The largest extent, and a WAD LZ77 stream — the format in [`wad.md`](wad.md), with a 16-byte header whose declared size equals the whole extent, i.e. the stream spans it exactly. Level 0 decompresses from 9,738,678 to **16,969,296 bytes**, a 1.74× ratio. It contains the four geometry subsystems (`tfrag` terrain, `tie` environment instances, `shrub` foliage, `moby` actors), sky shells, collision and particles. ## `core_index`: the geometry directory A 31,600-byte structure at the head of which sits a header of offsets into `core_data`. On level 0: | Field | Value | Lands inside core_data | |---|---:|---| | gs_ram | 404, count 18,704 | yes | | occlusion | 2,117,888 | yes | | sky | 2,192,576 | yes | | collision | 2,615,232 | yes | | moby_classes | 238 | yes | | tie_classes | 74 | yes | | shrub_classes | 7 | yes | | tfrag_textures | 93 | yes | | moby_textures | 168 | yes | | textures_base | 3,518,848 | yes | | part_bank | 8,141,696 | yes | | fx_bank | 8,332,160 | yes | Every offset falls inside the 16.9 MB `core_data`, which is the evidence that the header is being read correctly. `sun` and `collision` at their offsets begin with plausible structure — the collision block opens `40 00 00 00 50 c8 0d 00`, a plausible count followed by a size. **Not yet resolved:** the `ArrayRange` fields (`moby_classes` and friends) do not decode to a usable class table under the documented layout. Offsets and counts read as plausible numbers but the entries they point at are not valid `{offset, o_class}` records. The GC core header layout differs from the documented R&C1 one in a way not yet determined. Recorded in `../plan/level-assets.md`; this is the next thing to resolve. ## Provenance The structure matches `GcUyaLevelDataHeader` in the Wrench project (, GPLv3). **No Wrench code is copied** — see `PROVENANCE.md`. Everything here is written from the specification and verified against all 27 levels on this disc.