Back to Big Rig Rush
SOURCE / PINNED RELEASE

Made of little things.

Big Rig Rush

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

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

tests/speed-enforcement.test.mjs
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import ts from 'typescript';
const toJs = (file) => ts.transpileModule(readFileSync(new URL(`../src/game/${file}`, import.meta.url), 'utf8'), { compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ES2022 } }).outputText;
const asUrl = (js) => `data:text/javascript;base64,${Buffer.from(js).toString('base64')}`;
const limitsUrl = asUrl(toJs('speed-limits.ts'));
const limits = await import(limitsUrl);
const { Dispatcher } = await import(asUrl(toJs('dispatch.ts').replace("'./speed-limits.js'", `'${limitsUrl}'`)));

test('signs post round limits for every road kind, and calm cruising never trips the radar', () => {
  const roads = { drive: 45, street: 55, industrial: 58, avenue: 62, country: 72, ramp: 88, expressway: 112, spur: 150 };
  const posted = Object.fromEntries(Object.entries(roads).map(([k, v]) => [k, limits.postedKmh(v)]));
  assert.deepEqual(posted, { drive: 50, street: 60, industrial: 70, avenue: 70, country: 80, ramp: 100, expressway: 130, spur: 170 });
  for (const [kind, speed] of Object.entries(roads)) {
    const limit = limits.ticketKmh(posted[kind]);
    // Calm drivers (temper up to 0.95) and rude ones (up to 1.05) stay under; speeders (1.25+) don't.
    assert.ok(limits.toKmh(speed * 0.95) < limit, `${kind} calm`);
    assert.ok(limits.toKmh(speed * 1.05) < limit, `${kind} rude`);
    assert.ok(limits.toKmh(speed * 1.25) > limit, `${kind} speeder`);
  }
});

test('fines grow with the excess and are capped', () => {
  assert.equal(limits.fineFor(60, 60), 60);
  assert.equal(limits.fineFor(85, 60), 160);
  assert.equal(limits.fineFor(300, 60), 400);
});

function fixture({ truckSpeed = 0, speeders = [] } = {}) {
  const state = { stops: [], released: [], tickets: [], clocked: [], reassigned: [] };
  const trap = { kind: 'police', state: 'work', busy: true, x: 0, y: 0, layer: 0, body: { angle: 0 }, target: { x: 0, y: 0 }, task: { stop: 'trap' } };
  const world = {
    traffic: {
      wrecks: [], all: () => [], burningNear: () => [],
      speeding: () => speeders.filter((s) => !s.car.pulled),
      pullOver: (car) => { car.pulled = true; state.stops.push(car); },
      releaseStop: (car, ticketed) => { car.pulled = false; state.released.push({ car, ticketed }); },
      trapSpot: () => ({ x: 400, y: 0, layer: 0 }),
    },
    peds: { injured: () => [], injuredNear: () => [] },
    effects: { allFires: () => [], messSpots: () => [], firesNear: () => [], roadDamage: () => [], structureDamage: () => [] },
    services: {
      vehicles: [trap], available: () => 3, covering: () => false,
      laneAt: () => ({ kind: 'street', turn: false, speed: 55 }),
      reassign: (v, x, y, layer, task) => { v.task = task; v.state = 'drive'; state.reassigned.push({ x, y, task }); return true; },
    },
    street: { broken: () => [], fullBins: () => [] },
    wildlife: { carcasses: [] },
    truck: { x: 50, y: 0, layer: 0, angle: 0, speed: truckSpeed, plane: false },
    sound: () => {}, hour: () => 8, brokenProps: () => [], burning: () => [], rescueSites: () => [], inTurf: () => false, coordination: () => 1,
  };
  const dispatch = new Dispatcher(world);
  dispatch.onTicket = (car, fine, kmh, posted) => state.tickets.push({ car, fine, kmh, posted });
  dispatch.onClocked = (fine, kmh, posted) => state.clocked.push({ fine, kmh, posted });
  return { dispatch, state, trap, world };
}

const speeder = () => ({ x: 30, y: 0, angle: 0, speed: 80, layer: 0, mode: 'drive', pulled: false, body: { halfL: 9, halfW: 4 } });

test('a radar car pulls a speeder over, and the fine is collected only once the ticket is written', () => {
  const car = speeder();
  const { dispatch, state, trap } = fixture({ speeders: [{ car, kmh: 95, posted: 60 }] });
  dispatch.enforce();
  assert.equal(state.stops.length, 1);
  assert.equal(state.reassigned.length, 1);
  const task = trap.task;
  assert.equal(task.stop, 'ticket');
  assert.equal(task.offroad, false);
  assert.equal(task.valid(), true);
  // Pulls in behind the car, and the officer walks up on the curb side.
  assert.ok(state.reassigned[0].x < car.x);
  assert.ok(task.points()[0].y > car.y);
  assert.equal(state.tickets.length, 0);
  task.onPointDone();
  task.onDone();
  assert.deepEqual(state.tickets.map((t) => t.fine), [200]);
  assert.deepEqual(state.released.map((r) => r.ticketed), [true]);
  // Another radar sweep doesn't stop the same car twice while it's claimed.
  dispatch.enforce();
  assert.equal(state.stops.length, 1);
});

test('the radar only stops cars that have gone past it the way it faces', () => {
  const coming = { ...speeder(), x: -40 };
  const oncoming = { ...speeder(), x: 40, angle: Math.PI };
  const { dispatch, state } = fixture({ speeders: [{ car: coming, kmh: 95, posted: 60 }, { car: oncoming, kmh: 95, posted: 60 }] });
  dispatch.enforce();
  assert.equal(state.stops.length, 0);
  coming.x = 30;
  dispatch.enforce();
  assert.deepEqual(state.stops, [coming]);
});

test('a stop that falls through lets the driver go without a fine', () => {
  const car = speeder();
  const { dispatch, state, trap } = fixture({ speeders: [{ car, kmh: 95, posted: 60 }] });
  dispatch.enforce();
  car.mode = 'wreck';
  assert.equal(trap.task.valid(), false);
  trap.task.onAbort();
  trap.task.onPointDone();
  assert.equal(state.tickets.length, 0);
  assert.deepEqual(state.released.map((r) => r.ticketed), [false]);
});

test('the player is fined when clocked over the limit, at most once per pass', () => {
  const { dispatch, state, world } = fixture({ truckSpeed: 80 });
  dispatch.enforce();
  dispatch.enforce();
  assert.equal(state.clocked.length, 1);
  assert.equal(state.clocked[0].posted, 60);
  assert.equal(state.clocked[0].fine, limits.fineFor(limits.toKmh(80), 60));
  dispatch.time += 21;
  world.truck.speed = 50;
  dispatch.enforce();
  assert.equal(state.clocked.length, 1, 'under the radar limit');
  world.truck.plane = true;
  world.truck.speed = 200;
  dispatch.enforce();
  assert.equal(state.clocked.length, 1, 'the A-10 is not clocked');
});

test('speed traps only go out in a quiet city, with police to spare, away from family turf', () => {
  const { dispatch, world } = fixture();
  world.services.vehicles.length = 0;
  assert.equal(dispatch.police().length, 1);
  assert.equal(dispatch.police()[0].task.stop, 'trap');
  assert.equal(dispatch.police()[0].quiet, true);
  world.services.available = () => 1;
  assert.equal(dispatch.police().length, 0, 'keep a unit back for emergencies');
  world.services.available = () => 3;
  world.inTurf = () => true;
  assert.equal(dispatch.police().length, 0, 'not in family turf');
  world.inTurf = () => false;
  dispatch.incidents.push({ x: 900, y: 0, r: 60, layer: 0, stage: 'respond', born: 0, stageAt: 0 });
  assert.deepEqual(dispatch.police().map((j) => j.task.stop ?? 'scene'), ['scene'], 'scenes first');
});