# The STAR THREE hidden command prompt

2026-09-18. Addresses below are offsets in the unpacked 64 KiB image, excluding
the reconstructed EXE header. This report follows executable references; it does
not decode the DARKER.00–.04 archives.

## Activation and relation to save names

The four strings are **commands**, not displayed menu choices or ordinary save
names. The recovered activation sequence is:

1. On the **“Select a game: 1,2,3,4 or N”** screen, use **Shift+8**, release
   Shift, then press **3 on the number row**. Playtesting found that
   numpad input did not work. The automated DOSBox/X11 capture accepted a
   synthetic keypad-multiply event, so that result is environment-specific
   and should not be treated as reliable player instructions.
2. A separate input state uses the title **“STAR THREE”** and prompt
   **“What do you want?”**.
3. Enter one of the exact phrases below and press Enter. Case, spaces,
   apostrophe and question mark matter. Re-enter `*3` for another command.

**Confirmed in the original packed executable running in DOSBox**, using actual
keyboard events: [hidden prompt screenshot](../analysis/hidden-commands/ui/04-star-three.png),
[typed command screenshot](../analysis/hidden-commands/ui/05-command.png).
After submitting `Who gives true life?`, a debugger memory dump confirms its
patch is installed. All four phrases are additionally checked by executing
their original machine code in an isolated Unicorn harness.

The hidden input and normal new-game name input share their editor at `05D3`
and buffer at `DS:01E0`. They are distinguished by the menu-state byte at
`4540`: **4 means a normal new-game name; 5 means a hidden command**. A control
run entered `Who gives true life?` as a normal name: it was stored in the
synthetic save slot, and the cheat handler was not called. Hidden-command
tests did not modify the synthetic save-slot memory.

## Corrected string boundaries

The string-table reader at `060D–0637` resolves the original ambiguity:

```text
record := byte(text_length + 1), text[text_length], little_endian_handler_word
terminator := 01
```

| Record | Exact phrase | Handler |
| --- | --- | --- |
| `04E1` | `The Jason Brooke special` | `0537` |
| `04FC` | `Lyndon's little snooze` | `053E` |
| `0515` | `Who gives true life?` | `0543` |
| `052C` | `Level X` | `0549` |

**“Level XI” was an ASCII-string extraction artefact.** The last record contains
seven text bytes, `Level X`, then pointer bytes `49 05`. Byte `49` also displays
as `I`; it is not part of the phrase. The following `01` at `0536` terminates
the table. `Level XI` is explicitly rejected by the actual matcher.

## Reference and control-flow trace

These are instruction/table references checked against execution, rather than
every occurrence of the same two bytes anywhere in the binary.

| Address | Role |
| --- | --- |
| `0439`, `0499` | Menu drawing dispatch table; it includes the name/prompt renderer at `0645` |
| `0444–0449` | Gets the current menu record and calls its handler at record offset `+0A` |
| `07D5–07E0` | Menu record = `0451 + 12 * byte[4540]` |
| `045B` | State 0 handler pointer: `0751`, game selection |
| `048B`, `0497` | State 4 and 5 handler pointers: both `05D3`, text editor/submission |
| `0751–078D` | Processes selection input and recognizes the secret preceding-key state |
| `0747–074F` | Selects menu state 5 via `079F`, then marks the input for redrawing |
| `0645–0653` | Alternate prompt renderer chooses `SI=04BC` for the hidden state |
| `04BC–04E0` | Formatting controls plus `STAR THREE` and `What do you want?` |
| `05E3` | Tests `byte[4540] == 5`; branches to hidden submission at `0608` |
| `060D` | **Actual command-table reference:** `mov si,04E1` |
| `0615–0627` | Exact byte comparison against `ES:01E0`, followed by zero-terminator check |
| `0629–0637` | Pushes matched handler address, copies accepted text, then `RET` dispatches to handler |

The four individual text addresses do not need separate immediate references:
the matcher walks records sequentially from `04E1`.

### Why the sequence is asterisk, then three

`0800` obtains a character through the game's scan-code translation at `1534`,
then searches the selection keys `N4321` at `0553`. The reverse ordering means
`3` produces result index 2. Unmatched input records `character + 1` in the
immediate operand at `0786` (`0764–0768`). No-key result `FF` wraps to zero and
does not overwrite this remembered value, so idle frames are allowed.

When a recognized choice arrives, `0785` loads that remembered value into AH.
At `078A` the program compares AX with `2B02`. Therefore:

```text
AH = '*' (2A) + 1 = 2B
AL = selection index for '3' = 02
AX = 2B02 -> jump to 0747 -> hidden state 5
```

There is no elapsed-time test in this path. Another unrecognized printable
character can overwrite the remembered character. The harness confirms `*3`
and `*` + idle polls + `3`; it rejects `3`, `+3`, `*2`, and `*x3` as hidden-mode
entry sequences. This explains the title “STAR THREE” directly.

### Submission details

The editor accepts Enter through its control-character dispatch. State 5
submission returns to state 0 via `0608–060C`, then scans the command table.
The comparisons use `REPE CMPSB`, without case folding. The following byte of
the input buffer must be zero, preventing prefix-plus-extra-text matches.

On a match, the text including its null terminator is copied to the address
held at `E3F4`—initially the English game-selection prompt at `E553`. This is
an in-memory UI text change, not a savegame-name write. `PUSH AX` at `0629`
and `RET` at `0637` implement an indirect handler call through the stack.

## What the handlers do

### The Jason Brooke special

`0537` writes word `CA89` at `7F7B`, replacing:

```asm
; Before
mul cx           ; F7 E1: DX:AX = AX * CX
; After
mov dx,cx        ; 89 CA
```

**Playtest: infinite energy-boost recharges.** The effect survived dying,
loading other saved games, and entering additional commands during the same
running session. This gives the arithmetic patch a concrete gameplay meaning.

The following `shr dx,1` and `xchg ax,dx` remain. For the branch where
`DI > 250`, the intermediate result changes from
`floor(((DI - 250) * CX) / 131072)` to `floor(CX / 2)`, before subsequent
rounding/adjustment. The precise variable names and replenishment timing still
need mapping; the infinite-recharge interpretation is based on the
playtest rather than merely inferred from these instructions.

### Lyndon's little snooze

`053E` shifts byte `B949` right once: its initial `01` becomes `00`. This
changes `mov ax,1` at `B948` into `mov ax,0`, opening the handler at `B938`.

The gameplay dispatch table at `B7FA` maps **scan code `2C` (Z)** to `B938`.
Its reader at `B793–B79F` indexes by `(scan_code - 1) * 2`; the word is at
`B850`. The code's own keyboard map at `15B7` confirms the character.

With the gate open, Z swaps the current object's callback at `SS:[BP+66]`
between its previous value and `B925` (a bare `RET`), and zeroes
`SS:[BP+3E]`. The normal gameplay caller sets BP to `D986`. An isolated test
confirms the first Z installs the no-op callback and the second restores the
old callback.

**Playtest: Z freezes the player ship in space.** Enemy ships continue
moving, and the player can still fire and use external views. This is a
player-update freeze, not a global pause or an enemy-AI freeze. Debugging or
screenshot use is plausible, but developer intent is not established. The exact
phrase is `Lyndon's little snooze`; Jason's phrase enables the boost cheat.

### Who gives true life?

`0543` changes byte `84DE` from `3C` to `B0`:

```asm
; Before: cmp al,0 (leaves AL unchanged)
; After:  mov al,0
```

This zeroes an incoming quantity in the routine beginning at `84D0`, after
another helper has already run. One following path subtracts AL from byte
`810A`, saturating at zero; the patch prevents that decrement. An execution
probe with the resource initially 100 and incoming AL=21 produces **79 normally,
100 with the command enabled**. Call sites at `6EB0`, `6EE2` and `8BD1` place
this in collision/impact-related processing. Damage prevention is a strong
interpretation; universal invulnerability, including all other death paths,
has not been demonstrated.

The later Skimma trace identifies `810A` as shield reserve in the non-Caero
branch: depletion is applied while shields are enabled; with them off, a
separate damage status is set. See [flight controls](flight-controls.md).
This is not a universal health/invulnerability flag.

Playtesting confirmed that scenery crashes are still lethal; enemy-hit immunity
was not established because they did not manage to get hit during testing.

### Level X

`0549` changes byte `B92A` from `72` to `B0`:

```asm
; Before: jb B925  (72 F9), early return when a counter is below four
; After:  mov al,F9 (B0 F9), then fall through
```

The gameplay dispatch table maps **scan code `2D` (X)** to this handler at
`B926` (table word at `B852`). It then copies word `C610` to `C81E` and sets
byte `3E9A` to 1. The latter participates in the end-of-game/level transition
path around `3EEB`; `C81E` is also used by the game's script machinery. This
supports a progression/level-completion shortcut, rather than a literal
request for level ten. The harness verifies that X performs those writes
with the counter at zero only after the command has been enabled. The exact
destination depends on the current game's/script's values.

**Playtest: X immediately advances to the cutscene leading into the next
level.** This resolves the earlier uncertain impression about enemy speed.

The gameplay key dispatcher has additional normal-play/script-state gates
(`B7AB–B7B6`). The probes reproduce the normal-play value `FF` written at
`3D3C`; they do not imply the keys work during every cutscene or other state.

### Entry while flying and persistence

No direct in-flight route to the `*3` prompt has been identified. The proven
entry is in game-selection handler `0751`; flight input uses a different
dispatch path (`B780`). The Z/X actions are intended to run later through that
flight dispatcher, after their phrases have enabled them. Returning to game
selection without restarting the process allows further commands.

These handlers patch executable memory, rather than fields of a single save
record. Playtesting confirmed Jason's patch persists across deaths, loaded games
and additional commands. Persistence across exiting/relaunching DOS is not
claimed, nor has every patch's lifetime been exhaustively traced.

## Reproduction and validation

```sh
python3 tools/unpack_exe.py
# Optional analysis dependency, install in a suitable virtual environment:
python3 -m pip install unicorn==2.1.4
python3 tools/trace_hidden_commands.py
```

The harness accepts only the known extracted-image hash. It executes the
original x86 keyboard translation, selection, editor, matcher, handlers and
gameplay key dispatch. Assertions cover:

- Activation and negative/idle-input controls.
- All four phrases and their exact code writes.
- Case/punctuation/trailing-text failures, including `Level XI`.
- Ordinary save-name input versus hidden-command input.
- The damage/resource subtraction probe and gated Z/X handlers.

The machine-code probes use synthetic empty save slots and eight-pixel font
widths. They bypass mouse routines `1731`, `173C` and floppy housekeeping
`4217`, and feed the keyboard latch instead of emulating the physical IRQ.
They do not emulate the full renderer, DOS, or a complete gameplay session.
Results and substitutions are recorded in
[`verification.json`](../analysis/hidden-commands/verification.json).

### Independent graphical DOSBox confirmation

`tools/capture_hidden_prompt.py` launches a temporary copy of the **original
packed** `X.EXE`, dismisses the startup screens, presses keypad `*` then `3`,
types `Who gives true life?`, and presses Enter. It captures the screens and
then enters the heavy debugger with Alt+Pause to dump memory. The loaded
image is located by its unchanged handler bytes, rather than assuming a fixed
DOS load segment. The captured code at `84DE` is **`B0 00`**, versus original
`3C 00`, and the menu state is back to zero. No code patch was injected by the
capture tool; the game performed the write in response to the typed command.

The evidence is in [`ui/`](../analysis/hidden-commands/ui/), including a compressed
1 MiB memory snapshot and `provenance.json`. This confirms the real activation
and submission path, but is not a full gameplay test of invulnerability or
the other commands' effects.

```sh
# Requires Xvfb, xdotool, ImageMagick import, pexpect, and dosbox-debug.
xvfb-run -a -s '-screen 0 800x600x24 -extension GLX' \
  python3 tools/capture_hidden_prompt.py --dosbox-debug /path/to/dosbox-debug
```

Disabling GLX avoids an Xvfb/NVIDIA EGL crash observed in this environment.
The capture uses SDL's X11 video backend; the earlier SDL dummy-backend
experiments had not reached a usable graphical session. The startup timing
and Escape sequence are tailored to this installation and may need adjusting
for a different emulator configuration.

No original game file was changed. The unpacked image remains the canonical
unmodified extraction; patches occur in running memory. DOSBox mounts only
the temporary installation copy.

Follow-up: [player collision and damage](player-collision-and-damage.md) now verifies the streetlight-specific crash mutation, controlled native geometric sweeps, and the exact limits of the player damage cheat. Earlier open questions on that response path are superseded by these tests.
