re: who selects a loadout -- the pak entry does; the Arsenal pak is stage-scoped

Settled by elimination with two controls.  The 15 loadout names appear
as a field VALUE nowhere on the disc -- 0 occurrences across every pak
-- while the control Arbalest_155KG, which is referenced, appears 150
times as a value in the same pak.  They occur only as the field names of
the UNITS record.  They are not in the executable either; control:
WEAPONS (a section key) is, Arbalest_155KG is not.

So nothing references a loadout by name.  The selection is which pak
entry the Hangar loads.  GP_HANGAR_ARSENAL.pak has 180 IDXD entries in
10 shapes; 168 carry a UNITS roster = 28 stages x 6 languages, and the
other 12 = 2 x 6.  Each entry is one stage's whole Hangar config, and
its UNITS roster is the flight for that stage -- 5 distinct rosters over
15 / 5 / 5 / 2 / 1 stages, including one where Rhino2-Katana flies
alone.  Every count is a multiple of 6 and they sum to 28, the disc's
stage count by a fourth independent route.

Corrects the previous commit: it read the pak with setdefault, so
'15 loadouts / 24 allow-lists / STANDARD_ARM1 has 11 entries' is the
union of first-seen records, not one table.  Contents vary per entry --
PlayerSET_ARM1 has 5 distinct contents, STANDARD_ARM1 3, ExSET_NOSE 4.
The chain and both controls (60/60, 70/88) are per-record and
unaffected; only the per-list sizes were over-generalised.

Not settled: the entry filenames.  name_hash probing over 8 templates x
40 indices x 6 languages resolved 0, while the same probe's controls
<lang>\weapon.tbl and <lang>\strings.tbl resolved 12/12.

Artefact +40 lines / 1 changed heading; the other four regenerate
byte-identical.
This commit is contained in:
Sylpheed RE agent
2026-08-27 13:09:07 +00:00
parent 2b2d984f0c
commit 2b9709eaa0
4 changed files with 156 additions and 3 deletions

View File

@@ -7,6 +7,23 @@ with what**, and **what the Hangar is allowed to offer for each slot**.
Artefact `../data/hangar-loadouts.txt`, regenerator
`tools/re-capture/hangar_loadouts.py`.
> ## ⚠️ CORRECTION (2026-08-27, same day) — the pak is STAGE-SCOPED, and the
> ## counts below are a UNION, not one table
>
> `GP_HANGAR_ARSENAL.pak` has **180 IDXD entries in 10 distinct shapes**, and
> **168 of them = 28 stages × 6 languages** carry a `UNITS` roster. Each entry is
> **one stage's Hangar configuration**: its own `UNITS` roster, its own loadout
> records, its own allow-lists. The first pass read the pak with `setdefault`,
> keeping only the **first-seen** copy of each record name — so "15 loadouts / 24
> allow-lists / `STANDARD_ARM1` has 11 entries" is the union of first-seen, not a
> single table. The allow-list contents genuinely vary: `PlayerSET_ARM1` has **5**
> distinct contents across entries, `STANDARD_ARM1` **3**, `ExSET_NOSE` **4**;
> the `SNNSET_*` and `NULL_*` sets have exactly 1 each.
>
> **The structure of the chain below is unaffected** — the 60/60 and 70/88
> controls are per-record and still hold on the first-seen slice — but treat the
> per-list sizes as "one stage's", not "the game's".
`GP_HANGAR_ARSENAL.pak` carries **15 loadout records**`Bird1-Sandra`,
`Bird2-Billy`, `Bird3-Antonius`, `Bird4-Carl`, `Rhino1-Katana`,
`Rhino1-Raymond`, `Rhino2-Ellen`, `Rhino2-Gene`, `Rhino2-Katana`,
@@ -79,9 +96,43 @@ two Arm1 items, `STANDARD_ARM1` offers eleven.
Both are single rows against 13 that resolve, so they are exceptions in the
data, not a wrong reading of the field.
## ✅ Who selects a loadout — the pak ENTRY does
Settled the same day, by elimination with two controls:
* The 15 loadout names appear as a field **value nowhere on the disc** — 0
occurrences across every pak. **Positive control in the same loop:** the item
name `Arbalest_155KG`, which *is* referenced, appears **150** times as a value
in the same pak. They appear only as the **field names of the `UNITS` record**,
i.e. `UNITS` is the index over them.
* They are **not in the executable** either. **Control:** `WEAPONS` (a section
key) *is* in the executable; `Arbalest_155KG` is not — so the executable holds
table keys, not row names.
So nothing references a loadout by name. The selection is **which pak entry the
Hangar loads**, and there is one per stage per language (168 = 28 × 6). The
entry's `UNITS` roster is the flight for that stage, and it changes across the
campaign exactly as the story does:
| stages | pilots in `UNITS` |
|---:|---|
| 15 | Bird 14 (Sandra, Billy, Antonius, Carl) + `Rhino1-Katana`, `Rhino2-Ellen`, `Rhino3-Gene`, `Rhino4-Yoji` |
| 5 | Bird 14 + `Rhino1-Raymond`, `Rhino2-Gene`, `Rhino3-Katana`, `Rhino4-Ellen` |
| 5 | `Rhino2-Katana` **alone** |
| 2 | Bird 14 + `Rhino1-Raymond`, `Rhino2-Katana`, `Rhino3-Ellen` |
| 1 | `Rhino1-Katana`, `Rhino2-Ellen`, `Rhino3-Gene`, `Rhino4-Brandon` |
Every count is a multiple of 6 and they sum to **28** — the disc's stage count,
reached here by a fourth independent route.
🟡 The entry FILENAMES are not recovered. Probing `name_hash` over 8 templates ×
40 indices × 6 languages resolved **0**; the same probe's controls
`<lang>\weapon.tbl` and `<lang>\strings.tbl` resolved **12/12**, so the method
works and the naming convention is simply not one of the eight guessed.
## 🟡 Not settled
* Who *selects* a loadout record. The names encode flight position and pilot,
* Which entry is which stage — see the filename note above. The names encode flight position and pilot,
and [the stage definition table](stage-definition-table.md) has
`AI_TCAF_RhinoFlight` / `AI_TCAF_BirdFlight` — the join is not shown here.
* `ExSET_*`, `S02SET_*` and `NULL_*` are referenced by no loadout in this pak.