doom.wasm
doom as a simple WebAssembly module

Doom is infamous for how easily portable it is. But can we port Doom to WebAssembly?

Of course we can! And we would not be the first to do this, by far (e.g. 1, 2, 3, 4, 5, 6).

But!

What if our goal wasn’t just to port Doom to WebAssembly, but instead to port Doom to WebAssembly in a way that empowers developers to make use of our work? What if our goal was to produce a Doom WebAssembly module that is super easy to reuse?

This is what I had in mind with doom.wasm.

The output of that project isn’t just an demo of running Doom in the browser (although, it has that too! here, and embedded at the bottom of this page).

The output of doom.wasm is an artifact that can be reused to easily run Doom on any WebAssembly runtime, and the project includes examples of doing just that in both C, Python, and (previously mentioned) in the browser via JavaScript.

This project accomplishes this by caring a lot about the WebAssembly interface exposed by doom.wasm. The imports and exports of doom.wasm have been curated to maximize usability while supporting as many features of Doom as possible (e.g. supporting the loading of custom Doom WADs).

You can find the latest release of doom.wasm here. There you’ll also find a quick glance at the small set of imports and exports of doom.wasm, along with links to documentation of these features, and general advice on how to leverage this WebAssembly module.

Also, here you’ll find a comparison on how doom.wasm measures up in usability against many other existing “Doom ported to WebAssembly” projects (summary: doom.wasm has around 75% less imports and exports than any of them).

And here, via doom.wasm, you can play the first episode of Doom, compliments of the Doom Shareware WAD (game controls are the same keyboard controls present in vanilla Doom, detailed here):

I’m hoping doom.wasm makes Doom even more accessible and portable, empowering others to do new or unusual things with Doom, like:

  • Use snapshotting of the WebAssembly instance to support rewinding of time in Doom
  • Run Doom entirely via the terminal
  • Use Doom to benchmark different WebAssembly runtimes
  • Make it so the passage of time in Doom is not constant
    • Maybe time constantly speeds up while the player has any keys pressed, and slows down otherwise?
  • Control Doom via unorthodox input devices
  • Perform interesting post-processing on the frames of Doom
    • E.g. enhance differences between the frames like here
  • … and so many other things I haven’t dreamed of!