Skip to content

Repository files navigation

warp.parts

A browser front-end for LEGO® Racers (1999), running the racers-portable engine reimplementation compiled to WebAssembly. It's a splash-screen launcher — Run Game, Configuration, Read Me — in the spirit of isle.pizza.

How it works

  • Svelte 5 + Vite 8 single-page app; no backend.
  • The game itself is the Emscripten build of racers-portable (LEGORacers.js + LEGORacers.wasm). The loader is injected only when you press Run Game, after the chosen settings are turned into command-line arguments — LEGO Racers has no config file, so every setting is an argv flag.
  • The original game data (LEGO.JAM, *.tun music, intro movies) is streamed over HTTP from /racers/ through WebAssembly's fetch filesystem using Range requests.
  • A Workbox service worker precaches the app shell and can install the game data for offline play.

Because the game uses WebAssembly threads / SharedArrayBuffer, the site must be served cross-origin isolated:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Requirements

  • Node.js 20+
  • A built racers-portable web target — LEGORacers.js / LEGORacers.wasm
  • An original LEGO Racers install (for the /racers/ game data)

Development

npm install
npm run prepare:assets   # symlink LEGORacers.js/.wasm from the racers-portable web build
npm run dev              # http://localhost:5173
  • npm run prepare:assets links the binaries from RACERS_BUILD_WEB (default ../racers-portable/build-web).
  • The dev/preview server streams the game data from RACERS_DATA_DIR (default /Users/foxtacles/Projects/LEGO Racers) with Range support + the isolation headers above.

Scripts:

Script Purpose
npm run dev Vite dev server. Service worker is off (offline install shows a note).
npm run build Production build into dist/ (copies the binaries in, injects the Workbox manifest).
npm run preview Serve the production build — service worker on, so test offline play here.
npm run check svelte-check (0 warnings enforced).

Configuration → launch arguments

Settings from the Configuration screen are stored in localStorage and translated to Module.arguments at launch (src/core/config.js):

Setting Argument
Aspect ratio --scale letterbox | --scale stretch
Render resolution --resolution native | --resolution original
Skip intro videos -novideo

Fullscreen is a live browser toggle (not persisted). Language is selected in-game. --renderer is intentionally omitted — the web build has a single WebGL2 backend.

Deployment

dist/ is uploaded to a Cloudflare R2 bucket (racers) with wrangler (scripts/deploy.sh):

npx wrangler login       # once
npm run deploy:assets    # first deploy — code + images/audio/pdf/workbox
npm run deploy           # later deploys — code only

The game data (/racers/*) is hosted separately. Whatever Cloudflare edge serves the bucket must add the cross-origin-isolation headers above and serve HTTP Range for the game data. Override the bucket with R2_BUCKET.

Layout

src/
  main.js            Emscripten Module bootstrap + Svelte mount
  App.svelte         shell (pages, popups, canvas, footer)
  stores.js          Svelte stores
  app.css            global styles / design tokens
  core/              emscripten launch, config→argv, audio, service worker, routing
  lib/               UI components (menu, config, read-me, popups, LEGO-brick buttons)
src-sw/sw.js         service worker (Workbox precache + Range-cache for /racers/)
scripts/             prepare (symlinks), workbox-inject, deploy

About

Custom frontend for the Emscripten port of racers-portable

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages