Flight dynamics and player movement
Gameplay overview and evidence · Native force results. Addresses refer to the normal 3.42 flight executable unless labelled otherwise.
Aircraft state and coordinates
The player has distinct world position, orientation, orientation matrices, world velocity and aircraft-relative velocity. The engine does not assume that movement follows the nose.
| DS offset | State |
|---|---|
0b05 |
Player position, three signed 32-bit coordinates |
0b11 |
Player/view angles, three words |
1d24 |
Incremental rotation matrix |
1d36, 1d48 |
Matrices used in world/body velocity and force transforms |
1d90 |
Three signed 32-bit force accumulators |
1d9c |
Aircraft-relative velocity, three signed words |
1dbc |
World-space velocity increments for position integration |
1dc2 |
World-space velocity, three signed words |
1dc8 |
Body velocity divided by 16, used by several force/control calculations |
1dfa, 1dfe, 1e04 |
Three signed 32-bit angular response accumulators |
1de2, 1de6 |
Current throttle and damage-limited engine ceiling |
1df0 |
Stall state |
1e34, 1e36 |
Current and previous airflow angle |
1e5e |
Effective elapsed step |
5bb0 |
The aircraft object retained while the pilot is outside |
Positions are the centimetre coordinates used by the world files; angles wrap a full turn at 65536. Different velocity representations include additional fixed point scales. The raw force coefficients below should not be presented as SI masses, newtons or metres/second without deriving those conversions.
The shared matrix-vector transform is at 581d; signed fixed-point products and
integer division are used throughout. Gravity is projected into aircraft axes,
forces modify body velocity, and the result is transformed back to world velocity.
Changing the nose changes the axes and control response; it does not instantaneously
replace the world movement vector. This is the basis for sideslip, banked turns
and flying backwards.
Rotation, inertia and controls
31a7–3789 turns centred stick input into angular response. The response depends
on airflow, atmospheric density, existing angular motion and damage. The three
angular accumulators are damped, then their high words are clamped to ±3000
before applying time-scaled rotation to the matrix. Rudder input is read separately
from roll/pitch. Ground state changes rudder response, and taxiing over grass adds
random pitch/roll disturbance (379c–37c4).
Damage is physical rather than a single remaining-health bar:
| Routine | Effect |
|---|---|
1060 |
Reduce the engine ceiling by its configured percentage; clamp current throttle |
0fc1 |
Add a random-sign roll bias and associated damage state |
1040 |
Increase shared control jitter |
0fff |
Add yaw/rudder bias, tending to reinforce its existing sign |
0f85 chooses one of these four damage channels for each hit. The repair routine
at 1e47 clears the accumulated biases/jitter and restores the engine ceiling to
200. Random control jitter is applied to all three angular high words at
36c7–370b, with its magnitude growing with damage and airflow.
This agrees with the manual's description of asymmetrical wing damage and damaged controls becoming difficult to fly. The exact physics here is a compact game model, not a full aerodynamic simulation with separate structural masses for every part.
Atmosphere, thrust, drag and lift
The force calculation is 37d0–3c0c. Theatre headers can change gravity, density
and atmosphere height (1d27). Gravity is clamped to −100..−15, density is
accepted in 1000..10000, and an atmosphere-height value must be at least 256.
Density falloff starts from the theatre's sea-level density:
height = max(0, altitude >> 8)
remaining_atmosphere = max(0, atmosphere_height - height)
density = sea_level_density * remaining_atmosphere / atmosphere_height
This describes the integer calculation at 3939–3965 in the ordinary altitude
range, not exponential atmosphere falloff. The native implementation takes the
word spanning position bits 8–23; it is not an unbounded signed 32-bit shift.
The density stored from one pass is also consumed earlier in the next pass.
Thrust depends on throttle above the idle value 20, the engine coefficient, forward airflow and density-related power falloff. The forward-speed denominator has a lower bound; the power reduction near the top of the atmosphere uses the original cosine routine. The rocket booster adds its own thrust term.
Forward and sideways drag oppose the sign of the corresponding body velocity and are quadratic in speed. Separate divisors and a speed breakpoint change the drag regime. Lift opposes the body's vertical airflow and likewise uses a signed square, atmospheric density and a stall-dependent divisor. Banking rotates that force into the world, so lift can turn the flight path sideways.
Selected initial coefficients, before theatre-specific overrides:
| DS | Raw value | Use |
|---|---|---|
1dda |
16 | Common force scale |
1ddc |
−48 | Gravity |
1dea |
450 | Normal engine coefficient |
1dee, 1df2 |
300, −300 | Clamps used for control-effective forward airflow |
1e18, 1e1a |
2016, 28224 | Unstalled and stalled lift divisors |
1e1c, 1e1e |
5957, 5957 | Sea-level density and atmosphere height |
1e22 |
3971 | Atmosphere/power transition parameter |
1e26, 1e28 |
13734, 1368 | Forward drag divisors |
1e2e |
136 | Alternate sideways drag divisor |
1e32 |
1390 | Drag-regime breakpoint |
The complete initial words remain in tables.json. Numbers there are engine coefficients; their labels do not assert physical units.
Stalls and flaps
At 3a57, the engine derives an airflow angle from forward and vertical body
velocity. A normal unstalled window is approximately −16°..+16°: add 2912
to the angle and require a non-negative value below 5824. With flaps, those
constants become 3882 and 7764, approximately ±21.3°.
Inside that window, the normal lift divisor is 2016. Outside it, the divisor becomes 28224—fourteen times larger, sharply reducing this lift term. Flaps halve the unstalled divisor, increasing lift, and quarter the forward drag divisor, increasing drag. Their extra lift therefore comes with a substantial speed cost.
The automatic stall limiter is separate (3633–36c7). It examines current/previous
airflow angle and angular motion and attenuates pitch response. It is not an
absolute clamp on aircraft attitude: low speed, sideslip, damage and an already
bad flight state can still cause a stall.
Controlled native force passes give these raw world-velocity results. Each starts
with identity axes, velocity (5000, 0, −1000), elapsed step 5 and otherwise stored
defaults; only the stated input changes. These are single-pass comparisons, not
terminal speeds or a performance specification.
| Scenario | Density used | Resulting velocity |
|---|---|---|
| Throttle 200 | 5957 | (5014, 0, −977) |
| Throttle 20 | 5957 | (4996, 0, −977) |
| Flaps down | 5957 | (5012, 0, −933) |
| Altitude 1,000,000 cm | 2051 | (5016, 0, −1007) |
| Sea-level density 3000 | 3000 | (5016, 0, −1001) |
| Gravity coefficient −96 | 5957 | (5014, 0, −1001) |
The lower density reduces both lift and drag. Separate zero-forward-speed and backwards-velocity probes enter the stalled branch, whereas the baseline does not.
Three aircraft variants
Aircraft flags distinguish standard blue, reserve brown and experimental black variants. They share the main force calculation, with meaningful differences:
- Reserve aircraft (
1000h) reduce the engine coefficient from 450 to 350 (37f2–3810) and change the displayed colour. - Experimental aircraft (
2000h) select flying-wing geometry and change position integration from a right shift of four to two (15d5). At equal internal velocities, they travel four times as far. The airspeed display applies the same fourfold adjustment (c917). This is not a separately authored jet model. - The ordinary world aircraft has just two scenery hit points. That value is not the player's full damage model; entering the craft transfers to separate state.
A native integration probe with world velocity (1600, −800, 320) and zero
increment advances a normal/reserve aircraft by (100, −50, 20) cm and the black
variant by (400, −200, 80) cm. Integration also includes half of the saved velocity
increment. The smaller shift applies to vertical movement too, explaining the
manual's warning about the experimental aircraft falling much faster.
The black variant also has a campaign permission gate on throttle increases:
Combat Master unlocks the experimental flight.
Its cockpit and animated propeller remain shared. The propeller routine at
43c6–4421 positions the same model and derives its rotation from throttle and
the fast timer; it does not substitute a jet-specific cockpit for the black craft.
Landing, ground handling and autopilot
129a evaluates attitude and transforms left/right contact geometry to estimate
support height. 1805–198c handles ground state, contact penetration, suspension,
braking and crash landing. Runway contact is identified from the type-properties
bit, and the collision pass records runway elevation. This supports elevated
runways as well as ground strips.
The ground routine uses different thresholds for runway and grass contact; landing
is not just altitude <= 0. Grass taxiing adds random disturbance, while the
brake keys apply continuous deceleration. Once speed and throttle are low enough,
the stopped aircraft and landing-status flags are set. The subsequent native reconstruction
implements this path and checks wheel clearance, suspension/braking and
invulnerable bounces against original routines. That is stronger evidence than
the initial outline here, while still short of exhaustive marginal-touchdown
comparisons across every release.
Autopilot includes both control assistance and a relocation/approach sequence.
The F2 mission-selection relocation at 0e5c is refused when damage reaches 16;
when accepted, it installs the selected start, sets body forward speed to 5000,
rebuilds velocity/matrices and changes related control state. The ordinary A-key
assistance also responds to vertical motion and changing altitude (1327, 13bc).
The subsequent native reconstruction
checks 512 autopilot/beginner feedback cases, including both flight models, stall
state and engagement combinations. The addresses here remain a guide to the
original control flow.
Walking, ejection, parachute and remote flight
Ejection is handled at 4978–4b24. It leaves the aircraft as a separate object,
initializes 20 pistol rounds and one assassin bomb, transfers velocity to
the person, and adds randomized ejection motion when airborne. Walking out of a
stopped plane instead starts on the supporting surface. Space opens the parachute;
there is no automatic ripcord.
The stored startup inventory is zero pistol rounds at DS:1d01 and zero
carried assassin charges at DS:1d03. White Sands starts on foot, so no explicit
mission weapon-disable flag is required: the pilot has not yet left an aircraft.
Boarding and tower visits do not supply these items. Leaving the aircraft does.
Walking applies the effective elapsed step twice: WTADJ scales the signed
800-unit stride before rotation; MOVEOBS arithmetic-shifts by four and applies
DWTADJ again. The step gate (14c6) requires more than 40 fast PIT ticks since
the previous step, then alternates heading wobble by 100 angle units. Normal
elapsed time is the render duration in fast PIT ticks divided by eight and
clamped to 2–35; holding T overrides it to 50. Consequently even ordinary walking
speed depends substantially on rendering cadence, and T is not a uniform tenfold
walking multiplier.
At heading zero with no wobble, elapsed 10/normal 5 produces (198, 0, 0) cm per
accepted step; elapsed 50 produces (4990, 0, 0). The ports' reproducible
tools/generate_walking_reference.py executes the original caller and
GOODSTEP/MOVEOBS, covering 448 forward/backward, heading and timing cases
without stubbing arithmetic. The timer gate and wobble are excluded explicitly.
On foot, forward/backward movement follows horizontal facing (14eb and 1538)
and can still be controlled during a jump. Holding J charges the jump; release
installs a vertical velocity based on that charge. Gravity, drag and landing are
processed separately from aircraft aerodynamics (3d3d–3ee3). The parachute changes
fall parameters, rather than merely displaying a canopy. Hard landing can kill the
person; the invulnerability flag bypasses the fatal branch.
Caps Lock toggles DS:0f54, the remote-flight state. Aircraft controls and weapons
can then operate on the retained plane while the viewpoint remains with the person.
The abandoned aircraft continues to move (3efe–3f8d); leaving it does not freeze
its trajectory. Entering another aircraft saves the previous one back into the
world and adopts the new craft (1e6a).
Re-entry is gated: the player must first go more than 4000 cm from the retained
plane, then return within 2000 cm (427c–42c2). That explains the manual's
instruction to walk a few plane lengths away. Distance-tier/availability checks can
also prevent entry into an aircraft left too far away. Ordinary parked aircraft
can be repositioned by the ground-crew logic; the black and damaged variants are
explicitly excluded from parts of that repositioning (9701–976c).
Walking uses the extended property flags: horizontal fields, runways, fuel tanks, saucers and towers can support a person. Forcefields are not intrinsically fatal to flesh, whereas AAA shells, KLAs, hot craters, balloons and swarms are contact hazards. Aliens and hostile vehicles capture instead of applying aircraft damage.