> ✅ **CORRECTED 2026-08-25** by decoding the IXUD containers directly — see > [structures/ixud-localised-text](structures/ixud-localised-text.md). > Two errors here: `SUBOBJ_009` **does** have text (`'You destroyed all enemy > units!'` — all 91 of 91 sub-objectives have an `_Mes_L1` string), and > `SUBOBJ_005` is **two** fields (`'You rescued'` + `'the ally destroyer!'`), > which a single-line rendering drops. # The mission script in plain English — and why phase 1 never completed Status: ✅ the localised string tables are decoded and readable; ✅ the phase structure is confirmed narratively *and* by roster composition; 🟡 a concrete, testable reason the phase never advanced in any run. ## ✅ `IXUD` — the localised string container `language\*_local_string.tbl` (the prefix is `language\`, a third convention after `stage\` and `message\`) is **not** IDXD. Magic is `IXUD`, and its strings are **UTF-16 big-endian**. That is why every earlier ASCII-oriented dump of these files produced garbage. Reading them is immediate once the encoding is known, and it makes the mission design directly legible instead of inferred. ## ✅ Stage 02's nine sub-objectives, in words | id | text | |---|---| | `SUBOBJ_005` | You rescued the ally destroyer! | | `SUBOBJ_006` | You destroyed all enemy fighters! | | `SUBOBJ_007` | You sunk all enemy warships! | | `SUBOBJ_008` | You rescued the ally cruiser, Amalthea! | | `SUBOBJ_010` | The ally cruiser CALIBAN took no damage! | | `SUBOBJ_011` | You sunk the enemy destroyer targeting the ACROPOLIS! | | `SUBOBJ_013` | You destroyed all enemy cruise missiles! | | `SUBOBJ_014` | You destroyed all enemy missiles and units! | (`SUBOBJ_009` has no text.) 91 objectives are defined across the game. ## ✅ The three phases, confirmed twice over The guide script reads as three distinct acts, and each matches the per-phase roster composition found independently in [mission-phase-deployment.md](mission-phase-deployment.md): | phase | script | roster | |---|---|---| | 1 | *"The attackers with the orange markers, right?"*, *"Protect the ACROPOLIS!"* | turrets, attackers, fighters | | 2 | *"destroy the ship's engine"*, *"destroy that ship's weapons"*, *"take out the enemy's shield projector"* | destroyers, frigates, cruisers | | 3 | *"start by taking out that missile"*, *"Concentrate on destroying the missiles one by one"* | **`UN_e201_ADAN_ISCMissile` ×9** | Phase 3's nine cruise missiles against `SUBOBJ_013` *"You destroyed all enemy cruise missiles!"* is an exact match between two files decoded on different days by different routes. ## 🟡 Why phase 1 never advanced: the pilot killed the wrong things The phase-1 objective is stated outright — **destroy the marked attackers**: > *"Rhinos, prepare for combat. Are you all clear on your targets?"* > *"The attackers with the orange markers, right? Roger that!"* > *"Katana, those attackers are our targets!"* Those are `UN_e010_ADAN_Attacker_S`, of which phase 1 fields four squadrons. **The hunting pilot targeted turrets almost exclusively.** Every loss line in the run logs reads `UN_e007_ADAN_Turret`, with `UN_e010_ADAN_Attacker_S` appearing only twice across all runs — unsurprising, since `SYLPH_HUNT` was built to make turrets targets and `SYLPH_KEEPOUT` was tuned for them. So 42 kills were overwhelmingly the *wrong* 42. That gives a mundane explanation for the whole run of null results, and it does not require the frames reading or event-gating to be settled first. **Prediction:** destroying the phase-1 `UN_e010_ADAN_Attacker_S` squadrons should advance the phase, which is directly observable as `deployed` jumping from 41 toward the phase-2 roster. **Test:** a pilot that prioritises `e010` over `e007` — a target-preference knob, not new decoding — and the existing probe watching `deployed`. This is 🟡, not ✅: the objective text is certain, but that *this particular objective* gates the phase advance is inference from the script's structure. --- # The target-preference knob works, and the blocker is now combat, not RE (2026-08-24) ## ✅ `SYLPH_PREFER` added and measured `pilot.py` gained a target-preference knob: a unit-name substring whose matches get their target score multiplied by 0.05 and everything else by 4.0. With `SYLPH_PREFER=e010`, one clean 320 s run (witness: **0 stalls**): | killed | count | |---|---| | `UN_e007_ADAN_Turret` | 8 | | `UN_e010_ADAN_Attacker_S` | **2** | The preference is real — `e010` kills went from about one *across all previous runs* to two in a single run — but it is **weak**: turrets still outnumber attackers 4:1 in the kill log. Target commitment (`COMMIT_MAX`, `COMMIT_DROP`) and simple proximity keep pulling the nose back to turrets, which are far more numerous. `deployed` stayed at **41** throughout. No phase advance. ## 🚧 The blocker, quantified Phase 1's roster, by craft rather than by squadron: | unit | members | craft (`sum(n)`) | |---|---|---| | `UN_e007_ADAN_Turret` | 12 | **108** | | `UN_e106_ADAN_Destroyer` | 7 | 7 | | `UN_f001_TCAF_DeltaSaber_T` | 7 | 7 | | **`UN_e010_ADAN_Attacker_S`** | **4** | **16** | Clearing the marked attackers means destroying **16 craft**. At the measured rate of 2 per 320 s that is **~2560 s — roughly 43 minutes** of continuous verified-live flight, across many chained attaches, with a freeze rate of about two runs in five. **This is no longer a reverse-engineering problem.** Everything needed to observe the phase advance is built and validated: the roster link, the liveness read, the stall witness, chained attaches, the discard rule. What is missing is a pilot good enough to actually complete the mission objective, and that is game-playing work with an uncertain payoff. ## The choice, which is the user's to make 1. **Invest in the pilot** — better target selection, missiles, using the marker/lock the script keeps referring to. Uncertain, potentially several iterations, and drifts away from RE. 2. **Accept the static answer.** The phase structure, per-phase rosters, route paths and objective texts are all decoded and cross-confirmed. Only the *trigger* is inferred rather than observed, and it is inferred from the game's own guide script naming the objective outright. 3. **One very long run** — 40+ minutes of chained attaches — betting against the freeze rate. Recorded rather than chosen, because it is a question about how much effort this one confirmation is worth, not a technical unknown.