# `REGN` — a stage's tetrahedral navigation mesh (and `MCOL` beside it) **Status: ✅ `CONFIRMED`.** A `REGN` object is a **tetrahedral navigation mesh of the whole play volume** — vertices, tetrahedra, faces with full adjacency, per-tetrahedron portal costs — plus a uniform grid for point location. The decode is complete except for two small fields; see [the 2026-08-26 section](#-2026-08-26--the-reader-found-regn-is-a-tetrahedral-navigation-mesh), which supersedes the offsets in the older sections below (they were read **16 bytes early** — the loader's fixup base is `chunk + 0x10`). The older sections are kept because their refutations are still instructive. **New to this corpus** — no document mentioned `REGN`, `MCOL` or `hidden/MiscBin.pak` before 2026-08-24. ## Where it is `hidden/MiscBin.pak` — 40 entries, **none** name-resolved, in three groups: | magic | count | sizes | |---|---|---| | `REGN` | **11** | 49 KB … 3.1 MB | | `MCOL` | **11** | 37 KB … 81 KB | | (other) | 18 | — | Eleven of each, which pairs them: one `REGN` and one `MCOL` per map. `MCOL` is untouched here; the name and the size range read like mesh collision. ## The header, and why it is believable ``` 0x00 char[4] 'REGN' 0x04 u32 size of the data area (the POF0 table starts at 0x04-value + 16) 0x10 f32[4] bbox min (x, y, z, 1.0) 0x20 f32[4] bbox max (x, y, z, 1.0) 0x30 f32[4] extent (max - min) 0x40 f32[4] cell size 0x50 u32[4] grid dimensions 0x60 u16[6] six counts 0x70 u32[4] four section offsets (the first is always 0x80) ``` **The check that makes this a decode rather than a guess** — over all 11 objects: * `extent == cell × dims` holds **11 of 11**, exactly; * `counts[3]` equals the **cell count**: `1000` on every 10×10×10 map and `125` on every 5×5×5 one. Two independent fields reproducing the grid is what rules out coincidence. ## The three map sizes on the disc | half-extent | cell | dims | objects | |---|---|---|---| | 250 000 | 50 000 | 10×10×10 | 2 | | 50 000 | 10 000 | 10×10×10 | 6 | | 25 000 | 10 000 | 5×5×5 | 3 | So every map is a cube partitioned into 125 or 1 000 uniform cells — 10 km cells in a 100 km cube for the common case, and one pair of maps five times larger. ## ✅ Section 3 is the cell index — and it self-checks 11/11 The fourth section is a **one entry per cell** table of 8-byte records `(count, offset)`, immediately followed by the records those offsets point at: ``` index = offsets[3] .. offsets[3] + cells*8 payload = align16(index end) .. record = 32 bytes (offsets step by 0x20) ``` Checked over all 11 objects: the lowest offset any cell refers to equals **`align16(offsets[3] + cells × 8)` — 11 of 11**. On the six 10×10×10 maps `cells × 8` is already 16-aligned and the payload butts straight up against the index; on the three 5×5×5 maps `125 × 8 = 1000` is not, and the payload starts 8 bytes later, which is what makes the alignment rule visible rather than assumed. Two more invariants from the same sweep: * every occupied cell has count **exactly 1** — total items equals occupied cells on all 11 objects, so this is "one record per cell", not a bucket list; * **`counts[4] = occupied cells + 2`**, exactly, on all 11 (e.g. 997/995, 880/878, 125/123). The `+2` is unexplained — two sentinels, or two cells counted differently. Most cells are occupied: 878–998 of 1 000, 123 of 125. ## ✅ It is a serialised object graph with a `POF0` fixup table Every one of the 11 objects contains the tag **`POF0`**, always near the tail, and its position is exactly **`header[0x04] + 16`** — on **11 of 11**: ``` e993b93e header +0x04 = 0x0b100 POF0 at 45328 = 45312 + 16 e4155d94 header +0x04 = 0x235d70 POF0 at 2317696 = 2317680 + 16 … 11 of 11 identical relation ``` `POF0` is a **pointer-offset (fixup) table**: the file is a serialised C++ object graph, and the loader patches the recorded slots into real pointers. That explains a detail that would otherwise be odd — the "offsets" inside the cell index are absolute **file** offsets, because that is what a fixup table rewrites. So `header[0x04]` is the size of the data area, and everything past `header[0x04] + 16` is relocation bookkeeping rather than content. ## 🔴 Two readings of the cell payload, both refuted by generalising Both came from the smallest object and both died the moment they were checked against the other ten — recorded because the temptation to keep them was real: * **"the `f32` at record `+0x1c` is the grid's bounding-sphere radius."** On `e993b93e` it is 86 689 against `√3 × 50 000 = 86 603`, a ratio of **1.001**. On the other ten the ratio runs **0.13 – 0.27**. Fitted to one sample. * **"a record's `(count, offset)` pairs point at leaf arrays of `count × 4` bytes."** True for the first record of `e993b93e`; across the objects the offset deltas fail that rule on **every** object checked (0 of 11 clean). What survives is only descriptive: the payload area is dominated by **float data** — the "strings" a printable-run scan finds are all byte patterns like `0x46`/`0x47` high bytes, i.e. medium-magnitude floats, not text. ## ❔ The other three sections Their offsets scale with the object, and `counts[0..2]` scale with them — `(318, 1172, 2584)` for the 350 KB map against `(2936, 14967, 31155)` for the 3.1 MB one, a roughly `1 : 4.5 : 10` ratio that holds across all eleven. The smallest object (49 KB) is nearly empty by comparison — `(8, 6, 18)` — which makes it the cheapest one to decode first. ## Why this matters, stated without overclaiming A mission's enemy count **rises and falls** as waves arrive and are destroyed, so somewhere there is a scheduler with parameters — what spawns, where, and on what trigger. A per-map uniform grid indexed by cell is exactly the structure such a thing is indexed *by*. 🔴 **But nothing here shows spawn parameters yet.** The header is a spatial partition and no more; the sections are unread. Treat this as the location of the world's spatial data, not as the wave table. ## ✅ Update: `REGN` is a stage's **MapPath** The per-stage definition record (see [stage-definition-table.md](stage-definition-table.md)) has a field `MapPath = test.rgn`, and `name_hash("test.rgn") = 0x3506e972`, which is one of the `REGN` objects in `MiscBin.pak`. The sibling field `MapMesh = test.col` hashes to `0x2cf7eb47`, an `MCOL` object in the same pak. So `.rgn`/`REGN` is stage navigation/path data referenced by the stage record, and `.col`/`MCOL` is the stage collision mesh. This does not by itself validate either of the two refuted cell-payload readings recorded above, but it does explain why the payload looks like a grid of route data. ## ✅ Sections 0, 1 and 2 have record strides — and section 2 is a PLANE list **2026-08-26.** The three sections the page called undecoded are fixed-stride record arrays, and `counts[0..2]` are their record counts. Dividing each section's byte span by its count over all 11 objects: | section | stride | evidence | |---|---|---| | 0 | **12 bytes** | `count × 12` fits with a remainder of 0–12 in **11 / 11** | | 1 | **96 bytes** | `count × 96` fits with a remainder of **exactly 0 in 11 / 11** | | 2 | **48 bytes** | `count × 48` fits with a remainder of **exactly 96 in 11 / 11** | Section 1 landing on a zero remainder in every object, and section 2 on the same 96-byte tail in every object, is what makes these strides rather than a coincidence of division. ### ✅ Section 0 is a point list 12 bytes is three `f32`. Over **13 467** records across all 11 objects, **every one lies inside that object's own header bounding box — 13 467 / 13 467 (100 %)**. Values land on the box corners (`±250 000`) and inside. ### ✅ Section 2 is a plane list — 48 bytes, and the plane equation closes Read as twelve `f32`: [0..3] zero [4..6] unit normal |n| = 1 ± 0.02 in 133 573 / 133 573 (100 %) [7] signed distance d [8..10] a point on the plane, inside the bbox in 133 573 / 133 573 (100 %) [11] 1.0 exactly in 133 573 / 133 573 (100 %) **The check that makes this a decode**: for a genuine plane, `n·p + d` must be zero. Over all **133 573** records: |n·p + d| / scale : median 2.29e-08 p90 6.78e-08 max 2.15e-07 That is float round-off, not a fit — the relation holds to the last bits of a 32-bit float in **every record on the disc**. Three independent 100 % properties (unit normal, point in bbox, trailing 1.0) and an exact algebraic identity are well past what a wrong reading survives. So a `REGN` object carries, alongside its uniform grid, a **point list** and a **plane list** — which is the shape of collision or region-boundary geometry, and consistent with `MCOL` sitting beside it. ### ❔ Still open * **Section 1** (96 bytes/record, **63 410** records disc-wide) — a per-slot census is below, but what the record *means* is still ❔. * **What the planes are for.** "Collision or region boundary" is a reading of the shape; nothing here shows what queries them. * The **zeros at `[0..3]`** of every plane record, and the constant `96`-byte tail after section 2, are unexplained. ## 🟡 Section 1, slot by slot — measured, but not read **2026-08-26.** 96 bytes is 24 slots. Censusing every one of the **63 410** records across all 11 objects gives a clear regional structure, even though the record's purpose is not settled: | slots | what the values are | reading | |---|---|---| | 0–3 | slots 2 and 3 are zero in ~100 %; 0 and 1 mostly small | ❔ | | **4–6** | 96 % have \|v\| > 1 000, range **±250 000** — the header bbox range | 🟡 a **position** | | **7** | 99.9 % > 1 000, always positive, 519 … 107 600 | 🟡 a **radius or extent** | | 8–11 | as `f32` these are **denormals** (1.4 × 10⁻⁴⁵ upward) — i.e. they are **integers**, not floats | ✅ integer fields | | 12–23 | six **pairs**: the even slot 200 … 67 000 and never zero, the odd 0 … 212 000 and zero in 7–13 % | ❔ | The denormal signature in slots 8–11 is worth stating plainly: a float field never holds `1.4e-45`, so those four words are integers that a float reader would silently turn into near-zero garbage. A position plus a positive scalar plus integer links is the shape of a **bounding-volume hierarchy node**, which would fit a file that also carries a point list and a plane list. That is a reading of the shape and nothing more. ### ❌ The index test has no discriminating power I tried to confirm the integer slots are indices by splitting each into two `u16`s and checking them against each section's record count. The result is useless, and the reason is worth recording: | slot | halves valid for section 0 | section 1 | section 2 | |---|---|---|---| | 8 | 100.00 % | 100.00 % | 100.00 % | | 9 | 100.00 % | 99.99 % | 100.00 % | | 10 | 8.78 % | 44.19 % | 100.00 % | | 11 | 8.76 % | 44.16 % | 100.00 % | **A test that accepts every hypothesis rejects none.** Section 2 has tens of thousands of records, so "is this `u16` below the plane count" is satisfied by almost any small number — it measures the size of the section, not the meaning of the field. Only slots 10 and 11 discriminate at all, and they merely rule *out* section 0. `slot 11`'s halves are consecutive (`n`, `n+1`) in 54 % of records and slot 10's in 12 % — suggestive of paired links, but 54 % is not a rule and I am not promoting it. ❔ So section 1 stays open. What would settle it is a test with power: pick a record, follow a candidate index, and check that the thing it lands on is spatially consistent with that record's own position and radius. That needs the tree walked, not the fields counted. ## ❌ The BVH reading is refuted — and slot 7 is a *local* scale **2026-08-26.** Last iteration I wrote that "position + positive scalar + integer links is the shape of a bounding-volume hierarchy node", explicitly as a reading of the shape. Tested with a design that has power, it fails. **The containment test.** If slots 8–11 hold child indices, a child's sphere should sit inside its parent's. Following every `u16` half of every integer slot and checking `|C_child − C_parent| + R_child ≤ R_parent` (2 % slack): RANDOM control 0 of 126 787 = 0.00 % slot 8 half 0 63 389 tried 0.00 % slot 8 half 1 63 395 tried 0.00 % …every candidate… 0.00 % **The random control is the informative row.** It is also 0.00 %, which means no node's sphere contains any other node's sphere *anywhere in the file* — so there is no nesting for an index to point at, whatever the indices mean. The hypothesis fails before the indices are even in question. **Why**: slot 7 is far too small to bound neighbours. | | median | p10 | p90 | |---|---|---|---| | slot 7 | **3 139** | 1 965 | 9 275 | | pairwise centre distance | **45 457** | 19 071 | 126 295 | Slot 7 is **14× smaller** than the typical distance between nodes, and a random other centre falls within it only **0.40 %** of the time. It is also smaller than the smallest grid cell on any map (10 000). So ✅ **slot 7 is a local scale, not a hierarchy radius** — sub-cell sized, with a narrow spread. Together with 63 410 scattered centres across a 500 km cube, that is the shape of **many small independent volumes**, not a tree. 🟡 That fits per-object collision volumes — a map's asteroids and debris, which the mission `Route` tables independently show as `Frame_S_Asteroid` records. Stated as a reading, not a measurement; nothing here counts objects. ❔ Still open: what slots 8–11 index, and what the six pairs in 12–23 are. What this iteration removed is a wrong frame — the file is not a tree, so tree-shaped tests will keep returning nothing. ## ❌ The cell index does not reference section 1 — two powered tests, both negative **2026-08-26.** The obvious coupling in a file with a uniform grid and a list of small volumes is that the grid indexes the volumes. It does not, by the only test that could show it: **spatial agreement**. **Test 1 — the cell payload as indices.** For every occupied cell, read its 32-byte payload record and try each `u16` in it as a section-1 index, then check whether that node's centre lies **inside the cell that referenced it**: RANDOM control 0.138 % +0 0.08 % +2 0.18 % +4 0.11 % +8 0.08 % +10 0.10 % +12 0.08 % +14 0.08 % … Every field sits at the chance rate. **Nothing points at section 1.** **Test 2 — the cell payload as coordinates.** 32 bytes is eight floats, so a position could be in there. Trying every float triple and asking whether it lies inside its own cell: +0 0.81 % +4 0.81 % +8 0.15 % +12 0.16 % +16 0.26 % +20 0.78 % Also chance. ### ⚠️ And the tempting number in that table is worthless The same run reported those triples lie **inside the object's bounding box in 100.00 %** of cases, at five different offsets. That looks like a decode and is not: the bbox spans the entire 500 km map, so *any* mid-range float triple passes, and overlapping windows starting at +0 and +4 both scoring 100 % is the tell — a real field would not survive being read at a four-byte shift. It measures the size of the box, not the meaning of the bytes. This is the third time in this file's investigation that a containment test against something large has produced a meaningless 100 %, so it is recorded rather than quietly dropped. ❔ So the grid and section 1 have no demonstrated link, and how a cell reaches its geometry is unknown. What is now excluded: the cell payload holding section-1 indices, and holding cell-local coordinates. ✅ Incidental, from the same sweep: `u32` slots at **+0, +8 and +12** of the payload record are below `0x10000` in **100 %** of records, while +4, +16, +20 and +24 are in only 11 % and +28 never — so the record has three index-shaped fields and four wide ones, whatever they refer to. ## ❌ …nor the point list, nor the plane list — the static coupling search is exhausted **2026-08-26.** The previous test only tried section-1 targets, which left the obvious gap: the payload's three index-shaped `u32`s might address the **points** or the **planes** instead. Tested the same way — follow the index, ask whether the target lies inside the cell that referenced it: RANDOM control 0.203 % +0 -> points 0.17 % planes 0.16 % +8 -> points 0.81 % planes 0.09 % +12 -> points 0.81 % planes 0.09 % All at the control rate. The two 0.81 % cells are 4× the baseline, and I am **not** treating that as a signal: across this and the previous iteration I have now run on the order of twenty of these tests (three index fields × three sections × two readings × several offsets), and at that count a single 4× enrichment on ~8 000 trials is what noise looks like. Reporting it as a lead would be exactly the multiple-comparisons error that a long hypothesis sweep invites. ### Where this leaves `REGN` ✅ Decoded: the header and grid, section 0 (points), section 2 (planes), section 3 (the cell index), and the strides and field regions of section 1. ❌ Not decoded, and **not reachable by the tests available statically**: any link between the grid and the geometry. Every index-shaped field has been followed into every section and checked for spatial agreement, against controls, and nothing rises above chance. ❔ **What would actually settle it** is the code — find what reads a `REGN` object in the executable and watch which fields it dereferences. That is static PE work (the flat `.pe` in the project root, offset = VA − 0x82000000) of the same kind that cracked the `.slb` packing phase, and it is the honest next step rather than a twenty-first correlation. --- # ✅ 2026-08-26 — the reader found: `REGN` is a **tetrahedral navigation mesh** The previous section closed with "find what reads a `REGN` object in the executable and watch which fields it dereferences". That worked, and it did not need the consumer: the **deserialiser** answers the question, because the file carries its own pointer map and the deserialiser tells you how to read it. ## ✅ The reader — `sub_82465110` / `sub_82465138` / `sub_82465200` Three functions, all in the resource module around `0x82460000`: ``` sub_82465110 find_pof0(chunk) 82465110 lwz r11, 4(r3) ; datasize 82465118 add r11, r11, r3 82465120 addi r3, r11, 16 ; -> chunk + 16 + datasize 82465124 lwz r11, 0(r3) 82465114 lis r10, 0x504F / 8246511c ori r10, r10, 0x4630 ; 'POF0' 82465128 cmplw cr6, r11, r10 8246512c beqlr cr6 ; else return 0 ``` ``` sub_82465138 relocate_chunk_chain(chunk) 82465164 lbz r11, 8(r31) / clrlwi r11,r11,31 ; already-relocated bit 82465178 bl 0x82465110 ; find the POF0 chunk 82465194 addi r4, r11, 16 ; POF0 payload 82465198 lwz r5, 4(r11) ; POF0 payload size 8246519c addi r3, r31, 16 ; ← THE FIXUP BASE = chunk + 0x10 824651a0 bl 0x82465200 824651a8 ori r11, r11, 0x1 / stb r11, 8(r31) ; set the bit ``` ``` sub_82465200 apply_pof0(base=r3, table=r4, size=r5) 82465224 clrrwi r8, r10, 6 ; top two bits of the lead byte select 82465228 cmplwi cr6, r8, 0x40 ; 0x40 → 6-bit delta, 1 byte 82465230 cmplwi cr6, r8, 0x80 ; 0x80 → 14-bit delta, 2 bytes 82465238 cmplwi cr6, r8, 0xC0 ; 0xC0 → 22-bit delta, 3 bytes 82465258 add r11, r10, r11 ; running WORD index, never reset 8246525c slwi r8, r11, 2 82465260 lwzx r10, r8, r3 ; slot = base[word] 82465264 cmplwi cr6, r10, 0x0 8246526c add r10, r10, r3 ; *slot += base (skipped when *slot == 0) 82465270 stwx r10, r8, r3 ``` Two things follow, and both are load-bearing: 1. **The fixup base is `chunk + 0x10`, not `chunk + 0`** (`82465198`: `addi r3, r31, 16`). Every stored "offset" in a `REGN` file is relative to file offset `0x10`, and every **record origin** on this page above is therefore 16 bytes early. 2. **The `POF0` table is an exact list of which words are pointers.** It is not a heuristic — it is the data the retail loader itself walks. Decoding it gives the pointer graph directly, with no guessing. ### 🔴 A correction to how I first stated point 1 The first version of this section said "everything on this page above was read 16 bytes early", which is **too broad and I withdraw it**. For the plane fields it is *false*: the older reading put the section at `chunk + offset` and the normal at intra-record `+16`, which addresses **exactly the same bytes** as `chunk + 0x10 + offset` with the normal at `+0`. Its unit-normal and `n·p + d = 0` results were measuring real planes and stand unchanged. On `3506e972`, both conventions put face record 0's normal at file offset **`0x1c700` (116 480)** = `0x10 + 0x1c6f0`, where the header word at `0x78` is `0x1c6f0`. What is genuinely wrong is the **record boundary**, and it matters for one reason: it decides which 48-byte record the four integer words belong to — and those integer words are the face adjacency, i.e. precisely the thing the correlation search was hunting for. It also mis-resolves every stored pointer by 16 bytes, twice over along the cell → item → ref → tetrahedron chain, which is the mechanical reason that chain never landed on anything. ### ✅ Which tests actually decide the origin — and which have no power Most of the numbers on this page are **content** tests and address the same bytes under either convention, so they cannot settle the origin. Stated plainly, because the same trap caught the point-in-bbox test: | test | discriminates the base? | |---|---| | section-5 targets on 96-byte boundaries; ref-array packing | ❌ no — `target − start` cancels the base | | face passes through 3 of 4 vertices; portal-cost identity | ❌ no — same absolute bytes either way | | sphere reaches its cell (98.7 % vs 18–28 %) | ❌ no for the base; it discriminates the **axis order** | | points inside the bbox (the older section) | ❌ no — a denormal reads as ≈ 0, which is inside a ±250 km box | | **the loader's own `addi r3, r31, 16`** | ✅ direct | | **where `POF0` says the header pointers are** | ✅ at `+0x10` the six relocated slots are exactly `0x70`–`0x84`, the six section pointers. At `+0` they would be `0x60`–`0x74`: the loader would relocate the `u16` **counts** and would leave the pointers at `0x78`–`0x84` unrelocated. Not merely wrong — non-functional. | | **what section-0 record 0 contains** | ✅ at `+0x10` a real vertex (`-250000, 250000, -250000` on `d4c89536`); at `+0` the two remaining header pointer words read as floats — `2.2e-40, 2.7e-40, 0` | | **the section-2 record boundary** | ✅ see below, 100.000 % against 0.000 % | ### ✅ The record boundary, settled A tetrahedron names face `f`; the plane at record `f` is independently verified (three of the tet's four vertices lie on it, 100 %). The question is whether the adjacency block that says *"I am face `f`, my tetrahedra are A and B, at their face slots i and j"* sits in the **same** 48-byte record as that plane. Requiring `own == f` **and** `tet[A].faces[i] == f`: adjacency block taken from record f (base + 0x10) : 100.000 % adjacency block taken from record f + 1 (base + 0) : 0.000 % 11 of 11 objects, every face, both sides. The plane and the four integer words that describe it are one record, and that record starts at `chunk + 0x10 + offset + 48·f`. `sub_82465138` is reached from exactly two callers, `sub_82461018` (vtable slot 9 of the class at `0x820af8bc`, the pak/resource file class) and `sub_82461DE8`; both store `chunk + 16` as the object's data pointer, which confirms the same `+0x10` base from the other side. ### 🔴 …and the magic is never compared Worth recording because it is what sent the search to the fixup table: **`'REGN'` and `'MCOL'` are not constructed anywhere in the executable.** The title builds its four-character tags as `lis`/`ori` pairs, and a sweep of every such pair recovers 156 tags — `RATC`, `T8aD`, `XBG7`, `IPFB`, `IDXD`, `LSTA`, `POF0`, `PRMD`, `TBMD`, `WMV3` … — but neither of these. Nor does either half appear as an immediate anywhere: `0x474E` (`'GN'`) occurs **zero** times in 1 865 751 instructions, and the flat PE image contains the byte string `REGN` **zero** times. So no magic-dispatch site exists to find; `.rgn` objects are handed to the map code by the stage record, not identified by their tag. ## ✅ The header is 0x70 bytes at `chunk + 0x10`, with **six** sections Corrected, and re-derived from the `POF0` table, which relocates exactly six header words (`0x70`, `0x74`, `0x78`, `0x7c`, `0x80`, `0x84`) on 11 of 11: ``` chunk +0x00 char[4] 'REGN' +0x04 u32 data size (POF0 chunk at +0x04-value + 0x10) +0x08 u8 flags; bit0 = "already relocated" (set by sub_82465138) data = chunk + 0x10: +0x00 f32[4] bbox min (w = 1.0) +0x10 f32[4] bbox max +0x20 f32[4] extent +0x30 f32[4] cell size +0x40 u32[4] grid dims +0x50 u16[6] record counts, one per section +0x60 ptr[6] section pointers ``` The old page had four sections because it read the last two pointers as data. There are six, their strides are `12, 96, 48, 8, 32, 4`, and each section's span divided by its stride is its `counts[]` entry exactly — 11 of 11, with the only slack being 16-byte alignment padding and, for the face list, **two all-zero sentinel records** (which is the unexplained "constant 96-byte tail" from the section above: 2 × 48). | # | contents | stride | count | |---|---|---|---| | 0 | vertices | 12 | `counts[0]` | | 1 | **tetrahedra** | 96 | `counts[1]` | | 2 | **faces** (plane + adjacency) | 48 | `counts[2]` | | 3 | cell index, one per cell | 8 | `counts[3]` = cells | | 4 | cell items, one per **occupied** cell | 32 | `counts[4]` | | 5 | tetrahedron references | 4 | `counts[5]` | ## ✅ How a cell reaches its geometry — the question, answered The `POF0` table places every pointer in the file, and there are only four kinds. Verified on all 11 objects by `tools/re-capture/regn_decode.py verify`: * the six header words, and nothing else in the header; * **one pointer per occupied cell**, at section-3 record offset **`+4`** — so a cell is `{ u32 count; item* }` and the *count* word is not a pointer; * **exactly one pointer per section-4 record, at offset `+0x14`** — the 32-byte cell item is `{ …, u32 n @+0x10, tetref* @+0x14, … }`; * **every word of section 5**, all `counts[5]` of them. So the chain is: ``` position ─▶ cell (x,y,z) index = (z·dimY + y)·dimX + x ─▶ sec3[index] {count, item*} ─▶ item {…, n @+0x10, refs* @+0x14, …} ─▶ refs[0 .. n) each a pointer into section 1 ─▶ tetrahedron ``` Four independent checks, all 11 of 11 objects: * **section-5 targets land on section-1 record boundaries** — every one of **261 000** pointers is `sec1 + 96·k` with zero remainder; * **the reference arrays are packed contiguously in cell order** — `item[i].refs == sec5 + 4·Σ item[j