doom singleton

doom · sources · schema v2

DOOM runs the 1993 shareware game compiled to WebAssembly (doomgeneric) and renders each peer's OWN first-person view to the video 'out' jack, with the WASM SFX mixer bridged to stereo audio outputs. It is a host-only, single-node module (maxInstances 1, ownerOnly): the rack owner adds one DOOM card, clicks the surface to download/cache the ~4 MB shareware WAD and boot the WASM, then either plays solo or hosts a true-lockstep co-op netgame that up to 3 rack-mates one-click hot-join (4 marines total — the owner is player 1) — every peer runs its own runtime and the deterministic tic stream keeps all marines byte-identical. Play with the keyboard once the card is focused (arrows move/turn, Ctrl/F fire, Space uses doors), or drive it from CV: the per-slot gate inputs p1..p4 act as held keypresses (movement/fire/strafe/menu) so an LFO, sequencer, or GAMEPAD can play the marine — each peer applies only its own seated slot's group (own-slot rule), and in single-player only the p1 group is live. Two extra cheat gates inject IDDQD (god mode) and IDKFA (full arsenal) on a rising edge. Game events feed the audio domain as 10 ms gate pulses — per-player weapon fire, door opens, the any-monster kill plus per-monster-type kills, and per-player deaths — so DOOM's action can trigger synths, drums, or a SCOREBOARD. The card's load button, the Single Player / Host Multiplayer start choice, the guest Join button, the click-to-capture-keyboard hint, and the arbiter's New Game dialog (mode/skill/episode/map custom dropdowns + a Launch / Next Map button) are UI controls, not patchable params. There is no host framebuffer mirror — an unjoined spectator simply shows the dark attract screen until it JOINS.

DOOM runs the 1993 shareware game compiled to WebAssembly (doomgeneric) and renders each peer's OWN first-person view to the video 'out' jack, with the WASM SFX mixer bridged to stereo audio outputs. It is a host-only, single-node module (maxInstances 1, ownerOnly): the rack owner adds one DOOM card, clicks the surface to download/cache the ~4 MB shareware WAD and boot the WASM, then either plays solo or hosts a true-lockstep co-op netgame that up to 3 rack-mates one-click hot-join (4 marines total — the owner is player 1) — every peer runs its own runtime and the deterministic tic stream keeps all marines byte-identical. Play with the keyboard once the card is focused (arrows move/turn, Ctrl/F fire, Space uses doors), or drive it from CV: the per-slot gate inputs p1..p4 act as held keypresses (movement/fire/strafe/menu) so an LFO, sequencer, or GAMEPAD can play the marine — each peer applies only its own seated slot's group (own-slot rule), and in single-player only the p1 group is live. Two extra cheat gates inject IDDQD (god mode) and IDKFA (full arsenal) on a rising edge. Game events feed the audio domain as 10 ms gate pulses — per-player weapon fire, door opens, the any-monster kill plus per-monster-type kills, and per-player deaths — so DOOM's action can trigger synths, drums, or a SCOREBOARD. The card's load button, the Single Player / Host Multiplayer start choice, the guest Join button, the click-to-capture-keyboard hint, and the arbiter's New Game dialog (mode/skill/episode/map custom dropdowns + a Launch / Next Map button) are UI controls, not patchable params. There is no host framebuffer mirror — an unjoined spectator simply shows the dark attract screen until it JOINS.

Full guide: DOOM multiplayer How the shared-rack DOOM netgame works — joining, the lockstep model, and its caveats.

the faceplate

doom · singletoniddqd_incvidkfa_incvoutvideoaudio_laudioaudio_raudioevt_killgateevt_doorgateevt_gun_p1gateevt_gun_p2gateevt_gun_p3gateevt_gun_p4gateaudiocvgatepitch
2 inputs · 9 outputs · 4 params

inputs

idcablewhat it does
iddqd_incvCheat gate (rising-edge trigger): a LOW->HIGH crossing injects the 'iddqd' keypress sequence into the WASM, flipping the local player's god-mode flag. One-shot — holding HIGH does not re-fire; the gate must fall and rise again.
control voltage (CV); modulates cv_iddqd_in (summed directly (the destination DSP scales it))
idkfa_incvCheat gate (rising-edge trigger): a LOW->HIGH crossing injects the 'idkfa' sequence (all keys, all weapons, full ammo) for the local player. One-shot per rising edge; not replicated to other peers.
control voltage (CV); modulates cv_idkfa_in (summed directly (the destination DSP scales it))

outputs

idcablewhat it does
outvideoVideo out: this peer's own first-person DOOM framebuffer (640x400 BGRA, swizzled BGRA->RGBA) letterboxed/pillarboxed into the engine's 4:3 FBO. Shows the dark attract screen until this peer loads or JOINS.
RGB video stream
audio_laudioLeft audio: the DOOM SFX/PCM mixer stream (mono internally, split to two channels) scaled by the Gain knob, bridged into the audio graph via the video->audio bridge.
audio signal
audio_raudioRight audio: the same DOOM PCM mixer stream as audio_l (duplicated channel) scaled by Gain, so downstream patches can route the two sides independently.
audio signal
evt_killgateAny-monster kill gate: a 10 ms HIGH pulse each time a counted monster dies, firing alongside the matching per-type kill gate.
gate / trigger
evt_doorgateDoor gate: a 10 ms HIGH pulse when a door opens (EV_DoDoor / EV_VerticalDoor).
gate / trigger
evt_gun_p1gateWeapon-fire gate for player 1: a 10 ms HIGH pulse each time slot 1 fires its weapon.
gate / trigger
evt_gun_p2gateWeapon-fire gate for player 2: a 10 ms HIGH pulse each time slot 2 fires its weapon.
gate / trigger
evt_gun_p3gateWeapon-fire gate for player 3: a 10 ms HIGH pulse each time slot 3 fires its weapon.
gate / trigger
evt_gun_p4gateWeapon-fire gate for player 4: a 10 ms HIGH pulse each time slot 4 fires its weapon.
gate / trigger

params

idlabelrangedefaultcurve
audioGainGain0..21linear
fillModeFill0..1discrete
cv_iddqd_inIDDQD0..10linear
cv_idkfa_inIDKFA0..10linear

controls

controlwhat it does
GainGain (0..2, linear, default 1): volume trim on the DOOM SFX -> audio_l/audio_r bus, on top of the worklet's fixed makeup gain. Rendered as the card's Volume knob and forwarded live to the PCM worklet on change.
IDDQDHidden synthetic param (label 'IDDQD') behind the iddqd_in cheat gate; a rising-edge setParam injects the 'iddqd' god-mode keypress sequence into the WASM. One-shot, hidden from the card.
IDKFAHidden synthetic param (label 'IDKFA') behind the idkfa_in cheat gate; a rising-edge setParam injects the 'idkfa' (all keys/weapons/ammo) keypress sequence. One-shot, hidden from the card.
Cv p1 altHidden synthetic param (label 'P1 ALT') behind the p1_alt gate input; edge-detected to press/release slot 1's strafe modifier. No card row.
Cv p1 ctrlHidden synthetic param (label 'P1 CTRL') behind the p1_ctrl gate input; edge-detected to press/release slot 1's FIRE key. No card row.
Cv p1 downHidden synthetic param (label 'P1 DOWN') behind the p1_down gate input; edge-detected to press/release slot 1's backward key. No card row.
Cv p1 enterHidden synthetic param (label 'P1 ENTER') behind the p1_enter gate input; edge-detected to press/release slot 1's ENTER key. No card row.
Cv p1 escHidden synthetic param (label 'P1 ESC') behind the p1_esc gate input; edge-detected to press/release slot 1's ESC (menu) key. No card row.
Cv p1 leftHidden synthetic param (label 'P1 LEFT') behind the p1_left gate input; edge-detected to press/release slot 1's turn-left key. No card row.
Cv p1 rightHidden synthetic param (label 'P1 RIGHT') behind the p1_right gate input; edge-detected to press/release slot 1's turn-right key. No card row.
Cv p1 spaceHidden synthetic param (label 'P1 SPACE') behind the p1_space gate input; edge-detected to press/release slot 1's USE key. No card row.
Cv p1 upHidden synthetic param (label 'P1 UP') behind the p1_up gate input; setParam values are hysteresis edge-detected to press/release slot 1's forward key. No card row.
Cv p2 altHidden synthetic param (label 'P2 ALT') behind the p2_alt gate input; edge-detected to press/release slot 2's strafe modifier. No card row.
Cv p2 ctrlHidden synthetic param (label 'P2 CTRL') behind the p2_ctrl gate input; edge-detected to press/release slot 2's FIRE key. No card row.
Cv p2 downHidden synthetic param (label 'P2 DOWN') behind the p2_down gate input; edge-detected to press/release slot 2's backward key. No card row.
Cv p2 enterHidden synthetic param (label 'P2 ENTER') behind the p2_enter gate input; edge-detected to press/release slot 2's ENTER key. No card row.
Cv p2 escHidden synthetic param (label 'P2 ESC') behind the p2_esc gate input; edge-detected to press/release slot 2's ESC (menu) key. No card row.
Cv p2 leftHidden synthetic param (label 'P2 LEFT') behind the p2_left gate input; edge-detected to press/release slot 2's turn-left key. No card row.
Cv p2 rightHidden synthetic param (label 'P2 RIGHT') behind the p2_right gate input; edge-detected to press/release slot 2's turn-right key. No card row.
Cv p2 spaceHidden synthetic param (label 'P2 SPACE') behind the p2_space gate input; edge-detected to press/release slot 2's USE key. No card row.
Cv p2 upHidden synthetic param (label 'P2 UP') behind the p2_up gate input; edge-detected to press/release slot 2's forward key. No card row.
Cv p3 altHidden synthetic param (label 'P3 ALT') behind the p3_alt gate input; edge-detected to press/release slot 3's strafe modifier. No card row.
Cv p3 ctrlHidden synthetic param (label 'P3 CTRL') behind the p3_ctrl gate input; edge-detected to press/release slot 3's FIRE key. No card row.
Cv p3 downHidden synthetic param (label 'P3 DOWN') behind the p3_down gate input; edge-detected to press/release slot 3's backward key. No card row.
Cv p3 enterHidden synthetic param (label 'P3 ENTER') behind the p3_enter gate input; edge-detected to press/release slot 3's ENTER key. No card row.
Cv p3 escHidden synthetic param (label 'P3 ESC') behind the p3_esc gate input; edge-detected to press/release slot 3's ESC (menu) key. No card row.
Cv p3 leftHidden synthetic param (label 'P3 LEFT') behind the p3_left gate input; edge-detected to press/release slot 3's turn-left key. No card row.
Cv p3 rightHidden synthetic param (label 'P3 RIGHT') behind the p3_right gate input; edge-detected to press/release slot 3's turn-right key. No card row.
Cv p3 spaceHidden synthetic param (label 'P3 SPACE') behind the p3_space gate input; edge-detected to press/release slot 3's USE key. No card row.
Cv p3 upHidden synthetic param (label 'P3 UP') behind the p3_up gate input; edge-detected to press/release slot 3's forward key. No card row.
Cv p4 altHidden synthetic param (label 'P4 ALT') behind the p4_alt gate input; edge-detected to press/release slot 4's strafe modifier. No card row.
Cv p4 ctrlHidden synthetic param (label 'P4 CTRL') behind the p4_ctrl gate input; edge-detected to press/release slot 4's FIRE key. No card row.
Cv p4 downHidden synthetic param (label 'P4 DOWN') behind the p4_down gate input; edge-detected to press/release slot 4's backward key. No card row.
Cv p4 enterHidden synthetic param (label 'P4 ENTER') behind the p4_enter gate input; edge-detected to press/release slot 4's ENTER key. No card row.
Cv p4 escHidden synthetic param (label 'P4 ESC') behind the p4_esc gate input; edge-detected to press/release slot 4's ESC (menu) key. No card row.
Cv p4 leftHidden synthetic param (label 'P4 LEFT') behind the p4_left gate input; edge-detected to press/release slot 4's turn-left key. No card row.
Cv p4 rightHidden synthetic param (label 'P4 RIGHT') behind the p4_right gate input; edge-detected to press/release slot 4's turn-right key. No card row.
Cv p4 spaceHidden synthetic param (label 'P4 SPACE') behind the p4_space gate input; edge-detected to press/release slot 4's USE key. No card row.
Cv p4 upHidden synthetic param (label 'P4 UP') behind the p4_up gate input; edge-detected to press/release slot 4's forward key. No card row.
FillFill (0..1, discrete, default 0): output aspect fit — 0 = letterbox/pillarbox preserving DOOM's native 8:5, 1 = fill (cover-crop). Rendered as the card's OUTPUT FIT toggle, not a knob.

source

doom.ts on GitHub.

Generated from packages/web/src/lib/{audio,video}/module-registry.ts · repo