From 1f0f90e3046319ad0c8f6d369cc9eb5d09cd992b Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Fri, 28 Aug 2026 02:03:23 +0000 Subject: [PATCH] re: the 8 values per asteroid are index, quaternion, position Measured over every Frame_*Asteroid* record on the disc - 384 records, 37518 items (6253 per language pack x 6; the remaining 380 per pack belong to the seven record-less Alpha frames, the same 57-vs-64 split as before). slot 0 equals the running index 0..N-1 37518 / 37518, max 587, and the largest FrameCount is 588, so the last index is N-1 slots 1-4 a unit quaternion 37518 / 37518 within 1e-4 of 1.0 (min 0.999999, max 1.000001) slot 4 sign of the real part min +0.001, never negative - canonical w-last, so the order is (x, y, z, w) slots 5-7 position in metres -163858..+79572, -114308..+76422, -105224..+110263 - inside the +/-250 km half-extent of mapmesh_box_500km len(anonymous fields) == 8 * FrameCount on 384 of 384, zero mismatches. The unit-norm test is the control: an arbitrary 4-tuple has no reason to sit on the unit sphere and every one of the 37518 does. Two further cross-checks fell out - the maximum index is exactly max(FrameCount) - 1, and every position lies inside the 500 km box the corpus already knows (world unit = 1 metre). There is no scale slot: an asteroid's size comes from its group's AsteroidModelName, which is why a group is one model plus one placement list. Not settled: whether the quaternion is object->world or world->object and its handedness - a norm test cannot separate those; and why S28_p1 has an asteroid volume with no definition. All fifteen artefacts byte-identical. --- docs/re/BACKLOG.md | 32 +++++++++++++++++++++++++++ docs/re/INDEX.md | 2 +- docs/re/structures/asteroid-fields.md | 32 +++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/docs/re/BACKLOG.md b/docs/re/BACKLOG.md index 02ebb6e8..5f2963e1 100644 --- a/docs/re/BACKLOG.md +++ b/docs/re/BACKLOG.md @@ -5793,3 +5793,35 @@ a discrepancy, **read how the corpus routine calls it** β€” the prefix list was 🟑 Not settled: what the 8 values per asteroid are (position/rotation/scale is the obvious reading, untested β€” [[regn-map-grid]] has the neighbouring work); why `S28_p1` has an asteroid volume and no definition. + +--- + +## βœ… 2026-08-28 β€” the 8 values per asteroid: index, quaternion, position + +Item (a). Measured over every `Frame_*Asteroid*` record on the disc β€” **384 +records, 37 518 items** (6 253 per language pack Γ— 6; the remaining 380 per pack +belong to the seven record-less `Alpha` frames, which is the same 57-vs-64 split +as before). + +| slot | test | result | +|---|---|---| +| 0 | equals the running index `0…Nβˆ’1` | **37 518 / 37 518**, max **587** β€” and the largest `FrameCount` is **588**, so the last index is `Nβˆ’1` | +| 1–4 | a **unit quaternion**? | **37 518 / 37 518 within 1e-4 of 1.0** (min 0.999999, max 1.000001) | +| 4 | sign of the real part | min **+0.001**, never negative β€” canonical w-last, so `(x, y, z, w)` | +| 5–7 | position in metres | βˆ’163 858…+79 572, βˆ’114 308…+76 422, βˆ’105 224…+110 263 β€” inside the Β±250 km half-extent of `mapmesh_box_500km` | + +`len(anonymous fields) == 8 Γ— FrameCount` on **384 of 384**, zero mismatches. + +**The unit-norm test is the control**: an arbitrary 4-tuple has no reason to sit +on the unit sphere, and every one of the 37 518 does. Two further independent +cross-checks fell out β€” the maximum index (587) is exactly `max(FrameCount) βˆ’ 1`, +and every position lies inside the 500 km box the corpus already knows +([[regn-map-grid]], world unit = 1 metre). + +πŸ”‘ **There is no scale slot.** An asteroid's size comes from its group's +`AsteroidModelName` β€” which is why a group is *one model plus one placement +list*, and why the group table needed both fields. + +🟑 Not settled: whether the quaternion is objectβ†’world or worldβ†’object, and its +handedness β€” a norm test cannot separate those. And still: why `S28_p1` has an +asteroid volume with no definition. diff --git a/docs/re/INDEX.md b/docs/re/INDEX.md index 53ce8cdd..b8a7143a 100644 --- a/docs/re/INDEX.md +++ b/docs/re/INDEX.md @@ -119,7 +119,7 @@ files, which is how the same ground got covered twice. | [`structures/isl-message-dialogue-link.md`](structures/isl-message-dialogue-link.md) | Mission scripts as dialogue β€” built-in 64 -> message id -> caption text | βœ… CONFIRMED total, 2 683/2 683 call sites across all 28 stages resolve, no residue | | [`structures/mission-objective-counter.md`](structures/mission-objective-counter.md) | `REMAINING OB` β€” the mission's own objective counter, in RAM | βœ… CONFIRMED for one Stage 02 run: a big-endian u32 whose value | | [`structures/movie-subtitles.md`](structures/movie-subtitles.md) | Movie subtitles & the movie ↔ mission ↔ text chain | β€” | -| [`structures/asteroid-fields.md`](structures/asteroid-fields.md) | `AsteroidGroup_00N` β€” the asteroid-field tables a `Phase_N.AsteroidDefinition` names | βœ… 10 objects/pack, 384 group records, 3 fields each (`AsteroidModelName`, `AsteroidFrameName`, `EnumAsteroid` = **the frame record's `FrameCount`, 57/57**, and the frame holds 8 anonymous values per asteroid); `Enum` counts while `Enumerate` names a table (54/60); the join resolves as `name_hash("stage\" + name)` 9/9; πŸ”‘ a tenth `Frame_Alpha_S01_*` object nothing references β€” it miscounts AND its 7 frames have no placement records; πŸ”‘ **S28_p1 has an asteroid volume but no definition** | +| [`structures/asteroid-fields.md`](structures/asteroid-fields.md) | `AsteroidGroup_00N` β€” the asteroid-field tables a `Phase_N.AsteroidDefinition` names | βœ… 10 objects/pack, 384 group records, 3 fields each (`AsteroidModelName`, `AsteroidFrameName`, `EnumAsteroid` = **the frame record's `FrameCount`, 57/57**, and the frame holds **`index, quaternion(x,y,z,w), position(x,y,z)`** per asteroid β€” 37 518 items, unit norm 37 518/37 518); `Enum` counts while `Enumerate` names a table (54/60); the join resolves as `name_hash("stage\" + name)` 9/9; πŸ”‘ a tenth `Frame_Alpha_S01_*` object nothing references β€” it miscounts AND its 7 frames have no placement records; πŸ”‘ **S28_p1 has an asteroid volume but no definition** | | [`structures/mcol-collision.md`](structures/mcol-collision.md) | `MCOL` β€” same container and map parameters as `REGN` | 🟑 OPENED β€” `POF0` at `data_size+16` 11/11, bbox pad words 11/11, `extent == maxβˆ’min` 11/11, and bbox + cell-size distributions identical to `REGN` (2/6/3 and 2/9); everything past `0x40` ❔ | | [`structures/regn-map-grid.md`](structures/regn-map-grid.md) | `REGN` β€” a per-map spatial grid (and `MCOL` beside it) | βœ… CONFIRMED for the header, which self-checks on all 11 objects on | | [`structures/savegame-format.md`](structures/savegame-format.md) | Save file (`savedata`) β€” container βœ… exact, 3 fields named βœ…, rest ❔ (2026-08-11) | βœ… CONFIRMED for the container and the chunk layout β€” parsed off the | diff --git a/docs/re/structures/asteroid-fields.md b/docs/re/structures/asteroid-fields.md index 79bdf441..8f263af1 100644 --- a/docs/re/structures/asteroid-fields.md +++ b/docs/re/structures/asteroid-fields.md @@ -112,9 +112,37 @@ works here. (`Stage\` scores identically β€” the hash lower-cases.) **Two independent joins, 9/9 agreement**, and both leave the same tenth object unreferenced. +## βœ… The 8 values are `index, quaternion(x,y,z,w), position(x,y,z)` (2026-08-28) + +Measured over every `Frame_*Asteroid*` record on the disc β€” **384 records, +37 518 items** (6 253 per language pack Γ— 6; the other 380 per pack belong to the +seven record-less `Alpha` frames). One raw item, for shape: + +``` +0 0.268744 0.505919 0.579670 0.579487 15667.14 -7199.61 -58794.88 +1 -0.053496 -0.540765 -0.260996 0.797868 -43571.37 -60583.68 -3417.80 +2 -0.696396 0.682371 … +``` + +| slot | test | result | +|---|---|---| +| 0 | equals the running index `0…Nβˆ’1` | **37 518 / 37 518**, max **587** β€” and the largest `EnumAsteroid`/`FrameCount` is **588**, so the last index is `Nβˆ’1` | +| 1–4 | is it a **unit quaternion**? `\|q\|` | **37 518 / 37 518 within 1e-4 of 1.0** (min 0.999999, max 1.000001) | +| 4 | sign of the real part | min **+0.001**, never negative β€” the canonical **w-last** form, so the order is `(x, y, z, w)` | +| 5–7 | position, metres | ranges **βˆ’163 858…+79 572**, **βˆ’114 308…+76 422**, **βˆ’105 224…+110 263** β€” inside the Β±250 km half-extent of `mapmesh_box_500km` | + +And `len(anonymous fields) == 8 Γ— FrameCount` on **384 of 384** records, zero +mismatches. + +The unit-norm test is the control: an arbitrary 4-tuple has no reason to sit on +the unit sphere, and **every one of the 37 518 does**. World unit = 1 metre, so +these are metres from the map origin. **There is no scale slot** β€” an asteroid's +size comes from its group's `AsteroidModelName`, which is why one group is one +model plus one placement list. + ## 🟑 Not settled -* What the 8 values per asteroid are β€” position/rotation/scale is the obvious - reading, untested here; [[regn-map-grid]] has the neighbouring work. * Why `S28_p1` has an asteroid volume and no definition (S28 is the challenge mission that alone flies `rou_f004`, see [[stage-numbering-and-player-craft]]). +* Whether the quaternion is objectβ†’world or worldβ†’object, and its handedness β€” + the norm test cannot tell them apart.