Run the original 1993 Doom (shareware) inside a secure-exec sandbox, rendered in your terminal using ANSI true-color and Unicode half-block characters.
The Doom engine (doomgeneric) is compiled
from C to WebAssembly using the same wasi-sdk toolchain the rest of the project
uses. No WASM-specific code — just a standard POSIX terminal backend.
- wasi-sdk built at
native/wasmvm/c/vendor/wasi-sdk/(make wasi-sdkinnative/wasmvm/c/) - Patched sysroot at
native/wasmvm/c/sysroot/(make sysrootinnative/wasmvm/c/) wasm-opt(binaryen) on PATH- A terminal with true-color support (most modern terminals)
make buildThis downloads the doomgeneric source and doom1.wad (shareware, freely
distributable by id Software), then compiles everything to a ~430KB WASM binary.
pnpm tsx src/index.ts| Key | Action |
|---|---|
| Arrow keys | Move / turn |
| W/A/S/D | Move / strafe |
| F | Fire |
| Space | Open / use |
| R | Run |
| , / . | Strafe L / R |
| Enter | Menu select |
| Esc | Menu |
| 1-7 | Switch weapon |
| Q / Ctrl+C | Quit |
-
C backend (
c/doomgeneric_terminal.c) implements 5 callbacks:DG_DrawFrame()— converts BGRA framebuffer → ANSI half-block outputDG_GetKey()— reads keypresses viapoll()+read()on stdinDG_GetTicksMs()/DG_SleepMs()—clock_gettime/nanosleepDG_Init()— switches to alternate screen buffer
-
Makefile compiles doomgeneric + our backend →
build/doom(WASM) -
Node.js runner (
src/index.ts) creates a kernel, loadsdoom1.wadinto the virtual filesystem, mounts the WASM runtime, and spawns doom viakernel.spawn()with raw stdin/stdout forwarding