Back to Big Rig Rush
SOURCE / PINNED RELEASE

Made of little things.

Big Rig Rush

Release
ec9b6549f752…
Author-recorded commit
74b729258b1a…
License
LICENSE
Author’s source reference
nostr://npub1sj2vketepqw9v6fmge5fdzuj7atj9sv6qv2jss05n2z6rl64lcfqumdsnt/wss%3A%2F%2Fgit.napplet.soy%2F/n-0a99f0cae40

Archive hash verified: 900e22810340ccb1…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/game/a10.ts
/**
 * The A-10's flight: level flight at a fixed working height over the city, in SI units.
 *
 * Two TF34 turbofans (40.3 kN each) that spool with a lag push against parasite and
 * lift-induced drag from the 47 m² wing, so the airspeed settles where thrust meets drag
 * (about 720 km/h flat out, about 250 km/h at idle before it won't go slower). The stick
 * rolls it into a bank and the bank turns it; a turn costs lift, and the extra induced
 * drag bleeds speed. Turns are tightened for the game's scale. Stores lighten the jet.
 *
 * A / D (or the arrows) roll, W / S (or Up / Down, or N / M) move the throttle lever.
 * Let go of the roll and the wings come level.
 */

export const METERS = 0.33;
export const G = 9.81;
/** The working height the jet flies at, in map units (about 40 m): bombs fall in view. */
export const FLIGHT_ALT = 120;

const WING_AREA = 47;
const CD0 = 0.068;
const K_INDUCED = 0.061;
const THRUST_MAX = 2 * 40300;
const EMPTY_KG = 11320;
const FUEL_KG = 3600;
/** Roll rate (rad/s) and the steepest bank the stick holds. */
const ROLL_RATE = 2.2;
const MAX_BANK = 1.2;
/** The game's map is small for a jet: turns are this much tighter than real. */
const TURN_BOOST = 2.6;
const MIN_SPEED = 68;
/** Gun recoil: about 45 kN while the GAU-8 is firing at full rate. */
export const GUN_RECOIL = 45000;

export interface FlightInput {
  roll: number;
  throttleUp: boolean;
  throttleDown: boolean;
}

export class A10Flight {
  /** True airspeed (m/s). */
  v = 135;
  /** Heading (rad), same convention as the map's angles. */
  heading = 0;
  bank = 0;
  /** Throttle lever 0 (idle) .. 1 (max), and the engines' actual spool. */
  lever = 0.55;
  spool = 0.55;
  /** Load factor in the turn (g). */
  g = 1;
  /** Stores, gun ammunition and fuel aboard (kg); the game updates it as weapons go. */
  stores = 3200;
  /** Extra drag force (N) this step, e.g. the gun's recoil. */
  recoil = 0;
  /** Shot down: how far it's fallen toward the ground (0 flying .. 1 down). */
  fall = 0;

  constructor(heading: number) {
    this.heading = heading;
  }

  get mass(): number {
    return EMPTY_KG + FUEL_KG + this.stores;
  }

  /** Lever steps (a tap of N or M). */
  nudge(step: number): void {
    this.lever = Math.max(0, Math.min(1, this.lever + step));
  }

  step(dt: number, input: FlightInput): void {
    const m = this.mass;
    const W = m * G;
    if (input.throttleUp) this.lever = Math.min(1, this.lever + dt * 0.6);
    if (input.throttleDown) this.lever = Math.max(0, this.lever - dt * 0.6);
    // High-bypass turbofans spool slowly, quicker near the top.
    const target = 0.06 + this.lever * 0.94;
    const tau = target > this.spool ? 1.4 - this.spool * 0.5 : 1;
    this.spool += (target - this.spool) * Math.min(1, dt / tau);

    // Roll toward the bank the stick asks for; let go and the wings come level.
    const rollStep = ROLL_RATE * dt;
    this.bank += Math.max(-rollStep, Math.min(rollStep, input.roll * MAX_BANK - this.bank));

    const v = Math.max(MIN_SPEED, this.v);
    const q = 0.5 * 1.225 * v * v;
    // A level, coordinated turn: the wing carries 1/cos(bank) g.
    this.g = 1 / Math.cos(this.bank);
    const CL = (this.g * W) / (q * WING_AREA);
    const drag = q * WING_AREA * (CD0 + K_INDUCED * CL * CL);
    const thrust = THRUST_MAX * this.spool;
    this.v = Math.max(MIN_SPEED, this.v + ((thrust - drag - this.recoil) / m) * dt);
    this.recoil = 0;
    this.heading += ((G * Math.tan(this.bank)) / v) * TURN_BOOST * dt;
  }
}