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 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.