# 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_` 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[_pN]_Asteroid_NN` — the placement frame | | `EnumAsteroid` | 37 | a **count**, 1 … 588; 6 633 asteroids per pack summed | `Frame_S_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` is a count; `Enumerate` 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. ## 🟡 Not settled * What `EnumAsteroid` counts *of* — instances per frame is the obvious reading and the 1…588 range fits, but it is untested. * Why `S28_p1` has a volume and no definition (S28 is the challenge mission that alone flies `rou_f004`, see [[stage-numbering-and-player-craft]]). * 🔴 **The name→object join did not reproduce by hash.** `AsteroidDefinition` values do not map to their objects' pak entry keys under `name_hash`, nor under that key reduced `mod 0x00FFF9D7` or masked to 24 bits — the join above is by frame prefix, which is direct. Either these keys are not name hashes or [[archive-naming]]'s resolver differs from `unitgroup.name_hash`; not chased.