Add-on Directory

Vaadoom - Vaadin Add-on Directory

DOOM in a Vaadin Flow component, running on a SUBLEQ virtual machine compiled to WebAssembly. Vaadoom - Vaadin Add-on Directory
DOOM rendered as a playable Vaadin Flow component. A NOMMU "Eternal" Linux runs fbdoom on Adrian Cable's single-instruction SUBLEQ virtual machine, compiled to WebAssembly and driven from a Web Worker that paints the framebuffer onto an OffscreenCanvas. The WAD is the constructor argument: new Vaadoom(Vaadoom.SHAREWARE_WAD) plays id Software's freely redistributable shareware episode, and any IWAD URL you host yourself plays that game — DOOM, The Ultimate DOOM, DOOM II and Final DOOM are told apart by their lump directory and served to DOOM under the name that selects the matching game mode. The file never passes through the emulated CPU: a host-file device copies it into guest RAM on demand, where a /dev/wad driver hands it to DOOM. Sound effects and music are both audible. Effects come from the guest's PCM sound card; the music is DOOM's own score played on an emulated OPL3 (Nuked-OPL3, LGPL-2.1) with eighteen voices and real double-voice instruments. Playback follows the emulator's clock rather than the sound card's: an audio worklet buffers and resamples each stream, because the virtual machine produces sound at roughly 97% of real time and anything consuming at exactly 100% drops out a few times a second. setSound(false) mutes everything, and setMusicGain(double) sets the music level against the effects. Click the viewport to play — arrows move, Ctrl fires, Space uses, Alt strafes, Shift runs, 1-7 pick weapons, Esc opens the menu, and F1-F12 work. Input is delivered without SharedArrayBuffer, so no COOP/COEP cross-origin-isolation headers are required. The engine and the compressed Linux+DOOM boot image ship inside the add-on JAR; first paint takes ~15 seconds behind a loading overlay.
View on GitHub
Online Demo

Vaadoom version 1.0.0
1.0.0 — playable DOOM. Fast minimal NOMMU WebAssembly engine (~2.7x faster; first paint ~15s), full keyboard control (movement, fire, strafe, run, weapons 1-7, Esc menu, Tab automap, F1-F12), doomguy-head icon, and complete third-party license notices. No cross-origin-isolation headers required.

Vaadoom version 1.1.0
**Play any WAD from a URL, and hear DOOM.** - The WAD is now the constructor argument: `new Vaadoom(url)`. Any IWAD works — DOOM, Ultimate DOOM, DOOM II, Final DOOM — identified from its lump directory and served under the name that selects the right game mode. Commercial IWADs are not freely redistributable, so host your own copy; only id Software's shareware episode is linked here. - Sound effects are audible, played through Web Audio from the guest's PCM sound card (~150 ms). `setSound(false)` mutes them. OPL3 music is driven by the guest but not yet synthesized. - A new host-file device streams the WAD into guest RAM on demand, so the emulated one-instruction CPU never copies it — a 14 MB IWAD is no trouble. - New boot image (modified kernel + fbdoom, corresponding source offered in THIRD_PARTY_NOTICES.md) whose init launches DOOM itself. - The no-argument constructor still plays the shareware WAD bundled in the image.

Vaadoom version 1.2.0
1.2.0 gives DOOM its sound. - Music, on an emulated OPL3 (Nuked-OPL3): eighteen voices, real double-voice instruments, and a sequencer that keeps time across a level load. - Sound effects from the guest's PCM sound card, mixed with the music under a limiter. - Playback follows the emulator's clock, not the sound card's. The VM produces sound at about 97% of real time, and anything consuming at exactly 100% drops out a few times a second; an audio worklet buffers and resamples each stream so it never gaps, degrading by playing slightly slow instead. No SharedArrayBuffer and no COOP/COEP needed. - setSound(boolean) and setMusicGain(double) control it. The WAD is still a URL given to the constructor. The demo plays id Software's freely redistributable shareware episode from the Internet Archive; an IWAD you own and host yourself plays the full game. Contains Nuked-OPL3 under LGPL-2.1 — see THIRD_PARTY_NOTICES.md in the archive.

Vaadoom version 1.2.1
1.2.1 - a song change no longer leaves a note hanging. A song change reaches the OPL device as a queue flush, and the device dropped the whole scheduled-write queue - including the key-offs the old song had already planned for the notes still sounding: 20 of them at the title screen to E1M1 switch. Those voices kept ringing (-16 to -24 dBFS, indefinitely), and later notes on the same channel no longer retriggered, because an OPL3 envelope needs a key-off first. Releasing the voices is not enough on its own: DOOM's GENMIDI bank contains instruments with a release rate of 1, which ring for tens of seconds after the key-off. The flush now pulls the release rate to 15 on those operators and puts the instrument's own rate back 50 ms later. Measured on the isolated tail, 8 s after the switch: -24.3 dBFS before, -75.1 dBFS now. Engine wasm only - the Linux+DOOM boot image is unchanged.