StageMessageSet_S02.tbl is resolved. stage-mission-tables.md had recorded it as absent from the pak; it is present, and the archive prefix is message\ rather than stage\ like its siblings. Sweeping prefix candidates over the full 16630 entry TOC found it immediately. It holds a voice mapping, a unit message set pointer, and a list of 31 message tables including ScriptMessage_S02_msg.tbl and the per-character PresetMessage sets. message\UnitMessageSet_S02.tbl then gives an independent confirmation of the phase structure. Its 26 records have exactly four named fields: CrewCount and PresetMessage_Phase1, Phase2 and Phase3. Every message set carries a different preset table per phase, so phases now appear in three unrelated table families -- the stage record, the route names, and the message sets. They are not a quirk of one file. The promising lead did not survive. ScriptMessage_S02_msg.tbl has 149 records whose third positional field takes values like Killed and None, which looked like a trigger. Enumerated across S01 and S02 it is a small closed vocabulary of None, Emergency, Killed and Noise -- delivery categories for radio chatter, meaning how a line is played rather than mission control flow -- and the fourth field is 1 in every record, so it is not an argument either. Rejected. That leaves no table anywhere carrying a phase-advance condition. Everything found is a consequence of the phase and never its cause, which points at the advance logic living in code. The only place left is the executable, and default.xex is encrypted on disc, so the decrypted image exists only in guest RAM and reaching it needs a run plus function-level work. Recorded as the honest end of the static search rather than continuing to guess at table names.
5.4 KiB
Enemies come into play per PHASE, deployed at phase start
Status: 🟡 strongly supported and internally consistent, one unexplained off-by-one; ❔ what advances a phase is now the single open question.
This is the answer the wave line of work has been converging on, and it is not the one the route timetable first suggested.
The evidence
Static, from Route_S02.tbl cross-referenced with UnitGroup_S02.tbl:
| phase | squadrons with routes | members |
|---|---|---|
| 1 | 37 | 42 |
| 2 | 34 | 36 |
| 3 | 44 | 49 |
| no route | 3 | 3 |
(Squadrons appear in more than one phase — 37+34+44 = 115 against 111 squadrons — so the member totals overlap and do not sum to 116.)
Dynamic, measured repeatedly across many runs:
deployed = 41 of 116 records, from the first observable instant, never changing
41 deployed against 42 phase-1 members. The deployed set is the phase-1 roster, to within one record.
What this makes coherent
Every previously puzzling observation falls into place:
- All 116 records exist at mission load — confirmed on two stages — but only the current phase's squadrons hold craft.
deployedis 41 before the ready room ends and never moves, because phase 1 deploys as a unit at load rather than on a schedule.- No arrival was ever observed in up to 435 s of verified-live flight with 42 kills, because phase 1 never completed in any run — and phases 2 and 3 are where the other 85 members are.
- The route times are within-phase fly-in timings, not release times, which fits the frames reading (Stage 01 phase 2's t = 1500/1800/2100 → 50/60/70 s at 30 Hz).
So: enemies come into play per phase, deployed together at phase start. The route entry gives each squadron its entrance path and the moment it flies in.
The off-by-one is not explained
41 observed against 42 expected. Candidates, none tested: the player's own record may be counted differently; one squadron may hold craft in a way the liveness read misses; or one phase-1 member may genuinely not deploy. It is recorded rather than rounded away — a one-record gap is exactly the size of the errors that have misled this corpus before.
❔ The single open question: what advances a phase
This is now the whole remaining question, and it is the same one raised many
iterations ago in
structures/stage-mission-tables.md — the
stage record declares Phase_1..3 but nothing found says what ends one.
What is now known that was not then:
- a phase advance is directly observable —
deployedwould jump from 41 toward the phase-2 roster, which is unmissable with the current probe; - it did not happen in any run, including 435 s of verified-live flight with 42 craft destroyed, so it is not a short timer and not a small kill count;
- the likely gate is an objective, and
SUBObjectiveSettings_S02.tblnames nine of them but carries only rewards and HUD strings — no trigger.
Places not yet looked: StageMessageSet_S02.tbl (never resolved in
GP_MAIN_GAME_E.pak), and the executable, whose decrypted image is only
available in guest RAM.
Hunting the phase trigger in the message tables (2026-08-24)
✅ StageMessageSet_S<NN>.tbl resolved — the prefix is message\
structures/stage-mission-tables.md recorded
this table as ❔, "not in GP_MAIN_GAME_E.pak under that name". It is there; the
archive prefix is message\, not stage\ like its siblings. Sweeping the
prefix candidates over the full 16 630-entry TOC found it immediately.
It holds three records — VoiceID2SndID, UnitMessageSetTable, and a Files
list of 31 message tables: ScriptMessage_S02_msg.tbl,
ScriptMessage_S02guide_msg.tbl, DemoMessage_S02_msg.tbl, and per-character
PresetMessage_* sets.
✅ Phases are a first-class runtime concept, confirmed independently
message\UnitMessageSet_S02.tbl (26 records) has exactly four named fields:
CrewCount, PresetMessage_Phase1, PresetMessage_Phase2, PresetMessage_Phase3
Every message set carries a different preset message table per phase. That is
a third, independent table family organised around Phase_1..3, after the stage
record and the route names. Phases are not a quirk of one file.
🔴 Refuted: the script-message trigger field is not a phase trigger
ScriptMessage_S02_msg.tbl has 149 records whose third positional field looked
promising — values like Killed alongside None. Enumerated across the corpus
it is a small closed vocabulary:
| value | S02 | S01 |
|---|---|---|
None |
105 | 72 |
Emergency |
33 | 5 |
Killed |
5 | 2 |
Noise |
5 | 8 |
These are delivery categories for radio chatter — how a line is played
(urgent, over static, on a death) — not mission control flow. The fourth field is
1 in every single record, so it is not an argument either. Rejected.
❔ No table carries a phase-advance condition
Phases now appear in the stage record, in route names, and in message sets, and not one of those files says what ends a phase. Everything found is a consequence of the phase, never its cause.
That points at the advance logic living in code rather than data. The only place
left is the executable, and default.xex is encrypted on disc — the decrypted
image exists only in guest RAM, which means a run plus function-level work.
Recorded as the honest end of the static search rather than continuing to guess at table names.