This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docs/re/structures/asteroid-fields.md
Sylpheed RE agent 863a88dbf3 re: EnumAsteroid counts the rocks, and the hash join was mine to fix
EnumAsteroid is the frame record's FrameCount - 57/57, zero mismatches. Each
AsteroidFrameName is itself an IDXD record name; those records carry one named
field, FrameCount, plus a run of anonymous ones, and the anonymous fields
number exactly 8 x FrameCount on all 384 occurrences (ratio histogram
{8.0: 384}). The frame record is the placement table, 8 values per asteroid,
and EnumAsteroid counts the rocks. The frame-name -> EnumAsteroid map is
single-valued for all 64 names.

mission-wave-arrivals already met these records - they were the outliers that
broke its route-speed measurement, filtered out by name. regn-map-grid already
guessed the link and said so honestly ("a reading, not a measurement; nothing
here counts objects"). Neither says the count is exact.

The abandoned table lost its placement data too: exactly 7 of 64 frame names
have no record, and they are exactly the seven groups of the unreferenced
tenth object (Frame_Alpha_S01_Asteroid_{01,02,04}, Frame_Alpha_S01_Haze_
{01,02,03}, Frame_TAlpha_S01_Asteroid_03). 57 + 7 = 64, zero partials.

Withdrawing the previous commit's red flag: the hash join works and my call
was wrong. AsteroidDefinition values resolve to their objects' pak entry keys
as name_hash("stage\" + name), 9 of 9, each landing on the object the
frame-prefix join independently predicted. I had hashed the bare file name;
archive_naming.py hashes prefix + name over a path-prefix list. Two
independent joins, 9/9 agreement, both leaving the same tenth object
unreferenced.

Not settled: what the 8 values per asteroid are; why S28_p1 has a volume and
no definition.

All fifteen artefacts byte-identical.
2026-08-28 01:48:52 +00:00

121 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# The asteroid-field tables (`AsteroidGroup_00N`)
**Status: ✅ decoded statically, 2026-08-28.** Every number below is an exact
disc census over all 41 `.pak` archives using the corpus reader.
## Where it sits in the chain
[[stage-definition-table]] and [[stage-mission-tables]] already record that a
stage's `Phase_N` block carries an **`AsteroidDefinition`** field naming a `.tbl`
(`test_s8p1_asteroid.tbl` in the `_Test` template, `""` in most phases), and
[[unit-datasheet-static]] already partitions the `Generic` records and finds
**10 per pack whose only field is `{EnumAsteroidGroup}` — "an asteroid-group
file"**. What neither says is what is *inside* those ten files.
```
Stage_SNN . Phase_N . AsteroidDefinition = "S04_asteroid.tbl"
└── that object: Generic . EnumAsteroidGroup = "7"
AsteroidGroup_000 … AsteroidGroup_006
AsteroidModelName = mob_n050
AsteroidFrameName = Frame_S04_Asteroid_01
EnumAsteroid = 39
```
## ✅ The table
**10 objects per pack × 6 `GP_MAIN_GAME_<lang>` packs = 60**, holding **384
`AsteroidGroup_*` records** in total. Each object has **4 or 7** groups (12
objects with 4, 48 with 7). Every group record carries exactly **three** fields,
present on all 384 with no partials:
| field | distinct values | what it is |
|---|---:|---|
| `AsteroidModelName` | 28 | the mesh — `mob_n050``mob_n056` (24 uses each) and `mob_n040``mob_n043` (18 each) |
| `AsteroidFrameName` | 64 | `Frame_S<NN>[_pN]_Asteroid_NN` — the placement frame |
| `EnumAsteroid` | 37 | a **count**, 1 … 588; 6 633 asteroids per pack summed |
`Frame_S<NN>_Asteroid` is the same name [[regn-map-grid]] reports the mission
`Route` tables showing independently — the frame is the join to the map data.
## ✅ `Enum<Thing>` is a count; `Enumerate<Thing>` names a table
`EnumAsteroidGroup` equals the number of `AsteroidGroup_*` records in its own
object in **54 of 60** objects, and `EnumAsteroid` is a plain integer. That is
the opposite of the `Enumerate*` convention, where the value is a child table's
file name. **The `-erate` is the difference**, and it is worth checking the
spelling before assuming which kind a field is.
⚠️ `Count`-style fields still are not safe: the **6 failures are one object,
repeated once per language pack** — it declares `4` and contains `7`.
## 🔑 The tenth object is unreferenced, and it is the one that miscounts
Joining the ten objects to the nine `AsteroidDefinition` values by frame prefix:
| object's frame prefix | groups | declared | named by |
|---|---:|---:|---|
| `Frame_S01_Asteroid` | 4 | 4 | `S01_asteroid.tbl` |
| `Frame_S04/S05/S13/S14_p1/S14_p2/S08_p1/S08_p2_Asteroid` | 7 | 7 | the matching `SNN[_pN]_asteroid.tbl` |
| `Frame_Test_Asteroid` | 4 | 4 | `test_s8p1_asteroid.tbl` |
| **`Frame_Alpha_S01_Asteroid` + `Frame_Alpha_S01_Haze` + `Frame_TAlpha_S01_Asteroid`** | **7** | **4** | **nothing** |
Nine `AsteroidDefinition` names, nine matching objects, and a **tenth that no
phase names** — an `Alpha` Stage-01 variant with its own `Haze` frames and a
`TAlpha` set. It is also the only object whose declared count is wrong, which is
what an abandoned table looks like.
## 🔑 S28 has an asteroid *volume* but no asteroid *definition*
[[mcol-collision]] lists **nine** `_AsteroidVolume_wp` collision meshes: S01,
S04, S05, S08_p1, S08_p2, S13, S14_p1, S14_p2 and **S28_p1**. The nine
`AsteroidDefinition` values are the same eight stages plus **`test_s8p1`**. So
the two sets share eight and differ by one each: **`S28_p1` has the collision
volume for an asteroid field but no table saying which rocks to scatter in it**,
while `test_s8p1` has a table with no volume of its own.
## ✅ `EnumAsteroid` is the frame record's `FrameCount` — 57/57 (2026-08-28)
Each `AsteroidFrameName` is itself an **IDXD record name**. Those records carry
one named field, **`FrameCount`**, and a run of anonymous ones:
* **`EnumAsteroid` equals that record's `FrameCount` in 57 of 57** frames that
have a record — **zero mismatches**, and the map is single-valued for all 64
frame names.
* The anonymous fields number **exactly 8 × `FrameCount`, on all 384 occurrences**
(ratio histogram: `{8.0: 384}`). So the frame record is a table of
**8 values per asteroid** — the placement data — and `EnumAsteroid` counts the
rocks.
[[mission-wave-arrivals]] already met these records: they were the outliers that
broke its route-speed measurement, and it filtered them out by name, noting "the
corpus already records that the 8-value frame is not universal". [[regn-map-grid]]
already guessed the link — "a map's asteroids and debris, which the mission
`Route` tables independently show as `Frame_S<NN>_Asteroid` records… stated as a
reading, not a measurement; nothing here counts objects." **What neither says is
that the count is exact.** Now it is measured.
🔑 **The abandoned table lost its placement data too.** Exactly **7 of the 64**
frame names have no record, and they are exactly the seven groups of the
unreferenced object: `Frame_Alpha_S01_Asteroid_{01,02,04}`,
`Frame_Alpha_S01_Haze_{01,02,03}`, `Frame_TAlpha_S01_Asteroid_03`. `57 + 7 = 64`,
zero partials on either side.
## ✅ The name→object join DOES reproduce by hash — with the path prefix
Withdrawing the 🔴 from the first write-up. `AsteroidDefinition` values resolve
to their objects' pak entry keys as **`name_hash("stage\" + name)`**, **9 of 9**,
each landing on the object the frame-prefix join independently predicted. My
first attempt hashed the bare file name; [[archive-naming]]'s resolver hashes
`prefix + name` over a list of path prefixes, and `stage\` is the one that
works here. (`Stage\` scores identically — the hash lower-cases.)
**Two independent joins, 9/9 agreement**, and both leave the same tenth object
unreferenced.
## 🟡 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]]).