doom singleton
doom · sources · schema v2DOOM 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
inputs
| id | cable | what it does |
|---|---|---|
iddqd_in | cv | Cheat 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_in | cv | Cheat 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
| id | cable | what it does |
|---|---|---|
out | video | Video 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_l | audio | Left 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_r | audio | Right 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_kill | gate | Any-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_door | gate | Door gate: a 10 ms HIGH pulse when a door opens (EV_DoDoor / EV_VerticalDoor). gate / trigger |
evt_gun_p1 | gate | Weapon-fire gate for player 1: a 10 ms HIGH pulse each time slot 1 fires its weapon. gate / trigger |
evt_gun_p2 | gate | Weapon-fire gate for player 2: a 10 ms HIGH pulse each time slot 2 fires its weapon. gate / trigger |
evt_gun_p3 | gate | Weapon-fire gate for player 3: a 10 ms HIGH pulse each time slot 3 fires its weapon. gate / trigger |
evt_gun_p4 | gate | Weapon-fire gate for player 4: a 10 ms HIGH pulse each time slot 4 fires its weapon. gate / trigger |
params
| id | label | range | default | curve |
|---|---|---|---|---|
audioGain | Gain | 0..2 | 1 | linear |
fillMode | Fill | 0..1 | — | discrete |
cv_iddqd_in | IDDQD | 0..1 | 0 | linear |
cv_idkfa_in | IDKFA | 0..1 | 0 | linear |
controls
| control | what it does |
|---|---|
| Gain | Gain (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. |
| IDDQD | Hidden 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. |
| IDKFA | Hidden 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 alt | Hidden 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 ctrl | Hidden 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 down | Hidden 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 enter | Hidden 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 esc | Hidden 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 left | Hidden 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 right | Hidden 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 space | Hidden 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 up | Hidden 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 alt | Hidden 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 ctrl | Hidden 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 down | Hidden 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 enter | Hidden 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 esc | Hidden 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 left | Hidden 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 right | Hidden 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 space | Hidden 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 up | Hidden 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 alt | Hidden 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 ctrl | Hidden 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 down | Hidden 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 enter | Hidden 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 esc | Hidden 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 left | Hidden 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 right | Hidden 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 space | Hidden 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 up | Hidden 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 alt | Hidden 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 ctrl | Hidden 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 down | Hidden 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 enter | Hidden 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 esc | Hidden 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 left | Hidden 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 right | Hidden 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 space | Hidden 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 up | Hidden synthetic param (label 'P4 UP') behind the p4_up gate input; edge-detected to press/release slot 4's forward key. No card row. |
| Fill | Fill (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.