Skip to content
Home/Projects/Rolling Thunder

WebAssembly emulation Live

Rolling Thunder. Namco, 1986, in a tab.

MAME 0.277's Namco System 86 driver, compiled to WebAssembly with Emscripten on my own machine. Exact ROM match, real save states, the Tab menu, DIP switches — the whole cabinet, minus the coin slot and the carpet that arcade carpet is famous for. A browser build of the 1986 arcade title, running the reference MAME driver compiled to WebAssembly. No plugins, no ads, no external services.

First load pulls a ~56 MB WebAssembly core — it's a whole arcade emulator, not a thumbnail. Be patient once.

Controls

Keyboard, obviously.

ActionKeys
Move / aimArrow keys, or W A S D
Shot (button 1)Ctrl, J or Z
Button 2Alt, K or X
Insert coin5 — yes, actually press it
Start1
Player 2I J K U + F / G
MAME menu (DIPs, graphics)Tab

The 5 key is the one people miss. The cabinet wants a coin; the cabinet always wins.

Build notes

What's actually running.

  • Driver: src/mame/namco/namcos86.cpp, machine rthunder — “Rolling Thunder (rev 3)”.
  • Emulator: MAME 0.277, compiled to WebAssembly with Emscripten — not a reimplementation, not a JS port.
  • ROM set: all 28 files verified byte-for-byte and CRC-for-CRC against MAME master's ROM_START(rthunder).
  • Runtime: ROM mounted into the in-memory filesystem at boot; save states, NVRAM and F12 screenshots all work.
  • Single-threaded on purpose — no cross-origin isolation headers needed, so it runs on plain static hosting.
[i]
Why this exists: it's the same muscle as the day job — take something complicated and opaque, compile it down until you can observe it, and make the numbers legible. One of those numbers is a high score.

Where the 56 MB lives

In this repo. On purpose.

The whole build — the 56 MB WebAssembly core, the ROM set and the EmulatorJS fallback — is committed under projects/rthunder/play/assets/, so the play page is self-contained: GitHub Pages, a laptop, a phone on the LAN — any static server that sends the right MIME for .wasm will do. The page still resolves its assets at boot and verifies each file by CRC32 before it will boot it.

  1. Ships with the site — play/assets/ is committed; a first visit pulls the core once, after that it is just the browser cache.
  2. Re-staging (after a rebuild) — point the packer at a build and commit the result:
    node scripts/package-rthunder.mjs --install-local --src D:\work\rthunder\app
    then node serve.mjs and open the game.
  3. Separate origin (optional) — publish dist/rthunder-build/ anywhere that sends Access-Control-Allow-Origin: *, and set RT_REMOTE_BASE at the top of play/index.html to test it:
    node scripts/package-rthunder.mjs
[!]
The ROM is not mine. The emulator is; the arcade ROM's copyright belongs to its owner. The full set is provided here so the project actually runs for anyone who opens the site — every file is CRC-verified against MAME's ROM_START(rthunder) at boot, so a truncated download refuses to start instead of showing a black canvas.
[i]
?remote=1 skips the local probe; ?sdlsoft=1 drops to SDL's software renderer if your GPU driver is being creative. Diagnostics for a man who shipped an emulator and wants to know why it didn't start.

Direct link to the game → · fullscreen, sound on.
Build notes — how MAME got compiled (markdown) →

[→]
Back to the projects menu, where there is also a spreadsheet about dragons.