Files
flight-sim/README.md
T
Quintine 8c19cdaae6 3D flight simulator: 6-DOF physics, three.js r160, browser HUD
- Detailed flight dynamics: aero lift/drag/side-force with smooth stall,
  control-surface moments, stability derivatives, engine spool with prop
  torque and gyro precession, inertial coupling, ISA atmosphere, ground
  effect, 3-point gear handling, landing vs crash classification.
- Pure ESM, zero build step; three.js vendored locally. Deterministic
  simulation; physics core is Node-testable (14 node:test cases).
- Procedural 8 km world with runway, water, sky dome, cloud wrap; DOM
  instrument panel (attitude indicator, tapes, VSI, lamps, stall warning).
- Controls: WASD/arrows, Q/E rudder, Shift/Ctrl throttle, F flaps, G gear,
  B brakes, C camera (chase/cockpit/orbit), R reset, P pause, D debug.
2026-08-24 17:58:58 +10:00

4.8 KiB
Raw Blame History

Flight Sim

A browser 3D flight simulator: a detailed 6-DOF propeller aircraft flown over a procedural 8 km world, with an instrument HUD, synthesized engine/wind audio and three camera views (chase / cockpit / orbit). Pure ES modules, zero build step, no assets, no runtime network — Three.js r160 is vendored locally.

Spawn: on the south end of the runway, engine idling, flaps 25 %, gear down, brakes on. Throttle up with Shift, release brakes with B, roll forward with the stick, and rotate at ~120–140 kts.

Run it

ES modules must be served over HTTP (opening index.html directly on file:// is blocked by the browser). From the project root:

python3 -m http.server 8080
# or
npx serve .

Then open http://localhost:8080. Fullscreen canvas; CLICK TO START enables audio (the browser requires a user gesture for WebAudio).

Controls

Table below mirrors KEY_BINDINGS from src/controls.js (single source).

Key Command
W / S Elevator — pitch up / down
A / D Aileron — bank left / right
↑ / ↓ Elevator (arrow keys)
← / → Aileron (arrow keys)
Q / E Rudder — yaw left / right
Shift/Ctrl Throttle up / down
F Flaps 0 → 25 % → 50 % → 100 %
G Gear up / down
B Brakes on / off
C Camera view (chase/cockpit/orbit)
R Reset flight
P Pause
D Debug overlay
S / Enter Sound on / off

Sticks slew smoothly (~1.6 full-range/s), throttle slews slowly (~0.4/s) so engine response feels realistic; toggle keys ignore auto-repeat.

Architecture

index.html            static shell: canvas, #hud, start overlay
css/style.css         HUD/instrument glass styles + start overlay (integrator)
src/main.js           game loop, fixed-timestep physics driver, cameras,
                      crash/reset/pause/debug, audio + HUD feed (integrator)
src/config.js         SI constants — single source of truth (airframe, atmo)
src/world.js          deterministic height field + runway (single ground source)
src/physics.js        6-DOF rigid-body dynamics, ground model, crash logic
src/controls.js       keyboard → smoothed inputs + action events
src/aircraft-model.js Three.js visual model (surfaces/prop/gear animate)
src/terrain.js        sky, sun, elevation-mapped ground, runway, water, clouds
src/instruments.js    DOM instrument overlay (attitude, tapes, lamps, stall)
src/audio.js          synthesized engine/wind/stall/touchdown (WebAudio)
vendor/three.module.min.js   Three.js r160 (vendored)

Loop

main.js runs a fixed-timestep sim: real frame dt is clamped to 0.05 s, accumulated, and consumed in 1/120 s physics steps (max 8 per frame), so simulation behaviour is frame-rate independent and deterministic. No Math.random() anywhere in physics; cosmetic randomness is seeded.

Physics summary

  • Body frame +X forward, +Y right, +Z down; quaternions [w,x,y,z]; heading 0° = north, +Y world up.
  • Forces: stability-axis lift fitted with a smooth stall blend toward the flat-plate regime, drag CD0 + k·CL² + flaps/gear + flat-plate, side force from β and rudder; moments from static stability, control effectiveness and rate damping (Cmq, Clp, Cnr).
  • Engine: first-order spool to throttle, thrust scaled by (ρ/ρ0)^0.7, prop torque and gyroscopic moment about the thrust axis.
  • Inertial coupling with the full symmetric inertia tensor; semi-implicit Euler integration at 1/240 s substeps, quaternion renormalised per substep.
  • Ground: wheel-height contact, crash vs. landing classification by sink rate, gear state and attitude; rolling friction, ×3 braking, ground steering, taxi thrust. Fuel burn ∝ rpm·throttle.
  • Atmosphere: ISA density lapse with altitude.

Camera modes (C)

  1. Chase — smooth follow 8 m aft / 2.2 m above the c.g., looking just ahead of the nose.
  2. Cockpit — pilot eye at aircraft-model.cockpitOffset(), hard-locked to the aircraft attitude with a subtle g-load sway.
  3. Orbit — slow auto-spin around the ship; drag with the mouse to steer the view angle and height.

Notes

  • Shadows are disabled by default (cheap path; flip buildEnvironment(scene, { shadows: true }) and enable renderer.shadowMap in main.js to test the 4096 px variant).
  • Altimeter/airspeed/VS are pitot-static cosmetics: ft, kts, fpm.
  • One CSS file owns all HUD look; instruments.js only sets per-frame transforms and class toggles.