DARKER Research archive

Mission text sections and script conditions

The scenario viewer now separates formatted briefing/presentation pages from counted in-flight/scripted messages. Each page and message retains its resource offset. Where a sequential association can be established under explicit assumptions, message entries show the script offset, preceding checkpoints/waits/delays, display placement, display lifetime and delay before script continuation.

message-sections.json exports the associations for all three languages: 372 language sections, 226 with a sequential association under the stated assumptions, covering 1,167 nonempty messages. Sections without messages are included in the section count. Complex cases show stored text and candidate script operations separately rather than inventing an order.

First mission example: 04_000 / 0

The four English formatted pages contain introductory quotations, the shuttle-station welcome and the briefing. Their exact presentation transitions have not been mapped by this pass. They are separate from the counted-message suffix.

Script offset Action
002D Establish checkpoint
002E Wait for objective-cell-list exhaustion and remaining objective counter zero
002F Delay 10 × 50 = 500 clock ticks, approximately one second
0031 Consume the empty entry at English offset 04B1; draw nothing and skip timing operands
0034 Consume the entry at 04B2: “Well done- you can return to base.”
0037 Stop this object script after the preceding scheduling delay

The scenario has two initially active counted-object templates, indices 1 and 2 (definition slot 19), and an empty objective-cell list. Thus the wait is governed by the remaining objective counter in this setup. The script does not test the displayed message text or a separate generic “mission complete” Boolean.

The return message is centred and has lifetime 40 × 50 = 2,000 ticks, approximately four seconds. The instruction schedules continuation after 42 × 50 = 2,100 ticks, approximately 4.2 seconds. These timers run in parallel, not four seconds plus another 4.2 seconds. Display expiry starts at the current clock; continuation advances the existing script deadline, so a late update can shorten the remaining continuation delay. See the native scheduler trace. Timing in seconds uses the approximately 500 Hz game clock; the original tick quantities remain exported.

Native consumers

Opcodes 0C, 0D and 0E enter C403, C3F9 and C3FE respectively, selecting centre (B132), left (B125) or right (B147) display placement. All use C406 and the shared sequential text cursor in the instruction immediate at C059. The operands are a display-duration byte followed by a script-delay byte; neither is a string ID.

For a nonempty entry, the placement helper consumes the width byte and stores a pointer to the counted string. C406 then reads the length, advances C059 past the glyph bytes, notifies through B906 and enters the usual delay path at C454. Each duration byte is multiplied by the shared header's time multiplier.

For a zero-width entry, C059 advances one byte, nothing is displayed and the delay operand is skipped. If current object flag +07 bit 20h is set, the instruction skips both operands without advancing the text cursor. Consequently matching message operations to strings purely by count can be wrong in a suppressed execution.

C213/C84E implements the objective wait: the current objective-list byte must be FF and counter C16F must be zero. Otherwise it enters checkpoint retry at C1E1.

DA2F–DA43 feeds formatted pages through B292 and stores the returned pointer in C059. This connects the formatted-page stream to the later counted-message stream, but is not by itself a reconstruction of all presentation transitions.

Association limits

The exporter follows the player's script root (or the presentation root), retaining ordered prerequisites between message operations. It links entries only when the main path accounts for all message operations, the stored-entry count matches, and no detected loop, cursor branch/context swap, conditional repeat, presentation transition, supplementary record or language decoding error makes that association unsafe. It assumes the cursor has reached the counted-message suffix and no message suppression or external consumer intervenes.

Object/world flag waits and other incompletely named conditions retain their raw operands and original operation names. Initially counted object indices are context, not a complete list of all future objectives: reserves and script counter adjustments can change that state. The conditions are a static path description, not a reconstructed live scheduler trace or an assertion that every formatted page is shown at mission start.

Verification executes the original handlers for 12 combinations of placement, empty/nonempty entry and suppression, checking cursor movement, text pointers, expiry and delay. Four original objective-wait cases cover exhaustion/counter combinations. Sound notification is substituted and scheduler/retry entry points intercepted. The first mission's exported association is checked separately. All 124 scenario views were exercised in Chromium without script errors.

python3 tools/mission_message_sections.py
PYTHONPATH=/tmp/darker-python python3 tools/verify_mission_messages.py
python3 tools/mission_browser.py