DOOM — multiplayer

doom · video · up to 4 players, co-op netgame

The DOOM module runs the shareware game in WebAssembly, one independent instance per peer. Only the rack owner can add the DOOM widget — it's a host-driven module. The owner starts a multiplayer game; every other person in the rackspace then sees the same card and can join it with one click. Each peer renders its own first-person view, and every player's marine appears in every other peer's world. Up to 4 players (one shared DOOM card, one runtime per peer).

Owner-only widget

DOOM can only be added by the rack owner. Guests won't find it in the add-module palette — there is exactly one shared DOOM card per rack, and the owner is its host (Player 1). This keeps the flow simple: the owner sets up the game, everyone else joins it.

Start a multiplayer game (owner)

The owner is the host / arbiter (Player 1) and drives the game start:

  1. Add a DOOM module to the canvas and click the card to load the game (the shareware WAD downloads once, then caches locally).
  2. Click Host Multiplayer, then open New Game and pick mode (co-op), skill, episode, and map.
  3. Hit Launch. You enter the level, and the game is now live — that's the single gate. From this point, any guest's Join is always valid.

Only the owner sees the New Game dialog and the start choice (Single Player / Host Multiplayer). Single-player is owner-only too: a lone owner plays a normal single-player game with no netcode. Mode, WAD, and skill are locked while a level runs — changing them means ending the current game.

Join (one-click hot-join)

Guests see the DOOM card with a Join button. It stays disabled — reading "Waiting for host to start a multiplayer game…" — until the owner is actually running a live multiplayer game. The moment the owner is in-level, your Join button enables and a single click drops you straight into the running level with your own first-person view. No second host action is needed.

The arbiter assigns you the next free player slot (Player 1 → 4, in order). You don't pick a slot — the arbiter assigns it deterministically so two simultaneous joins can't collide.

How the hot-join works

DOOM has no true mid-level join: the original netgame fixes the player set when the level starts (G_InitNew spawns one marine per active slot, and the lockstep tic stream assumes a constant playeringame[]). So spawning a new marine into an already-running level mid-tic isn't possible.

We get the same outcome the pragmatic way: when you click the enabled Join, the arbiter seats you as an active player and automatically re-launches the current map (same skill, episode, and map — only the player count grows). Every peer reloads the level via G_InitNew, so you drop into the current map at your coop start within a second or two — a brief reload blip, not a wait for the next map, and not a separate host step. This works for anon invite-link guests too: once the owner's game is live, any guest's one click is a hot-join.

Player colors

Each player slot gets a fixed color — the vanilla DOOM marine palette — used for the card's slot badge ("P1".."P4"), the header tint, and the in-game marine sprite. Slots are 1-based in the UI ("Player 1" = slot 0).

SlotPlayerColorSwatch
0Player 1Green #3fa34d
1Player 2Indigo #5b5bd6
2Player 3Brown #8a5a2b
3Player 4Red #c2342b

Controls

Click the card to give it keyboard focus, then play. Keys are released automatically when the card loses focus or the tab is hidden (no stuck movement).

KeyAction
Arrow Up / DownMove forward / backward
Arrow Left / RightTurn left / right
CtrlFire
SpaceUse / open doors / flip switches
1 – 7Select weapon

Cheats — IDDQD / IDKFA gate inputs

The DOOM card carries two extra gate inputs in the patch panel under a Cheats section:

  • IDDQD — god mode. A rising edge synthesises the iddqd keypress sequence into the WASM key queue; DOOM's cheat parser flips the local player's god-mode flag on the 5th character.
  • IDKFA — all keys, all weapons, full ammo. Same rising-edge semantics, types idkfa into the engine.

Both gates are one-shot: holding the gate HIGH does not re-trigger; the gate must return LOW and rise again to re-fire. The injection takes about 250 ms per cheat (50 ms per character × 5), so the effect lands within ~500 ms of the rising edge. Cheats act on the local player only (same scope as if you'd typed them on a focused card) — they aren't replicated across peers.

Notes

  • Only the rack owner can add DOOM — one shared card per rack.
  • A guest's Join is disabled until the owner is running a live multiplayer game; then it's a one-click hot-join into the running level.
  • A player who closes their tab or leaves mid-level vanishes from the game (vanilla DOOM behavior); the arbiter frees their slot for the next joiner.
  • Single player is owner-only: a lone owner plays a normal single-player game with no netcode involved. Guests never get a single-player path.
  • No save/load in multiplayer, matching the original game.
Generated from packages/web/src/lib/{audio,video}/module-registry.ts · repo