EDuke32 compiled to WebAssembly with Emscripten
EDuke32 compiled to WebAssembly with Emscripten: the classic 8-bit software renderer running in a browser via Asyncify, no plugins. Single-player. The engine diff is ~60 lines across five files, all behind #ifdef __EMSCRIPTEN__; native builds are unchanged. Nothing is stubbed and ENet is untouched.
What changed
- build:
build_wasm.sh: SDL2 software renderer, no OpenGL,-sASYNCIFYso the existing blocking main loop runs in the browser. - timer:
#undef CLOCK_MONOTONIC_RAW: Emscripten'sclock_gettimedoesn't implement it, which froze the engine clock. - compat / sdlayer: skip
getpwuidand<execinfo.h>: undeclared/absent under emscripten, so they broke the build. - sdlayer: clamp a non-positive display refresh rate: the browser reports 0, which made
engineFPSLimit()busy-spin and hang the page. - sdlayer: two
emscripten_sleepyields (event pump + frame present) so the blocking loop cooperates with the browser; without them it freezes / stays black. - config: default to windowed: a fullscreen default requests the HTML5 Fullscreen API, which needs a user gesture, so the canvas stays black until then.
- premap: throttle the precache event pump: each poll is an Asyncify stack unwind (E1L1 load ~9 s → under a second).
- web: a minimal static page (
webhost/index.html) that mounts a GRP, takes the render resolution from the window size, unlocks Web Audio on first click, fills the window, and re-renders on resize via the engine's normal SDL path.
How to test
Needs the Emscripten SDK (built and tested with emcc 5.0.7). Then:
LINK=1 ./build_wasm.sh # -> webhost/eduke32.{js,wasm}
cp DUKE3D.GRP webhost/ # the shareware GRP works
cd webhost && python3 -m http.serverOr build with no local toolchain, using the official Emscripten image:
docker run --rm -e LINK=1 -v "$PWD":/src -w /src emscripten/emsdk ./build_wasm.shThen serve webhost/ (e.g. python3 -m http.server) and open http://localhost:8000/. It boots through the logos and title to the menu; New Game runs E1L1 with keyboard + click-to-capture mouselook; OPL3 music and SFX play; resizing the window works.
Written with AI assistance (Claude); I've reviewed and tested all of it.