This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docs/re/mission-objectives-text.md
Sylpheed RE agent 34c99a1568 re: decode the IXUD localised text -- 534 entries, six languages
534 IXUD entries across 36 paks, 94 distinct keys, 92 resolved by name. Content
identified: mission objective/lose/hint panels, 91 bonus-objective banners,
scripted radio, cutscene dialogue, the reactive combat-chatter pool (MSG_ADAN
23,236 fields, MSG_RHIN 21,196, ...), resupply barks, speaker labels and the
hangar weapon Name/Desc/Condition.

Verified independently: language\MissionDialog_local_string.tbl decodes to 600
fields with the trailer identity holding, giving Stage 02's real objectives --
phase 1 'Shoot down all invading enemy fighters / while watching out for attacks
/ on the ACROPOLIS', phase 2 'Protect the Admiral's ship the CALIBAN', phase 3
'Destroy the interstellar cruise missiles'. That matches the script exactly: the
phase-1 condition polls three enemy squadrons and the escort's loss is the fail
branch, and phase 2 is positional, which is why no kill count appears there.

The .ssb symbol names (S02_P1_OBJECTIVE etc.) are NOT IXUD keys -- they are
records in an IDXD map, message\MissionDialogMessage.tbl, whose positional
fields list the lowercase per-line IXUD names; *_GRAPH holds a texture instead.

Structure: one record per object (except the six 63-record hangar files),
624,440 named fields, 55% of them empty line slots, no control characters, the
only escape a literal two-char \n in block-text tables, and records/fields in
ascending key order so lookup is a binary search. '[OB]' turns out to be a HUD
marker label in this text -- the same one the REMAINING OB work chased.

Six languages confirmed D/E/F/I/J/S; J omits the trailing empty line slot in 78
of 86 objects. Two keys remain unresolved, byte-identical across all six paks
(untranslated Japanese voice transcripts).

Also corrects mission-objectives-text.md: SUBOBJ_009 does have text, and
SUBOBJ_005 is two fields.
2026-08-25 21:01:55 +00:00

6.4 KiB
Raw Permalink Blame History

✅ CORRECTED 2026-08-25 by decoding the IXUD containers directly — see structures/ixud-localised-text. 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:

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.