# Development leftovers and embedded records

This survey follows strings to code or relocated records in the September 1994 **TFX 2.05** executable. Addresses are file offsets unless labelled as data-object offsets. Function names are research annotations, not recovered source symbols. See [the executable notes](executable-format.md) for the image layout and compiler evidence.

## A developer joke in the terrain loader

**“Jamie has bodged it again”** is a real fatal diagnostic at file `0xf2410`, rather than an unused joke string. The check at [0xb0358](code/index.html#b0358) subtracts the terrain-tag buffer's start pointer from its current cursor and rejects an extent greater than **16 KiB**. Its callers append/read strings and 16-bit words in that buffer. Native checks at extents 0, 16,384 and 16,385 confirm the boundary and exact message; fatal termination is intercepted in the capture.

The original manual credits **Jamie Cansdale** with **World Generator, Flight Model**, making the name consistent with this subsystem. That connection does not establish who wrote every surrounding routine.

The same code retains two terrain-tag paths. [0xb0144](code/index.html#b0144) reads an ASCII source list containing a count, then a path and ten numeric authoring values per 73-byte runtime record. [0xb0604](code/index.html#b0604) can assemble tag names by enumerating `*.sss`, or consume a precompiled `.dat` tag buffer. Ordinary flight launch at `0x727f2` selects the latter through data-object `0xaad4`. Both flight setup and UN Commander reach the world loader, so the alternative path should not be declared wholly unreachable without tracing the editor session. Here `.asc` means this terrain authoring list, not a presumed standard 3D-model interchange format.

## Default high scores: names rather than secret passwords

The executable's table at **`0xf7fbc`** contains ten **16-byte records**: three string pointers and a 32-bit score. [The initialiser](code/index.html#a6944) copies them into ten **67-byte runtime records**, each holding three 21-byte strings and the score at offset 63.

| First name | Surname | Callsign | Score |
| --- | --- | --- | ---: |
| PAUL | HOLLYWOOD | ICE BUN | 100 |
| ANDY | BATE | B8C | 90 |
| DONNA | CHIPPENDALE | LURVE WARRIOR | 80 |
| LYNDA | WHITBY | ULTRA VIXEN | 70 |
| JIM | JENNETT | FUNKY | 60 |
| CHARLIE | CHUCK | 2 COOL | 50 |
| TIM | JOHNSON | BEER | 40 |
| ANDY | GAHAN | PURE | 30 |
| JAMIE | CANSDALE | THE LIZARD | 20 |
| N | PLURA | EVIL | 10 |

Several names match the original credits, including Tim Johnson, Andrew Gahan, Jamie Cansdale and Nevil Plura. The records themselves do not identify every person's role or relationship. Their traced consumer is the high-score initialiser, so these callsigns are **not evidence of hidden enrolment passwords**.

The loader at [0xa6aec](code/index.html#a6aec) reads `tfx.hs` under the directory selected by the `DID` environment variable. The disk payload is 670 encoded bytes followed by a 32-bit checksum. [0xa69b0](code/index.html#a69b0) XORs each byte with the low byte of a reproducibly reset game random sequence; a second draw contributes to an additive checksum of the encoded bytes. [0xa6a10](code/index.html#a6a10) reverses the encoding and calculates the same checksum. Missing files or checksum mismatches restore the embedded defaults. This is obfuscation and an integrity check, not strong protection. Native initialisation and encode/decode roundtrip checks pass without opening or writing a score file.

## Retained interactive branch debugger

The presentation condition handler at [0xb22d8](code/index.html#b22d8) contains an interactive diagnostic path. It draws the condition, its destination and the variable's current value, then waits for:

```text
IF RANK == 7 THEN GOTO MISSION
 SPACE - YES           ENTER - NO
 VARIABLE IS CURRENTLY 8
```

This is an example produced by the original native formatter from synthetic parser records in the capture, not a recovered campaign screen. **Space takes the branch; Enter rejects it**, independently of the condition's actual truth. A GOSUB branch also saves the return node on the graph's return stack.

Normal parser initialisation at [0xb2a68](code/index.html#b2a68) calls [0x70d6c](code/index.html#70d6c), a stub that returns **AL = 1**, and stores it in data-object byte **`0xab41`**. For the ordinary equality condition tested here, that value sends execution directly to [0xb21cc](code/index.html#b21cc), which compares the variable normally. The diagnostic path remains compiled in. Six native cases confirm normal true/false handling, forced yes/no handling, and GOSUB stack updates. Drawing is intercepted and the gate is changed only in emulated memory.

No keyboard shortcut or documented command-line switch enabling this debugger has been identified. It is evidence of retained development machinery, not a newly established gameplay cheat. The original manual credits **David Dixon** with **Game Flow Editor, Instruments, Missions**. A complete authoring editor cannot be inferred just from this runtime debugger: code described as “writing parser file” also serves pilot-save serialisation.

## Personal names and animation fixes

[Parser variable initialisation](code/index.html#b2fc8) allocates 21-byte strings and initialises string-valued variables to **`DAVE`**; numeric variables start at zero. Game flow can replace those values subsequently. This is a default in working code, not a player-name check.

The generic [animation initialiser](code/index.html#ca0c4) also compares argument strings against **`DAVE_FADE`**, **`SLOW_FADE`**, **`MEDIA_BREAK_FIX`** and **`INTROGEN_FIX`**. These select palette/fade or presentation handling; they are **internal arguments, not environment variables or newly recovered DOS configuration keys**. The normal presentation-animation handler passes `DAVE_FADE`, as does another player at `0x7b2f4`. These names show individual fixes surviving in the shared playback API. Associating “DAVE” with David Dixon is plausible given his credited work, but the string alone cannot prove it.

## “Found an Ultra box!” resolved

This is a **fatal sub-flow loading diagnostic**, not an intentionally revealed player easter egg. The string at `0xf27b8` is referenced by [0xb388f](code/index.html#b388f), the **type-14** entry in the sub-flow loader's switch table at `0xb3594`. It calls [the fatal error routine](code/index.html#b0eb0), which formats the message, records fatal state and exits. The [sub-flow loader](code/index.html#b35d0) accepts ordinary return/quit/reset nodes but rejects type 14 before reading its payload. Four native synthetic loads confirm that distinction. “Box” here refers to a node in the graphical game-flow system, not a physical object in the world.

The top-level loader **does** support this node. [0xb3451](code/index.html#b3451) loads a 42-byte payload comprising three numeric conditions and pointers to up to three 17-byte choice-list records. [The runtime handler](code/index.html#b2724) tests conditions in priority order, then uses [0xb2620](code/index.html#b2620) to select a destination from the corresponding list. It records previously selected indices and avoids repeats until the entire list has been used, then resets that history. [0xb25e0](code/index.html#b25e0) converts the selected index and list stride into a destination node. Native cases check first/second/third condition priority, no matching condition, and a complete four-choice cycle; the random-candidate routine is intercepted to exercise retry and sequential fallback reproducibly.

Thus **“Ultra box” is an internal name for a compound conditional-choice node**, with varied non-repeating branch selection. The meaning or origin of “Ultra” itself is not recovered. It could support variation in dialogue or presentation sequences, but that use is an inference from the mechanism. **None of the nine decoded shipped parser graphs contains a type-14 node**, so there is currently no concrete TFX scene that demonstrates it in ordinary play. The restriction against using it in a sub-flow is confirmed; whether this was a deliberate authoring constraint or an unfinished sub-flow implementation remains unknown.

The extractor previously labelled type 14 `menu` from its multi-buffer layout. Native execution shows that there is no menu input in this handler; the research label is corrected to **`ultra_choice`**. This does not alter any decoded shipped scene because those graphs contain no type-14 nodes.

## Other data held in the executable

The executable supplies meaningful data beyond resources loaded from DID.DAT:

- **Player aerodynamics and initial state:** three different native initialisers write 95 captured floating-field locations for the Eurofighter, F-117 and F-22. The [preset comparison](entities/player-presets.csv) retains values; [the flight notes](game-logic.md#player-flight-dynamics) separate these from the external non-player entity profiles. Physical units and every field's meaning remain to be traced.
- **Sample playback records:** 26-byte descriptors supply original sample names, rates and cooldowns. These established the correct PCM interpretation for [the sound exports](audio/README.md#complete-audio-catalogue-and-sampled-effects); the sample bytes alone do not contain all those settings.
- **Interpreter dispatch:** embedded handler tables define model conversion/drawing, scenery events, part animation and presentation loading. These map opcode numbers to actual native functions and expose the boundary between authored data and engine behaviour in [the code browser](code/index.html).
- **Weapon labels and resource names:** the string block around `0xef90c`–`0xefbf4` pairs display labels such as `AAAM`, `AA-ARM`, `CSW` and `AGM 109 H` with model names. These are useful leads for matching weapon artwork and armament logic; their presence alone does not establish that a weapon was cut, playable, or implemented in every mode.

No additional secret mission, aircraft or gameplay easter egg is confirmed by this survey. `WAYEDITOR` belongs to a documented player-facing editor, and the video-recording strings belong to flight recording. The **“Found an Ultra box!”** diagnostic is now traced to the sub-flow restriction above; it provides no evidence of an “Ultra” difficulty or secret game mode. False positives are especially easy when a raw string scan includes padding around the actual referenced NUL-terminated strings.

## Sine tables: the same one-unit asymmetry, at opposite peaks

TFX and Darker both use 1,024 signed sine samples per turn, with cosine taken a
quarter-turn further along the same cycle. Their samples follow
`trunc(32767 × sin(2πi / 1024))`, with one exception in each game:

| Game | Index | Angle | Stored value | Mathematical reference |
| --- | ---: | ---: | ---: | ---: |
| Darker | 256 | 90° | +32766 | +32767 |
| TFX | 768 | 270° | −32766 | −32767 |

All other entries match that truncated formula. Comparing the complete recovered
tables gives exactly two differing entries. Shifting Darker's table by half a
turn and negating it reproduces all 1,024 TFX values, including the exceptional
negative peak. This is a numerical relationship, not evidence of a particular
shared implementation.

A published table or common generation routine circulating among developers is
one possible explanation. Slight differences in floating-point sine generation,
angle accumulation or conversion near an extremum could also produce a one-unit
shortfall when a result just below an integer is truncated. **The origin is
unknown:** no specific publication, shared source file or generation program has
been identified. The matching pattern alone cannot distinguish those possibilities.

The anomaly is tiny: one integer unit is about 0.00305% of unit amplitude on the
32,767 scale. Native Q15 multiplication uses 32,768 as its divisor, so TFX's
largest sample error against ideal unit sine is 2/32,768, or about 0.00610%, at
270°. The much more visible limitation at modern resolutions is the angular
spacing: each table step is 0.3515625°. Near the centre of a 3,840-pixel-wide,
56° horizontal view, that is roughly a 22-pixel displacement.

The faithful reconstructions retain the respective exceptional samples. Redux's
continuous display transforms evaluate sine and cosine without the original
1,024-phase rounding; simulation/reference arithmetic remains separately checked.
See the [Redux precision notes](https://github.com/Lost-Engines/tfx-redux/blob/master/docs/rendering-precision.md)
for the rendering changes and benchmarks.

Sources: [Darker's exported table](https://github.com/Lost-Engines/darker-reverse/blob/master/analysis/tables/sine.csv),
[Darker's findings](https://github.com/Lost-Engines/darker-reverse/blob/master/docs/executable-unpacking.md#trigonometry-with-a-one-unit-asymmetry),
and [TFX's reconstructed native table](https://github.com/Lost-Engines/tfx-cpp/blob/master/src/math/native.cpp).
This comparison uses those recovered tables and mathematical sine; it is not a
new claim about the historical toolchain that generated them.

## Evidence and reproduction

[check_development.py](../tools/check_development.py) executes the original routines in an isolated relocated LE image, with flat segment selectors. It checks all ten default records, their encode/decode roundtrip, six branch-handler cases, three terrain-buffer boundaries, four synthetic sub-flow loads and five Ultra-choice cases. [development-checks.json](development-checks.json) retains the exact results and executable hash. Keyboard events, drawing, fatal termination and synthetic sub-flow I/O/allocation are intercepted; Ultra random candidates are fixed for the no-repeat checks; no installation or save file is changed. The terrain source path and animation argument uses above are static code traces, not claims that their complete authoring tools were executed.

```sh
python3 tools/check_development.py
```

The credit assignments come from page 98 of the [original manual scan](../literature/TFX%20Tactical%20Fighter%20Experiment%20Manual%20(Ocean)(1994)_text.pdf), rather than guesses based on names embedded in the executable.
