# Gameplay and engine investigation

The flight engine is substantially mapped: its update loop, all **61 object-handler
entries**, thirteen eight-quality tuning tables, aircraft force calculation,
weapons, damage, enemy state machines and objective checks are identified.
The campaign front end also supplies an exact scoring formula and different
promotion rules for the normal game and Other Worlds.

- [Flight dynamics, controls, walking and ejection](flight-dynamics.md)
- [Weapons, collisions and enemy behaviour](enemy-behaviour.md)
- [Objectives, campaign persistence, scoring, ranks and endings](mission-rules.md)
- [World-by-world objective inventory](gameplay/theatres.md): 25 original world
  variants and 339 stored objective anchors, with coordinates and qualities.
- [Native tables](gameplay/tables.json), [flight/gameplay disassembly](gameplay/disassembly.txt),
  [campaign disassembly](gameplay/campaign-disassembly.txt) and
  [verification results](gameplay/native-checks.json).

## Evidence and scope

Unless stated otherwise, addresses are **file offsets in
`installs/deluxe_dnk/3.EXE`**, the normal-game 3.42 flight engine. `DS:xxxx`
means a data-segment offset, not an executable file offset. The data segment is
`1129h` relative to the loaded module; its file base is `11490h`. Normal near-code
pointers become file offsets by adding the 512-byte MZ header. Campaign helpers
have different headers and segments, recorded separately.

The explanations below distinguish traced code, execution of isolated original
routines, and claims from the supplied manuals. Descriptive variable names are
research labels, not recovered assembler symbols. `MBUILDER.DOC` actually does
preserve original symbols and tables; those are identified as such.

**520 controlled native cases pass**, with eight additional recorded flight-force
scenarios. These cover collision boundaries, damage, all quality selectors,
aircraft position scaling, weapon restrictions, saucer states, all eight orb
objectives, scoring, medal boundaries in both editions, promotion differences, and experimental-aircraft throttle permission.
The force scenarios retain original vector transforms, trigonometry and arithmetic;
only HUD and sound calls are stubbed. These checks do not amount to a full-game
emulator or an exhaustive campaign playthrough.

The newer flight engine's addresses must not be applied to the older engines.
The pristine-world catalogue uses the 3.42 rules to describe their object fields;
it does not establish that every older executable behaves identically.

## Runtime organisation

The top-level frame loop begins at `280c`. Much of the player's physics is inline
in this loop rather than behind one convenient flight-update function.

| Phase | Principal code | Work |
| --- | --- | --- |
| Frame timing and pause/help | `280c–2a1c` | Read timer, clamp elapsed step, apply held T, handle pause/help |
| View and scenery setup | `2a1c–2cc7` | Camera transforms, player geometry, ground/sky, stars and sun |
| Distant-object pass | `7ef2`, called at `2cc7` | Inspect distant records and promote objects becoming near enough |
| Prepare local census | `ba36`, called at `2e26` | Preserve/reset defence and objective counters, update effect state |
| Particle and moving-object integration | `0b17`, `a187` | Lifetimes, velocity, gravity, drag and position |
| Active world pass | `7c8c`, called at `2e42` | Object handlers, collisions, drawing, walking surfaces and hazards |
| Portal/autopilot relocation and streaming | `217b`, `0e5c`, `7dc8`, `8362` | Relocate player; load/offload scenery |
| Aircraft rotation and forces | `31a7–3c0c` | Control response, damage biases, stall limiter, thrust, drag and lift |
| Ground contact and movement | `3c0c–3fbc` | Landing, aircraft position, walking, jumping, parachute and remote aircraft |
| Effects, instruments and input | remainder through `4c5a` | Weapon recharge/fire, booster, views, ejection, status and exit |
| Finish sortie | `4c5a–4de6` | Serialize state/results, update world and present outcome |

Rendering and simulation are interleaved. Distance sorting, collision eligibility
and scenery streaming affect which handlers run. A faithful reconstruction cannot
simply draw all objects and update every distant enemy indefinitely.

## Object storage and dispatch

A live object occupies **74 bytes**. Important recovered fields:

| Byte offset | Representation | Meaning |
| --- | --- | --- |
| `00,04,08` | signed 32-bit | World position X/Y/Z |
| `0c,0e,10` | 16-bit turns | Orientation |
| `12` | byte | Distance tier; `ff` when detached from lists |
| `13` | byte | Collision group/instance tag; also overloaded by effects |
| `14` | 32-bit | Squared distance key; scale depends on tier |
| `18` | word | Live flags, quality and type-specific state |
| `1a` | byte | Rotation/detail-related selector, used by generic integration |
| `1b` | byte | Hit points for damageable scenery/enemies |
| `1c,20,24` | three 32-bit values | Squared distance thresholds used by drawing/object logic |
| `28,2a,2c` | three near data pointers | Near/middle/far model records |
| `2e,30,32` | signed words | Velocity components |
| `34` | word | Lifetime/countdown, age or other type-specific timer |
| `36,38,3a` | signed words | Generic angular increments |
| `3c,3e` | words | Random motion/drag inputs for generic integration |
| `40,41` | bytes | Gravity and effect/type-specific flags |
| `42,44,46` | words | Collision half-extents |
| `48` | word | Object type |

The compact world record's four raw parameters expand into the three velocities
and timer (`7f85–8056`). Model pointers are data pointers, not executable callbacks.

The separate code-pointer table is at **DS:`2c50`**, indexed by `type * 2`.
A handler entered with **carry clear** performs ordinary updates; **carry set**
notifies a collision. For player/aircraft contact, `DI=ffff` is a sentinel rather
than another object pointer. Several handlers give this sentinel special treatment.
The extended type-properties table at **DS:`2d44`** governs walking, runway,
forcefield, capture and other contact rules. It is distinct from live flags.

Live flag meanings are context-dependent, but the common uses include:

| Mask | Common use |
| --- | --- |
| `0001` | Object allocated/present |
| `0006` | State bits, including saucer movement states |
| `0008` | Receive object collision callbacks |
| `0010` | Run per-frame handler |
| `0020` | Participate in player contact checks |
| `0040` | Six-hit attacking object |
| `0080` | Twenty-five-hit attacking object |
| `0100` | Select box-collision path; also damaged-aircraft state |
| `0200` | Objective complete, for applicable types |
| `0800` | Type-specific special option |
| `7000` | Quality index 0–7; builder displays 1–8 |
| `8000` | Newly allocated record awaiting list insertion |

A flag cannot be renamed globally from one example: crew use `1000` for their
shot pose, aircraft use the quality bits for variant selection, and saucers and
vehicles use low state bits differently.

The main moving pool has **320 slots**, starting at DS:`8fa6`, allocated at
`9fac`. Guns have a separate **32-slot** pool at DS:`7732` (`08a5`). Objects need
both zero flags and a detached tier before their slot is reusable. World loading
also uses a separate distant record store; the working tile neighbourhood contains
four tiles. The original builder documentation's warnings about far-object editing
and crowded tile boundaries follow directly from these finite stores.

## Clocks and reproducibility

The PIT interrupt at `1732` increments the fast clock and frame counter. Normal
programming uses a divisor of 1024; every 64 fast interrupts chains the normal
BIOS timer. The game therefore has a fast timer, a BIOS-rate timer and a rendered
frame count, rather than one universal tick.

Frame step is `fast_frame_ticks >> 3`, clamped to **2..35**. The common time-scaling
denominator at DS:`1b7f` is **5**. Holding T replaces the effective step with **50**,
while preserving the normal step separately. It is a large simulation step per
rendered frame, not a request for one fixed multiplier independent of frame rate.

Many operations multiply by `step / 5`; others decrement once per frame or use
the hardware timers. The five-frame explosion is one example of a frame-based
lifetime. Damage and AI also consume the shared random stream. Frame cadence,
active objects and execution order consequently matter to reproduction; recording
only player input would not guarantee identical outcomes under a different loop.

The assembly PRNG updates a 32-bit state by multiplication with `278dde6dh`,
wrapping at 32 bits (`ea60`). The bounded wrapper at `ea51` uses the high part
of a product. This is separate from the Borland PRNG used to mask pilot saves.
It affects gameplay as well as cosmetic effects.

## Undocumented controls confirmed in the shipped 3.42 engines

These refer to the DOS originals. The [native reconstruction notes](https://github.com/Lost-Engines/corncob-cpp/blob/master/docs/reconstruction.md)
describe how those behaviours are carried into the unified executable; deliberate
Redux changes are separate from the findings here.

| Input | Behaviour and scope |
| --- | --- |
| Alt-I | Enables invulnerability and clears current aircraft damage. Normal 3.42 forces the flag on; Other Worlds toggles it on/off. |
| Main-row 9 | Latches the tester cheat flag. The sortie-exit code then skips marking the result as invulnerable (`2000h`). This is a result-marker bypass, not proof that every other career restriction disappears. |
| Hold H with R, G or B | Changes the corresponding hallucination/palette counter. The source calls the routine `takedrugs`. Use from the cockpit: H also has an on-foot handler. |
| H+1 / H+2 | Copies the currently altered sky/ground colours into the base palette and packs them into the world header; normal world saving can persist them in `3UNIV.DAT`. |
| U | Other Worlds: starts/stops recording the current flight to `3DEMO.DAT`. Normal 3.42 omits this recorder. |
| L | Toggles cockpit/full-view rendering; omitted from the main manual's key lists. |
| F10 | Queues the mission-objective congratulations message. It does not complete an objective or increment the objective counter. |

The main-row 9 branch is at normal-engine file `0x45e9..0x45f5` and expansion
`0x4af4..0x4b00`. Its flags are DS:`0ae7` and DS:`0bb0`. The corresponding
result exclusion tests start at `0x4c6a` and `0x51da`. Isolated execution of both
unchanged binaries verifies that an invulnerable sortie sets `2000h` without the
latch and leaves that bit clear with it. No whole-career scoring claim is implied.

The H key calls the normal palette routine at file `0x227b` from `0x4264`;
Other Worlds calls its equivalent at `0x22c1` from `0x472d`. Original keyboard-bit
reads and each R/G/B counter update were executed independently in both binaries.
With a five-unit step and rate 310, each key changes only its own counter by 310.
A private DOSBox run also confirms the visible H+R palette change in Other Worlds.

H+1/H+2 do more than change display registers. In normal 3.42 their setters
at file `0x22e1` and `0x22fa` both call `packbits` at `0x643a`. This packs the
sky and ground RGB components into the five `colorbits` bytes of the 16-byte
world header. `writeuniv` writes that header to the working world file,
`3UNIV.DAT`; normal exit writes it when `readfileflag` is set and no critical
error occurred. Resuming that saved world can therefore retain the colours.
The shortcuts themselves make no immediate DOS file-write call. They do not
rewrite the distributed theatre templates or install a global preference.
This persistence path is established by source and native setter disassembly;
a separate DOSBox save/reload experiment has not been performed.

A second private DOSBox check presses U twice in Other Worlds. It writes a
530-byte full/delta recording with the original 37-byte terminator. The recording
is made in a disposable install, not in the retained source installation.
The command-line `-b` playback path reads `3DEMO.DAT` in the current directory;
it must accompany the appropriate world state.

The normal engine also retains a developer world-copy operation gated by `-e`.
At file `0x2e4e`, it checks DS:`0ae5`, then the Right Shift release scan `b6h`,
flushes pending tile changes and calls `copyuniv` (`0x84a6`). The preserved
`F3DVEC.ASM` copies the current four-tile neighbourhood to eight preset locations:
(2,2), (2,4), (2,6), (4,2), (4,6), (6,2), (6,4), (6,6). This changes world
object records; it is a construction tool, not an ordinary flight difficulty
setting. The dispatch and call are confirmed in the shipped normal executable;
the resulting world rewrite has not been exercised in DOSBox.

[TOWER's keyboard tables](tower.md#navigation-and-mission-selection) add J/K,
U/D, G/Shift-G, several control-key navigation aliases, and F1's boss-screen
round trip. Those are reader functions, not a second hidden tower menu.
The [early sun-face trigger](remaining-assets.md#sun-and-an-early-visual-joke)
is confirmed in 1.20/2.00, while the later engines retain its geometry without
a confirmed selection trigger.

## Compile-time variants in the preserved source

These are assembly-time branches, not additional command-line cheats. The
preserved `KA.INC` actually selects `slalom=1`, `guns=0`, `saucey=0` and
`normaltet=0`. That is not the configuration of the ordinary retained 3.42
executables. The source collection contains historical and experimental paths;
this inspection does not establish that every switch combination still builds
or that a slalom edition was released.

### Slalom and the alternate scenery

The training path in `3.ASM:9850` follows six ordered crossings, numbered 0..5.
It takes the high word of X divided by two as the checkpoint index, requires
movement toward increasing X, and alternates the required side of the line
Y=2*65536 cm. An out-of-sequence crossing, wrong side or ground contact away
from home resets the six cockpit progress indicators. The final crossing calls
the normal `incondest` mission-objective routine. No separate race timer is
established by this path; it should not be described as a proven timed race.

`DEFOBJS.ASM:4861` constructs two rows of six Tet markers at different heights.
`normaltet=0` adds a long stem to their geometry and slalom enlarges their
collision bounds. The same alternate layout places fifty trees and a farm
building: type 49's shell geometry becomes a tree (`DEFOBJS.ASM:3166`), while
type 50's saucer geometry is replaced by `FARM.INC` (`DEFOBJS.ASM:3420`). The
alternate type-51 template is another propeller aircraft. Several handler paths
change too: mortar/saucer updates feed radar and nearest-object detection,
forcefields omit their ordinary shutdown paths, and the training checkpoint
code is replaced by a proximity-warning display when a world file is loaded.

`guns=0` independently omits the player's gun, missile and bomb control/update
blocks. It is broader than merely hiding the gun sight. `slalom` also disables
the map-builder variant even if `mbflag` is selected. These observations are from
source inspection; no alternate executable has been assembled or play-tested.

The blue ground polygon reuses `crtrobj`, but slalom sets its span to 16,000 cm
and its colour to blue. A pond is the likely visual intent; the retained symbol
name identifies the reused geometry, not a documented crater in the course.

For standalone generation, `3.ASM` initializes `naas`, `nvest` and `ndbst` to
zero. `INITPERMS` can still place AAA, ground-vehicle and KLA sites when those
counts are explicitly supplied, but the ordinary menu's combat-training defaults
must not be assumed for this source-only standalone run. The three forcefield
placements precede the `saucey` layout branch and remain part of the course.
Finishing the six crossings calls `incondest`, which queues the ordinary
`cmpltrmsg` congratulations popup and its airstrip/F2 advice; no separate slalom
completion text was found in this path.

The training generator also places two coincident `objsurv` markers at `(0,0,0)`
and three more completing the corners of a 20.97152-kilometre square. These
are survey markers, not established world boundaries. `survobj` is a 20-metre yellow
horizontal square with a black cross: the origin marker becomes conspicuous when
the usual generator is omitted. It has no generator/objective role.

The slalom farm's `bmrtim` delegates collision handling to `gmdest`, which replaces
it with the ordinary fuel-dump wreck (`gmobj2/gmobj3`, type 33) and emits twelve
fragments. It does not use the saucer's roll-on-hit or tumbling death behaviour.
Slalom's tree type 49 selects `donothing` instead of `shelltim`, so hitting a tree
must not unpack a concealed enemy. Type 51's slalom `bmrstim` handles hits and
moves the three placed aircraft straight along their fixed attitude with
`followangles`; it does not run the normal enemy-launch countdown. Their placement
height is 131,072 cm, and their type-51 property entry is zero, unlike boardable
player aircraft. Their precise intended gameplay role is not documented; traffic
or a proximity-warning experiment is an inference from these routines.

### Other significant switches

| Switch | Source-level effect |
| --- | --- |
| `shareflag` | Shareware/registered feature gates, including helper access, invulnerability toggle behaviour, demo machinery and world-type encoding choices. The makefile has explicit `3s`/`3r` targets. |
| `mbflag` | Includes the in-game mission-builder machinery; registered target selects it, shareware target omits it. Slalom overrides its map-builder selection. |
| `demover`, `nodemo`, `demorec` | Distinct demo-only, playback-availability and recording branches. A demo-only build omits ordinary configuration/tower/report paths. |
| `qrocket` | Includes the rechargeable rear rocket booster and its thrust/HUD/input code. |
| `protection` | Old registration/trial checks and bouncing-ball interruption machinery; disabled in this snapshot. The 2.00 readme explicitly says all protection was removed. |
| `testerflag` | Includes the main-row 9 tester latch and its invulnerable-result-marker bypass. Enabled in the snapshot and confirmed in both retained 3.42 engines. |
| `MVPCD` | CD packaging path: separate writable-directory prefix for generated files, and changed argument parsing. |
| `getunivbin` | Includes `UNIVBIN.DAT` object importing/merging into the saved world. |
| `vgmode` | Legacy 640x350 and 320x200 colour and Hercules-related rendering branches. Their presence does not establish a working alternative build on modern or original hardware. |
| `normaltet`, `saucey` | Alternative Tet geometry and alternative procedural training/scenery layouts. |
| `soundflag`, `fadeflag` | Sound-code and fade branches; sound is enabled when `soundflag=0`. |
| `simpflag` | Includes the beginner-aerodynamics pitch-assistance branch. |
| `avgthrot` | Smooths the engine sound's frequency value, rather than smoothing physical throttle input. |
| `stestflag` | Replaces normal startup flow with an interactive sound test. |
| `larryflag` | Startup test-point messages addressed to Larry; the separate ADL module's setting suppresses hardware port writes. |
| `printflag`, `diagflag`, `jdiag`, `polydiag`, `copydiag`, `chopchop`, `finalscreen` | Assorted state dumps, joystick/renderer/copy diagnostics, test paths and end-of-run reporting. |

The protection code is unusually personal. `DEFOBJS.ASM:5443` has a `hotshot`
branch described as detecting players too good for a trial. It checks roll and
attack-evasion progress, then branches to `hosehim`, with the comment "hose this
guy, he's too good!". That changes a survey object's collision-radius field to
-2. The later collision path explicitly treats negative radii as protection
signals: -1 sets critical error 97, -2 sets 98, and a negative radius on a type
other than survey marker 31 sets error 59. It also forces the ejected flag.
The main loop exits on a nonzero critical error and skips the normal world save.

[Eight isolated native trap checks](gameplay/protection-checks.json) confirm these
outcomes in both 1.20 and normal 3.42. The 1.20 code contains both negative-radius
producers (`0xc8d9`, `0xc910`); normal 3.42 contains neither producer even though
the trap consumer remains. These checks execute the unchanged trap prefix only,
not a complete trial-expiry session or all front-end handling.

## Recovered resources and runnable experiments

The [model browser](resources/index.html) now includes the source-only farm,
tree, unused foliage-only tree helper, tall Tet marker and large blue crater.
They appear beside normal models and under the **source variants** edition.
`tools/extract_source_models.py` reads the original DW/EQU/DUP data, preserving
all eight painter lists; it does not build or execute source instructions.
Its normalized data addresses start at `0xf800` and are not historical executable
offsets. The six stored detail models occupy 935 bytes. Source-file hashes are
recorded in [their metadata](resources/models/source_variants.json).

The C++ reconstruction bundles these data and provides `--slalom`. It launches
the recovered training-layout/checkpoint experiment with player weapons disabled,
six progress cells and local objective completion; it does not save this run into
pilot careers. The selected slalom aircraft reuse the ordinary aircraft's stored
middle/far models, rather than adding another hidden aircraft mesh. Their
placements use Z=131072 cm and zero angles: STRTPERM copies the nine KBUF words
over the template, including the high word of Z and all three angles. The tree
object uses its full model at near/middle detail and its line-trunk helper at far
detail; the foliage-only helper is stored but unreferenced by that template.

`--graphics-mode=ega-low` and `--graphics-mode=hercules` make the source's 320x200
colour and 720x348 monochrome scene profiles available alongside default
640x350 EGA. World projection/rasterization runs at the selected resolution.
Hercules uses the recovered BKCLRS fill masks and HGCLINE solid-line mapping.
The port adapts the preserved cockpit/instruments and retains the original
helper display modes: there are no verified alternative cockpit bitmaps, some
source helpers assume 640 pixels, and the alternate branches omit the usual
full-view definitions. These are source-based reconstructions with documented
adaptations, not pixel comparisons against a retained released alternate build.


### Was a Hercules edition released?

Publication remains unconfirmed after the 17 October 2026 web/archive search.
No identified Hercules distribution, contemporary announcement or authenticated
Hercules screenshot was found. This is a negative search result, not proof that
no such build ever circulated.

The source evidence is stronger than an unused resolution constant:
[3M.LNK](original_source/3M.LNK) and
[3DEMO.LNK](original_source/3DEMO.LNK) explicitly link `hgcpixad` and `hgcline`.
Together with the CRTC setup, raster routines and 720x348 projection branch,
these establish intended Hercules rendering support. The linker inputs do not
prove that a complete Hercules executable was built or distributed; the snapshot
also contains incomplete alternative paths and lacks verified alternate cockpit art.

Evidence from released versions points to VGA as the supported public target.
The retained 1.20 CORNCOB.DOC says “Corncob absolutely requires a VGA adapter”
and separately mentions that a mono-VGA system may or may not work. Its FAQ
explains the dependency on VGA write mode 3 and palette effects. A monochrome
VGA monitor is not a Hercules adapter. Later retained manuals require colour VGA.
The June 1993 Brisbug catalogue lists version 2.0 as VGA:
[contemporary newsletter](https://archive.shikadi.net/brisbug/Brisbug%20%5B1993-06%5D%20-%20Significant%20Bits%20%28Vol%208%20No%207%29.pdf).

The working hypothesis is an experimental or older development configuration,
possibly predating the documented releases. Its age and publication history
cannot currently be established. The C++ Hercules option is a reconstruction
from those source paths, not evidence of a recovered historical executable.

## MVP CD packaging switch

`MVPCD` is set to zero in the snapshot. Its branches in `3.ASM` and `CMDLINE.ASM`
redirect generated files through a writable-directory prefix, instead of trying
to write beside an executable on read-only media. A CD-enabled build accepts
`-p<path>` (also the `-z` dispatch alias) and prefixes `3.CMD`, `3.RES`,
`3UNIV.DAT`, `3D.CFG` and `3DEMO.DAT`; helper invocations also receive the path.
It suppresses the ordinary registered-copy banner. The branch does not introduce
CD audio, new models or a separate campaign-content loader.

The name and publisher identify this as MVP Software CD packaging, but no
retained disc executable has been compared. CD distribution itself is documented:
the Centre for Computing History's physical **1993 MVP Software's Game Jamboree**
[contents transcription](https://www.computinghistory.org.uk/det/59353/MVP%20Software's%20Game%20Jamboree/)
lists Corncob Other Worlds Campaign. That establishes a CD compilation appearance;
it does not establish an enhanced CD edition or which source configuration that
particular disc used.

## Early protection behaviour

The 1.20 [registration help](../installs/shareware_1_20/MOAG.INF) offers a $15
machine-bound economy reply code or a $25 supplied unprotected edition with the
builder. Its menu executable contains trial-expiry, incorrect-reply-code and
incorrect-system-date messages. These establish the trial/registration system
independently of the later source's `protection` condition.

The protected source's `welcomewagon` interrupts play with IMG help/welcome pages:
the first immediately, others after a delay, an airspeed or altitude threshold,
and later fifteen-second intervals. `bounceimg` silences effects and makes the
player wait for a bouncing ball before Space resumes. A hidden Enter + keypad 5
+ A check skips the current ball wait; it is established here from source only,
not from a keyboard experiment in the protected executable.

The `hotshot` branch can end a trial flight based on roll/attack-evasion progress,
not merely elapsed calendar time. It deliberately reaches the error-98/ejection
trap described above. The normal critical-error path bypasses world saving;
this is not a hidden reward or a more difficult enemy. The 2.00 readme explicitly
announces removal of all protection. None of this enforcement is enabled in the
C++ reconstruction.

## Cockpit frame and airflow indicator

In the unchanged deluxe 3.42 `3.EXE`, EPAGE (file offsets `0x561f..0x570e`)
subtracts one byte from the main window's first-byte offset, then adds `bpl-1`
to select the right strip. At 80 bytes per row this is column 79, pixels
632–639; using byte 78 incorrectly lets the scenery overwrite the frame.

DRAWMDS (`0xcd51..0xcdd2`, through its DRAWDisc call) computes a six-pixel
airflow indicator using body velocity and passes `win0`, the radar clipping
rectangle `(496,259)–(615,327)`. At zero velocity the computed centre is
`(638,243)`, outside this rectangle: the original writes no pixels. Drawing
it against the whole screen instead causes a stray red dot beside the cockpit.
Forward velocity `(1000,0,0)` gives a visible ball at `(559,298)`; lateral and
vertical samples independently confirm clipping at the right and top.

`tools/verify_cockpit.py` reproduces these findings in isolated original routines
without stubs, and retains the source hash, addresses and results in
`analysis/gameplay/cockpit-checks.json`. VGA memory writes establish pixel coverage;
this probe does not emulate four-plane colour composition or a complete frame.

## Reproduce the investigation

From the repository root, using the same Python environment as resource extraction:

```sh
python3 tools/analyse_gameplay.py
python3 tools/verify_gameplay.py
python3 tools/catalogue_mission_rules.py
python3 tools/extract_source_models.py
python3 tools/verify_source_switches.py
python3 tools/verify_cockpit.py
```

The first tool needs Capstone and the existing extraction dependencies. Native
checks additionally require Unicorn. An arbitrary extra range can be inspected
without rewriting reports:

```sh
python3 tools/analyse_gameplay.py --show 0x37d0:0x3c0c
```

Original installations are read-only inputs. The generated reports contain source
hashes and the native checks state their stubs and limits.

## Scope and subsequent reconstruction

This report records the initial disassembly and native probes. The later
[C++ reconstruction](https://github.com/Lost-Engines/corncob-cpp/blob/master/docs/reconstruction.md#verification) adds independent native comparisons
for fast-projectile contacts, landing/suspension, autopilot feedback, actor
updates and campaign transitions. Those are no longer unimplemented items merely
because this earlier report describes a smaller set of checks.

The limits of the evidence still matter. We have not compared every gameplay
branch across all seven flight binaries, nor established whole-session equivalence
against long DOS recordings with identical random-number consumption. A routine
matching its native fixtures does not by itself prove every possible interaction
in a complete campaign. The reconstruction notes list the coverage and remaining
qualifications for that work.
