frogger
frogger · gamesInteractive Frogger game module (clean-room TypeScript port of Adrian Eyre's React Frogger, MIT-licensed). FULL CV-gate control with NO keyboard exposure on the module: five gate inputs (up_gate / down_gate / left_gate / right_gate / start_gate) are rising-edge triggered to play the game. The start_gate auto-fires once on module-spawn (a synthesized first-tick rising edge) so the user sees a running game by default — the upstream React app's pre-game InfoBoard ("click Start Game") is bypassed via this synthetic pulse. The same start_gate is rising-edge triggered by external CV to restart at any time. Three gate outputs fire one 5 ms pulse per event: home_gate (a frog reached one of the 5 home slots — fires up to 5 times per level), dead_gate (frog hit a vehicle, fell in water without a raft, or the per-level timer ran out), level_gate (all 5 homes filled — level complete). One knob: TIME (10..120 s, default 60) sets the per-life timer ceiling, and it applies to the RUNNING game — lowering it clamps the life already in progress, raising it takes effect on the next life. Game logic runs at visual cadence on the main thread (no audio worklet); pure deterministic state stepper in frogger-state.ts with NO RNG anywhere, so the board is a pure function of tick count. The 14×13 grid renders at the head of the module's dock faceplate and on the legacy card. See docs/design/game-modules.md for the multi-user follow-up path.
the faceplate
inputs
| id | cable | what it does |
|---|---|---|
up_gate | gate | Move the frog UP one row on each rising edge — one hop toward the home pads per pulse (the move only fires on the gate's leading edge, so a held-high gate hops once, not continuously). gate / trigger; trigger — fires once per rising edge |
down_gate | gate | Move the frog DOWN one row on each rising edge — one hop back toward the start bank per pulse. gate / trigger; trigger — fires once per rising edge |
left_gate | gate | Move the frog LEFT one column on each rising edge — one hop per pulse. gate / trigger; trigger — fires once per rising edge |
right_gate | gate | Move the frog RIGHT one column on each rising edge — one hop per pulse. gate / trigger; trigger — fires once per rising edge |
start_gate | gate | Start a fresh game on each rising edge — resets the board, lives, score and timer and begins a new run. One synthetic pulse is auto-fired the first time the module is placed (so a game is already running by default); after that, pulse this to restart at any time (e.g. wire DEAD or LEVEL back here for an endless self-restarting loop). gate / trigger; trigger — fires once per rising edge |
outputs
| id | cable | what it does |
|---|---|---|
home_gate | gate | Fires a 5 ms pulse each time the frog reaches a home pad — if a single move scores more than one home (e.g. the last pad completing a level), it emits that many distinct staggered pulses so a downstream counter or envelope sees each one. Patch into a drum/envelope trigger to sonify successful crossings. gate / trigger; trigger — fires once per rising edge |
dead_gate | gate | Fires a single 5 ms pulse each time the frog dies (hit by traffic, drowned in the river, or the life timer expired). A trigger you can route to a crash sound, a sample, or back into START for auto-restart. gate / trigger; trigger — fires once per rising edge |
level_gate | gate | Fires a single 5 ms pulse each time a level is cleared (all five home pads filled). Use it as a progression trigger — bump a sequence, change a scene, or fire a fanfare. gate / trigger; trigger — fires once per rising edge |
params
| id | label | range | default | curve |
|---|---|---|---|---|
initialTime | Time | 10..120 | — | linear |
controls
| control | what it does |
|---|---|
| Time | The per-life countdown ceiling in seconds (10..120, default 60) — how long the frog has before the timer runs out and DEAD fires. Lower it for a frantic game (faster death pulses), raise it for a relaxed run. It applies to the RUNNING game: lowering it clamps the life already in progress down to the new ceiling straight away, while raising it takes effect on the next life rather than extending a countdown under you. Clearing a level still costs 5 s of ceiling (floored at 10 s), and that difficulty ramp is measured from wherever you have since moved this knob to. MIDI-learnable. |
source
frogger.ts on GitHub.