Browser-based engine simulator with realistic drivetrain physics, layered audio synthesis, turbocharger model, and a manual clutch transmission. Runs on desktop and mobile.
- Drivetrain physics — torque curve interpolation, constant-power throttle model (BeamNG-style), angular acceleration, rev limiter with tight fuel-cut hysteresis. Honda S2000 AP1 gearbox. Engine allows over-rev past redline (no damage modeled).
- Manual clutch — hold Shift/C to decouple engine from wheels. Shift gears while clutch is held, release to feel spring-damper engagement. Clutchless shifts also work for convenience (auto-engages spring-damper).
- Spring-damper clutch engagement — replaces instant RPM snap with torsional spring-damper coupling engine and wheel inertias. Oscillation frequency and damping emerge from physics per gear.
- Turbocharger — BeamNG-style exhaust energy model with spool lag, wastegate, compressor back-pressure, and blow-off valve. Boost adds torque proportional to manifold pressure.
- 13-layer engine audio — Web Audio API with frequency-band samples (low/mid/high) crossfading by RPM and throttle. Separate on/off-throttle sample sets, REV redline loop, limiter gated loop, transmission whine, 4-band decel layers, and synthesized shift thuds.
- Exhaust convolution reverb — procedurally generated impulse response from pipe geometry via ConvolverNode. Equal-power dry/wet crossfade.
- Per-cylinder variation — subtle timing jitter (±8%) and brightness/detune offsets per cylinder break mechanical perfection in both audio and visuals.
- Idle realism — idle air control holds RPM near 850, per-cylinder firing pulses add ±15 RPM flutter at ~14 Hz. Not a perfect flat line.
- Continuous throttle — 0–1 pedal position from keyboard (space = WOT), mouse drag, touch Y-position, or gamepad right trigger. Partial throttle blends on/off samples with volume scaling.
- Analog tachometer — DPR-aware canvas gauge with needle smoothing, redline arc, and glow. Responsive via ResizeObserver.
- Cylinder visualization — SVG cylinder bank with firing-order animations, per-cylinder brightness variation, and throttle-colored fills (orange = power, blue = engine braking). Supports inline-4, inline-6, and V6.
- Color token system — all colors in
tokens.js+ CSS custom properties. Canvas/SVG code imports JS tokens; stylesheets usevar(--c-*). - Responsive layout — works on desktop and mobile. Touch devices get on-screen clutch/shift/brake buttons and Y-axis throttle.
- Debug overlay — real-time bars for RPM (red on over-rev), speed, torque, throttle, boost, inertia, detune, clutch/engagement status, turbo spool, BOV, oscillation, audio band gains, and frame timing sparkline. Toggle with backtick.
| Input | Action |
|---|---|
| Space | Full throttle (WOT) |
| Click + drag up | Proportional throttle (mouse Y) |
| Touch drag up | Proportional throttle |
| Shift / C | Clutch (hold to decouple, shift, release to engage) |
| Arrow Up / Down | Shift up / down (works with or without clutch) |
| S or B | Brake |
| Backtick (`) | Toggle debug overlay |
| Gamepad RT / LT | Throttle / brake |
| Gamepad LB | Clutch |
| Gamepad RB | Shift up |
| Gamepad Dpad Down | Shift down |
| Touch CLT | Clutch button |
| Touch BRK | Brake button |
npm install
npm run devOpen http://localhost:5173. Choose cylinder count and layout, then START ENGINE.
- Svelte 5 with runes (
$state,$derived,$effect,$props) - Vite 6 + Cloudflare Vite Plugin
- Web Audio API (AudioContext, ConvolverNode, OscillatorNode)
- Canvas API / SVG
- Vitest for testing
- Cloudflare Workers for hosting (CD via GitHub Actions on tag push)
src/
├── App.svelte — screen router (customizer → sim), global CSS tokens
├── Customizer.svelte — engine config picker + audio loader
├── Sim.svelte — main loop, input handling (keyboard/mouse/touch/gamepad)
├── Tachometer.svelte — DPR-aware canvas analog gauge
├── CylinderBank.svelte — SVG cylinder bank with firing-order animation
├── GearIndicator.svelte — gear letter + speed display
├── Odometer.svelte — distance counter (localStorage persistence)
├── DebugOverlay.svelte — debug panel with bars, sparkline, status pills
├── engine/
│ ├── constants.js — RPM limits, normalizeRPM()
│ ├── drivetrain.js — physics: torque, gears, clutch, turbo, spring-damper
│ ├── audio.js — 13-layer Web Audio engine + exhaust reverb + turbo whine
│ └── tokens.js — color token system (JS exports + CSS vars)
│ └── __tests__/ — vitest test suites
└── main.js — Svelte mount point