re: phase membership is in the Route record names; the ~300 craft are ~150

Route_S<NN>.tbl names every route Route_<squadron>_p<N><kind> -- 120/120 for
S02 -- so the squadron-to-phase map was on the disc all along, in a table read
until now only for fly-in geometry. 108/111 S02 squadrons map; the 3 misses are
typos in the route table and all are phase 2.

That resolves the 387-vs-300 gap after four failed attempts, by refuting its
premise: there were never 300 craft. Phase 1's member-level n multiset
{1x25, 2x1, 4x4, 9x12} matches the measured craft-per-record fan-in
{2x24, 4x1, 8x4, 18x12} bucket for bucket at exactly 2x, so 300 = 2*(151-1),
the -1 being the documented 41-vs-42 off-by-one.

The 2x is the probe double-counting, not real units: a 2x reading needs 16
Delta Sabers for 8 named pilots, and breaks the formation capacity bound in 20
of 37 phase-1 squadrons (16 of them on Formation_1_only, one slot) where the 1x
reading has 0 violations. All three measured craft totals being even is a
further tell.

Refuted: UnitGroup has no phase/spawn/delay field (1019 = sum(Count)*4 + 5*111,
every slot accounted for); DisableInterval is No for all 111 S02 squadrons;
stage\EnumSquadron_Test.tbl does not exist.

Confirms tag_hash independently: UnitGroup record key == tag_hash(squadron id),
1160/1160.

Still open: what advances a phase -- no static table encodes a trigger.
This commit is contained in:
Sylpheed RE agent
2026-08-25 10:45:24 +00:00
parent 508db8e99f
commit afc33ea109

View File

@@ -0,0 +1,135 @@
# Which squadrons fly in which phase — and the ~300 craft are ~150
Status: ✅ the phase map, read out of `Route_S<NN>.tbl` record names;
✅ the 387-vs-300 gap explained — **the live-craft probe double-counts**;
❔ what *advances* a phase (nothing static encodes it).
## ✅ The phase map is in the route names
`stage\Route_S02.tbl` has **121 records: 120 routes + 1 roster**, and every route
name matches `Route_<squadron>_p<N><kind>`**120/120**:
```
Route_ADN101_p1F Route_TCN003_p2S Route_ADS351_p3M
```
The phase lives **in the name and nowhere else**; a route record's only named
field is `FrameCount`. So the squadron→phase mapping was on the disc all along,
one string-parse away, in a table that was being read for fly-in geometry.
**108 of 111** S02 squadrons match a route name exactly. The three that do not —
`TCN207`, `TCN208`, `TCS252` — are **typos in the route table** (`Route_TCT207_p2S`,
`Route_TCT208_p2S`, `Route_TCN252_p2F`), plus two orphan routes naming no
squadron (`Route_ADS352_p3F`, `Route_kichi_p3F`). All three near-misses are
**phase 2**, so phase 1 is unaffected.
Phase partition of Stage 02 (Σ`n` = 387 overall):
| phase set | squadrons | Σ`n` |
|---|---|---|
| {1} | 33 | 142 |
| {2} | 31 | 110 |
| {3} | 39 | 118 |
| {1,3} | 2 | 5 |
| {2,3} | 1 | 1 |
| {1,2,3} | 2 | 4 |
| none (the 3 typos) | 3 | 7 |
| **per phase** | 37 / 34 / 44 | **151 / 115 / 128** |
## ✅ The 387-vs-~300 gap: the probe counts each craft TWICE
[roster-to-craft-link](roster-to-craft-link.md) records four failed attempts to
explain how the roster becomes "~300 live craft". The premise was wrong — **there
were never 300 craft.**
Phase 1's **member-level** `n` multiset against the measured craft-per-record
fan-in (41 records, 300 craft):
```
phase-1 members (42): n=1 x25 n=2 x1 n=4 x4 n=9 x12 sum 151
observed craft/record: 2 x24 4 x1 8 x4 18 x12 sum 300
observed / 2: 1 x24 2 x1 4 x4 9 x12 sum 150
```
Every bucket matches shape for shape. The only discrepancy is 24 vs 25 records
at the bottom — **the already-documented 41-vs-42 off-by-one, and it is an `n=1`
record.** So `300 = 2 × (151 1)`. Unit type corroborates independently: the 12
records showing 18 craft are all `UN_e007_ADAN_Turret`, and phase 1 has exactly
12 turret squadrons at `n=9`.
### ✅ The factor of 2 is an artifact of the probe, not real units
Two static arguments, and the second is decisive because it is a hard capacity
bound:
1. **Named pilots.** Phase 1's eight `f001` members all have `n=1` and carry
distinct identities — `Character_Player_Test, ELLEN, RAYMOND, GENE, SANDRA,
BILLY, ANTONIUS, CARL`. A 2× reading means 16 Delta Sabers for 8 named people.
2. **Formation slots.** Squadrons cannot exceed their formation's `FrameCount`
(see [unit-group-table](structures/unit-group-table.md)):
| reading | violations among the 37 phase-1 squadrons |
|---|---|
| `Σn ≤ FrameCount` (1×) | **0** |
| `2·Σn ≤ FrameCount` (2×) | **20** |
Including 16 squadrons on `Formation_1_only` — one slot, `n=1` — which a 2×
reading would have placing two craft in a one-slot formation.
So the true phase-1 population is **~150**, and the 296 / 298 / 300 spread is
2 × a 148 / 149 / 150 population after kills. That all three measurements are
**even** is a further tell a 1:1 count would not produce half the time.
**Best explanation of the missing 42nd record:** the player's own tuple
(`TCN001` member 0, `Character_Player_Test`), which plausibly is not in the
AI-craft pool the `+0x130` def-pointer scan walks. That makes the chain exact:
`300 = 2 × (151 1 player)`.
⚠️ **This is a static argument about a dynamic measurement.** It says the probe's
number cannot mean what it was taken to mean; it does **not** identify *what* the
probe is double-counting. That needs a run — the counting rule in the craft scan
is the place to look, not the game.
## 🔴 Refuted along the way
* **`UnitGroup` carries no phase, spawn time or arrival delay.** The raw field
dump accounts for every slot: `1019 = sum(Count)·4 + 5·111`, with positional
entries tagged by sequential index (`0x0,0x1,0x2,…`), not hashes. There is no
spare field.
* **`DisableInterval` cannot explain Stage 02** — it is `No` for all 111
squadrons. Corpus-wide its 31 `Yes` records sit in just two stages, S04 (5) and
S14 (26), all on `GNN***` squadrons.
* **`stage\EnumSquadron_Test.tbl` does not exist** (`0x213f4a7e` is not in the
TOC). It was listed as a candidate for the arrival-interval values; it is dead.
* `AIParams_S02.tbl` is keyed by AI profile, not squadron, and carries only
combat tuning. `SUBObjectiveSettings_S02.tbl` is keyed `SUBOBJ_005..014` with
only points/unlock/HUD strings — no squadron, phase or trigger.
## ✅ Bonus: the `UnitGroup` record key, confirmed corpus-wide
A squadron record's key is `tag_hash(squadron_id)` — **1160/1160 across all 28
stages** (`ADN101``0x659aff47`). Same hash as
[idxd-tag-hash](structures/idxd-tag-hash.md); this is an independent
confirmation of it on a second kind of table.
## ❔ Still open: what advances a phase
Nothing static encodes a trigger. Swept the stage record and every table it
names — `Route`, `AIParams`, `SUBObjectiveSettings`, `FormationSet`, `nameplate`,
`EnumUnit`, `EnumCharacter`, `EnumLocalString`, `EnumWeapon` — plus the
`message\` family, for field names matching
`interval|time|phase|delay|wave|spawn|arrival|trigger|start|appear|event|condition`.
The only hits anywhere are `FrameCount` and `PresetMessage_Phase1/2/3` in
`message\UnitMessageSet_S02.tbl`. The trigger is almost certainly in the
executable, not the data.
## Falsifiable predictions for the next run
* Per-record craft counts, **in probe units (2×)**: 4 records at 8 =
`ADS151, ADT102, ADT107, ADT113` (all `UN_e010_ADAN_Attacker_S`); 1 record at
4 = `TCN105` (`UN_f106_TCAF_Destroyer`); 24 records at 2 = the remaining
phase-1 `n=1` members.
* A phase advance should move the deployed set toward phase 2: 34 squadrons,
36 members, Σ`n` 115 (≈230 in probe units).
* `TCN207`, `TCN208` and `TCS252` may **fail to arrive** in phase 2, because
their routes are misnamed.