The original reason for investigating REGN was that a mission's enemy count
rises and falls, so a scheduler with parameters must exist somewhere, and a
per-map uniform grid is what such a thing would be indexed by.
Now that it is decoded that reasoning is answered: REGN is a tetrahedral
navigation mesh -- vertices, faces carrying plane equations and adjacency,
tetrahedra with portal costs between face pairs, and a grid indexing which tets
fall in each cell. Every section is accounted for by that structure, and there is
no time field, no unit reference and no trigger anywhere in it.
So the wave-scheduler search should treat REGN as excluded rather than unread.
The page's original hedge was right to keep the reading provisional, but the
reasoning it hedged was a guess from shape, and the shape belonged to
pathfinding -- which is what pointed the whole investigation here.
The arrival timetable in Route_S<NN>.tbl, keyframed per squadron per phase with
t in seconds, remains the only located part of the mechanism.
Re-derived the other branch's central check with my own code, my own reading of
the record and my own control, rather than accepting the number.
At base chunk+0x10, with the plane at intra-record +0 and three u16 vertex
indices at +32: every one of 133573 faces has all three named vertices
satisfying its own plane equation. Random-vertex control 2782/400719 = 0.69%.
100% against 0.69% is not a fit.
That also settles the record boundary from my side: the u16s describing a plane
sit after it in the same 48-byte record, so my earlier 'four zeros at the start
of each record' was those integers seen 16 bytes out of position, one record
late.
Two implementations, two independent guesses at the intra-record layout, the
same 100%.
The other branch supplied concrete offsets: for 3506e972 its face record 0 and
its plane normal both begin at 0x1c700, and my chunk + offset_at_0x78 + 16 gives
0x1c700. Same bytes, different bookkeeping -- so the n.p+d result stands
unchanged and was never in dispute.
The base is chunk+0x10, on evidence with power: the loader does addi r3,r31,16;
at +0x10 the six POF0-relocated slots land exactly on 0x70-0x84, the six section
pointers, whereas at +0 they would relocate the u16 counts and leave two section
pointers unrelocated, which is non-functional; and section-0 record 0 reads as a
bbox corner at +0x10 and garbage at +0.
So my '13467/13467 points inside the bbox' was vacuous. Only 11 of 13467 read as
denormal at the wrong base -- the rest were still plausible coordinates, because
a 16-byte shift inside a packed array of f32 triples yields other floats from
the same array. Recorded the general form: a containment test cannot detect a
shift inside a homogeneous array, because the shifted values come from the same
distribution. For that class of error it is not a weak check, it is no check.
'Section 0 is a point list' happens to be right; the evidence I gave for it was
not evidence.
That branch decodes REGN as a tetrahedral navmesh with strong checks and claims
the POF0 fixup base is chunk+0x10, so every offset on this page was read 16
bytes early.
I could not reproduce that on the one independently checkable thing here: the
plane list gives 133573/133573 unit normals at the unshifted base and 0/133573
at +16, and n.p+d = 0 holds to float round-off unshifted. A 16-byte shift
destroys it, so the blanket statement does not hold for this record.
Likely reconciliation is bookkeeping: a 48-byte face whose plane fields sit at a
different intra-record offset addresses the same bytes from a different origin.
That is a guess and I am not adopting either wording until checked.
Also confirmed: my own section-0 point test passes at 100% at BOTH bases, so it
never had power to distinguish them and should not be cited as validating the
offsets.
The previous test only tried section-1 targets. Closing that gap: the payload's
three index-shaped u32s, followed into the point list and the plane list and
checked for the target lying inside the referencing cell, all sit at the 0.203%
random control.
Two cells read 0.81%, 4x the baseline. I am not treating that as a lead: across
this and the previous iteration roughly twenty such tests have been run, and at
that count a single 4x enrichment on ~8000 trials is what noise looks like.
Calling it a signal would be the multiple-comparisons error a long hypothesis
sweep invites.
So REGN's header, grid, points, planes and cell index are decoded, section 1's
slot regions are censused, and the link between the grid and the geometry is not
reachable by any static test I can construct. The honest next step is the PE
code that reads a REGN object -- the same kind of work that cracked the .slb
packing phase -- rather than a twenty-first correlation.
The natural coupling in a file with a uniform grid and a list of small volumes
is that the grid indexes the volumes. Tested by spatial agreement, it does not.
Test 1: every u16 in a cell's 32-byte payload, tried as a section-1 index and
checked for its centre lying inside the referencing cell. Every field sits at
the 0.138% random-control rate.
Test 2: every float triple in the payload, checked for lying inside its own
cell. 0.15-0.81%, also chance.
Recorded a worthless number from the same run rather than dropping it: those
triples lie inside the object's BOUNDING BOX in 100.00% at five different
offsets. The bbox spans the whole 500 km map so any mid-range triple passes, and
overlapping windows at +0 and +4 both scoring 100% is the tell -- a real field
would not survive a four-byte shift. Third time in this investigation that a
containment test against something large has produced a meaningless 100%.
Incidental and real: u32 slots at +0, +8 and +12 are below 0x10000 in 100% of
payload records while +4/+16/+20/+24 are in 11% and +28 never, so the record has
three index-shaped fields and four wide ones.
Last iteration I offered 'position + scalar + integer links is the shape of a
BVH node' as a reading of the shape. Tested properly it fails.
Following every u16 half of every integer slot and checking child-sphere-inside-
parent-sphere gives 0.00% for every candidate -- but the informative number is
the RANDOM control, also 0.00%. 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 and
the hypothesis dies before the indices matter.
The reason is scale: slot 7 has a median of 3139 against a median inter-node
distance of 45457, 14x smaller, and a random other centre falls within it 0.40%
of the time. It is also smaller than the smallest grid cell on any map.
So slot 7 is a LOCAL scale, not a hierarchy radius. 63410 scattered centres each
with a sub-cell extent is the shape of many small independent volumes, which
would fit per-object collision hulls for asteroids and debris -- a reading, not
a measurement.
What this removes is a wrong frame: the file is not a tree, so tree-shaped tests
will keep returning nothing.
96 bytes is 24 slots. Over all 63410 records: slots 4-6 hold values in the
header bbox range (a position), slot 7 is always positive 519..107600 (a radius
or extent), slots 8-11 are DENORMAL as floats -- 1.4e-45 upward -- so they are
integers a float reader would turn into near-zero garbage, and slots 12-23 are
six pairs with distinct even/odd distributions. Slots 2 and 3 are ~always zero.
Position + positive scalar + integer links is the shape of a BVH node, which
would fit a file carrying a point list and a plane list. That is a reading of
the shape and nothing more.
Recorded a failed test and why it failed: splitting the integer slots into u16
halves and checking them against each section's record count accepts ALL THREE
sections at ~100% for slots 8 and 9. A test that accepts every hypothesis
rejects none -- section 2 has tens of thousands of records, so the check
measures the section's size rather than the field's meaning. Slot 11's halves
are consecutive in 54%, which is suggestive and not a rule.
What would settle it is a test with power: follow a candidate index and check
the target is spatially consistent with the record's own position and radius.
The three sections recorded as undecoded are fixed-stride arrays and counts[0..2]
are their record counts: 12, 96 and 48 bytes. Section 1's remainder is exactly 0
in 11/11 objects and section 2's exactly 96 in 11/11, which is what makes these
strides rather than a coincidence of division.
Section 0 is a point list: 13467 of 13467 records lie inside their object's own
header bounding box.
Section 2 is a plane list, 12 f32: four zeros, a unit normal (|n|=1 in
133573/133573), a signed distance, a point inside the bbox (133573/133573), and
a trailing 1.0 (133573/133573). The decisive check is algebraic -- n.p + d must
vanish for a real plane, and over all 133573 records the relative residual has a
median of 2.29e-08 and a maximum of 2.15e-07. That is float round-off, not a fit.
So a REGN object carries a point list and a plane list beside its uniform grid,
which fits collision or region-boundary geometry and sits next to MCOL.
Still open: section 1 (96 B, 60631 records), what queries the planes, the zeros
at [0..3], and the constant 96-byte tail.
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.
Every one of the 11 objects contains POF0 near the tail, at exactly
header[0x04] + 16 - an 11 of 11 relation. POF0 is a pointer-offset fixup table,
so the file is a serialised C++ object graph the loader patches on load, which
also explains why the offsets inside the cell index are absolute FILE offsets.
header[0x04] is therefore the size of the data area.
Two readings of the cell payload are recorded as refuted rather than dropped,
because both were tempting and both came from the smallest object alone: the f32
at record +0x1c is NOT a bounding-sphere radius (ratio to sqrt(3)*half-extent is
1.001 on that one object and 0.13-0.27 on the other ten), and a record's
(count, offset) pairs do NOT point at leaf arrays of count*4 bytes (0 of 11
objects clean). What survives is descriptive only: the payload is dominated by
float data, and the printable runs a string scan finds are float high-bytes
rather than text.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
The fourth section is one 8-byte (count, offset) record per grid cell, followed
by the 32-byte records it points at. The check: the lowest offset any cell refers
to equals align16(offsets[3] + cells*8) on 11 of 11 objects - and the alignment
term is visible rather than assumed because the three 5x5x5 maps have 125*8 =
1000 bytes of index, which is not 16-aligned, so their payload starts 8 bytes
later than the six 10x10x10 maps'.
Two further invariants from the same sweep: every occupied cell has count exactly
1 (total items == occupied cells on all 11, so it is one record per cell rather
than a bucket list), and counts[4] equals occupied cells + 2 exactly on all 11 -
the +2 unexplained and recorded as such.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
hidden/MiscBin.pak was undocumented: 40 entries, none name-resolved, holding 11
REGN objects and 11 MCOL objects (plus 18 others). Eleven of each pairs them one
per map.
The REGN header decodes to a bbox, an extent, a cell size, grid dimensions, six
counts and four section offsets - and it self-checks twice over all 11 objects:
extent == cell x dims holds exactly 11 of 11, and counts[3] equals the cell count
(1000 on every 10x10x10 map, 125 on every 5x5x5). Two independent fields
reproducing the same grid is what makes it a decode rather than a guess.
Three map sizes exist: half-extent 250000 with 50 km cells, 50000 with 10 km
cells, and 25000 with 10 km cells on a 5x5x5 grid.
Written without overclaiming against the question that prompted it: a mission's
enemy count rises and falls, so a scheduler with parameters exists somewhere, and
a per-map cell grid is the kind of structure such a thing is indexed by - but the
four data sections are unread and nothing here shows spawn parameters.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE