gibribbon

gibribbon · sources

GIBRIBBON (video) — an AUDIO-DRIVEN rhythm line-runner in the spirit of Vib-Ribbon, cast with DOOM shareware sprites as fair-use artistic parody (owner-ruled rewrite 2026-08-28; audio-in redirect 2026-08-29). Like the original game — which analyses the music (any CD the player inserts) and builds its course from interesting frequency changes — the course derives from whatever is patched into AUDIO IN: the module's own analyser folds the signal into four musical bands (bass 20-200 / low-mid 200-1k / high-mid 1k-4k / treble 4k-16k Hz), and an ADAPTIVE extractor spawns events on relative peaks against each band's own rolling baseline, biased toward spectral-flux onsets — any source at any level plays, silence and stuck-flat signals spawn nothing, and there is no gain calibration anywhere in the path. THE BAND IS THE EVENT: bass=LOOP road dips (A), low-mid=JUMP humps (B), high-mid=IMP (X), treble=ZOMBIE (Y) — the low end shapes the road, the highs send the monsters (real TROO*/POSS* sprites when DOOM1.WAD is present, line-art otherwise; the marine is PLAY*). THE DAMAGE MODEL IS VIB-RIBBON'S: an uncleared event HITS the marine and degrades him one VISIBLE form down a DOOM ladder (the status-bar face mugshot grades from grin to bloodied; the line-art figure loses limbs), like Vibri degrading rabbit-to-frog-to-insect; hits at the floor are GAME OVER (evt_gameover pulses; the restart gate / R key / RESET revives); streaks heal and a long streak reaches gold SUPER. One clock: the internal TEMPO transport paces the ribbon while the audio decides what spawns; judgement is phase-anchored to it. An idle unpatched module self-plays in labelled ATTRACT (its bot deliberately fumbles so the ladder shows); any input — buttons, keyboard, or MOVING audio — starts a real run. Outputs: out (video), evt_hit/miss/fire/kill/gameover (10 ms gates), health_cv. Pure deterministic engine (gibribbon-engine.ts) + pure spectral fold (gibribbon-spectral.ts); VRT-baselined via the __gibribbonVrtSeed/__gibribbonVrtTicks pins. DOOM shareware terms apply (same file as the DOOM module, read-only).

An audio-driven rhythm line-runner in the spirit of Vib-Ribbon, cast with DOOM shareware sprites as fair-use artistic parody. Like the original game — which analyses the music (any CD the player inserts), looks ahead, and builds its obstacle course from interesting frequency changes — GIBRIBBON derives its course FROM THE SIGNAL you patch into AUDIO IN: the module's own analyser folds the input into four musical bands (bass 20-200 Hz, low-mid 200-1k, high-mid 1k-4k, treble 4k-16k), and an ADAPTIVE extractor spawns events on relative peaks against each band's own recent baseline, preferring spectral-flux onsets (the beat). Because prominence is relative, ANY source at ANY level plays — a quiet field recording and a hot drum bus alike — and silence or a stuck-flat signal spawns nothing. THE BAND IS THE EVENT: the low end shapes the ROAD (bass = LOOP pit-V dips, low-mid = JUMP humps) and the highs send the MONSTERS (high-mid = imps, treble = zombies/former-humans, rendered as real DOOM sprites when DOOM1.WAD is present, wireframe line-art otherwise). Clear each event with its ABXY button (loop=A, jump=B, imp=X, zombie=Y) inside the timing window as it reaches the marine; a ~2-bar lookahead lane names the next buttons. THE DAMAGE MODEL IS VIB-RIBBON'S: an event you fail to clear HITS the marine and degrades him one visible form down a DOOM ladder (the status-bar face grades from grinning to bloodied), like Vibri degrading rabbit-to-frog-to-insect; hits at the floor are GAME OVER; clean streaks heal forms back and a long streak reaches gold SUPER. Restart from the restart gate, the R key, or the RESET action — wire evt_gameover back to restart for an endless arcade loop. TEMPO sets the ribbon's course rate (the audio decides WHAT spawns, tempo decides how fast it approaches); DIFFICULTY scales density and speed together. An idle, unpatched module self-plays in ATTRACT mode — honestly labelled IN the picture, and its demo bot fumbles now and then so you can see the damage ladder work; any input (a button, the keyboard, or MOVING audio arriving at AUDIO IN) starts a real run. Play it three ways: patch a gamepad module's a/b/x/y gates + lx/ly axes straight in, click the screen and use the keyboard (F/D/J/K or arrows, R = restart), or sequence the rack from the event gate outputs — the game is half a sequencer.

the faceplate

gibribbonaudio_inaudioxmodsignalymodsignalagatebgatex_btngatey_btngaterestartgateoutvideoevt_hitgateevt_missgateevt_firegateevt_killgateevt_gameovergatehealth_cvcvaudiocvgatepitch
8 inputs · 7 outputs · 10 params

inputs

idcablewhat it does
audio_inaudioTHE SOURCE. Patch any audio here — the whole course derives from it, like Vib-Ribbon generating stages from a music CD. The module's own AnalyserNode folds the signal into four musical bands (bass/low-mid/high-mid/treble) and spawns events on relative peaks against each band's own rolling baseline, biased toward spectral-flux onsets. Tap-only and inaudible: route the signal to AUDIO OUT separately to hear it. Moving audio also counts as player presence — it wakes the module out of ATTRACT into a live run.
audio signal
xmodsignalAim X (bipolar -1..1): re-centres the judgement point by up to one hit-window (stick left = clear events slightly early, right = slightly late). Shifts the window, never widens it. Modulates the X control.
modulation (CV / gate / audio); modulates axis_x (additive offset — ±1 CV sweeps the full range, centered on the knob)
ymodsignalAim Y (bipolar -1..1): raises the marine off the ribbon (up) or crouches it (down) — a visible aim aid consumed by the renderer. Modulates the Y control.
modulation (CV / gate / audio); modulates axis_y (additive offset — ±1 CV sweeps the full range, centered on the knob)
agateThe A play button (rising edge): judges the nearest in-window LOOP event at the tick-anchored phase of the press. Spare presses with no matching event are ignored (no penalty). Modulates the A control.
gate / trigger; modulates btn_a (summed directly (the destination DSP scales it)); trigger — fires once per rising edge
bgateThe B play button (rising edge): judges the nearest in-window JUMP event. Modulates the B control.
gate / trigger; modulates btn_b (summed directly (the destination DSP scales it)); trigger — fires once per rising edge
x_btngateThe X play button (rising edge): judges the nearest in-window IMP event. Named x_btn to disambiguate from the x AXIS port. Modulates the X (btn) control.
gate / trigger; modulates btn_x (summed directly (the destination DSP scales it)); trigger — fires once per rising edge
y_btngateThe Y play button (rising edge): judges the nearest in-window ZOMBIE event. Named y_btn to disambiguate from the y AXIS port. Modulates the Y (btn) control.
gate / trigger; modulates btn_y (summed directly (the destination DSP scales it)); trigger — fires once per rising edge
restartgateRestart gate (rising edge): starts a fresh run — from GAME OVER or as a hard reset mid-run — so a rack can loop the game (wire evt_gameover back here through a delay for an endless arcade). Same path as the R key and the RESET action. Modulates the RESTART control.
gate / trigger; modulates restart_btn (summed directly (the destination DSP scales it)); trigger — fires once per rising edge

outputs

idcablewhat it does
outvideoThe rendered game frame (video): the 16:9 ribbon scene — course, sprites, the DOOM status-bar face showing the marine's current form, and the in-canvas HUD (score, combo, ATTRACT label, count-in, GAME OVER banner) — letterboxed into the engine's 4:3 output.
RGB video stream
evt_hitgateA ~10 ms gate pulse on every successful clear (any in-window button match). In ATTRACT mode the self-player keeps firing these — the sequencer half of the module stays alive while idle.
gate / trigger; trigger — fires once per rising edge
evt_missgateA ~10 ms gate pulse every time an uncleared event HITS the marine (it reached him without the right press), as he degrades a visible form down the ladder.
gate / trigger; trigger — fires once per rising edge
evt_firegateA ~10 ms gate pulse when the marine FIRES — emitted on a successful enemy (imp/zombie) clear.
gate / trigger; trigger — fires once per rising edge
evt_killgateA ~10 ms gate pulse when an enemy DIES (its death animation), emitted alongside evt_fire on an enemy clear.
gate / trigger; trigger — fires once per rising edge
evt_gameovergateA ~10 ms gate pulse fired once when the marine's form degrades past the floor — GAME OVER (Vibri hit once too often as an insect).
gate / trigger; trigger — fires once per rising edge
health_cvcvThe marine's vitality as a 0..1 CV (super=1, healthy=0.75, wounded=0.5, critical=0.25, dead=0), ramped smoothly on each form change.
control voltage (CV)

params

idlabelrangedefaultcurve
axis_xX-1..10linear
axis_yY-1..10linear
btn_aA0..10linear
btn_bB0..10linear
btn_xX (btn)0..10linear
btn_yY (btn)0..10linear
restart_btnRESTART0..10linear
autoplayAttract0..11discrete
difficultyDifficulty0..10.5linear
tempoTempo60..180log

controls

controlwhat it does
AttractATTRACT toggle (0/1, default 1 = ON). The id says autoplay for historical continuity; the behaviour is ATTRACT MODE: when ON, an IDLE and unpatched module self-plays a labelled attract run through the real extractor and judge (its demo bot deliberately fumbles some events so the damage ladder shows), and any real input — a button, the keyboard, or moving audio at AUDIO IN — starts a fresh live run. Set 0 and the module never self-plays; an idle ribbon stays honestly empty.
XThe aim-X value (-1..1, default 0) re-centring the judgement window; written by the X axis jack.
YThe aim-Y value (-1..1, default 0) raising/crouching the marine; written by the Y axis jack.
AThe A-button level (0..1); a rising edge judges the nearest in-window loop event. Written by the A jack (or keyboard F / left-arrow).
BThe B-button level (0..1); a rising edge judges the nearest in-window jump event. Written by the B jack (or keyboard D / down-arrow).
X (btn)The X-button level (0..1); a rising edge judges the nearest in-window imp event. Written by the x_btn jack (or keyboard J / right-arrow).
Y (btn)The Y-button level (0..1); a rising edge judges the nearest in-window zombie event. Written by the y_btn jack (or keyboard K / up-arrow).
DifficultyThe one game knob (0..1, default 0.5): scales course density (extraction bar + spawn-rate cap) and the course rate together. Low = sparse and readable; high = dense and fast.
RESTARTThe restart level (0..1); a rising edge starts a fresh run (from game over, or hard reset mid-run). Written by the restart jack (or keyboard R / the RESET action).
TempoThe ribbon's course rate (60..180 BPM-equivalent, default ~143 = the classic 0.42 s beat). The audio decides WHAT spawns; TEMPO decides how fast the course approaches. One clock: judgement is anchored to this transport's tick phase.

source

gibribbon.ts on GitHub.

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