Sweeping the 811 unnamed IDXD objects in GP_MAIN_GAME_E.pak by schema turned up
schema 3c9ae32e: the per-stage definition record. 23 of them, one per stage,
each naming its background, resource package, collision set, message set,
nameplates, MapMesh/MapPath and EnumerateSquadron = UnitGroup_S<NN>.tbl.
That resolves two open threads at once:
- MapPath = test.rgn hashes to 0x3506e972, a REGN object in MiscBin.pak, and
MapMesh = test.col to 0x2cf7eb47, an MCOL object. REGN is a stage's map
path data; MCOL is its collision mesh.
- stage\UnitGroup_S02.tbl (0x019fd129, in all six language paks) is the
Stage 02 squadron roster: 112 records, 112 squadron IDs, and a field
vocabulary of FormationID / AIID / SideID / Count / DisableInterval, plus
the unit model (UN_e010_ADAN_Attacker_S and friends, which match the XBG7
mesh names we already decode), the MessageSet and the pilot character.
DisableInterval is the first direct evidence of the arrival-timing knob, which
is what the user's reframing predicted: the mission has a schedule with
parameters, not a fixed roster.
Container layout is only partly read. The 112x16 entry array was confirmed by
its boundary — keys increase for exactly 112 entries and break at 0x708, where
the next section header sits — not assumed. pak dump mislabels this file's
first key as its schema.
Refuted and recorded: the 16-byte record key is not the squadron ID's name
hash. name_hash("TCN001") = 0xd639f1a4 but the keys start 0x659aff47; 0 of 112
match.
Still open: the per-record payload fields, the meaning of the key, where the
interval values actually live, and the missing S17-S23 stage records.
6.2 KiB
REGN — a per-map spatial grid (and MCOL beside it)
Status: ✅ CONFIRMED for the header, which self-checks on all 11 objects on
the disc. ❔ the four data sections are undecoded. 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 × dimsholds 11 of 11, exactly;counts[3]equals the cell count:1000on every 10×10×10 map and125on 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+2is 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
f32at record+0x1cis the grid's bounding-sphere radius." One993b93eit 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 ofcount × 4bytes." True for the first record ofe993b93e; 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) 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.