# 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: ```bash python3 -m http.server 8080 # or npx serve . ``` Then open . 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.