Debugging and panic recovery in Hydra
Learning objectives
- learner can recognise and fix the five silent-failure patterns in Hydra: missing `.out()`, bare reactive values, unclamped FFT reads, feedback gain at-or-above 1, and wrong output-buffer selection
- learner can trace any Hydra failure to one of two error surfaces — throw to `#err` or silent black/frozen/blown-out canvas — and choose the correct diagnostic step for each
- learner can work within the rig's 4-bin Strudel shim: tag patterns with `.analyze('hydra')`, stay within `a.fft[0..3]`, and substitute band thresholding for absent onset/RMS/centroid features
- learner can recover a crashed or blown-out sketch live using the panic-safe pattern, and explain why frame buffers survive across re-evals while JS state does not
Capstone — one whole task that evidences the objectives
Take a deliberately broken Hydra file seeded with one bug from each silent-failure class: (1) a chain that never renders because `.out()` is missing; (2) a reactive `a.fft` value baked in because its `() =>` thunk is missing; (3) a `src(o0)` feedback loop that whites out because gain is not contracted below 1; (4) an out-of-range `a.fft[5]` read returning NaN; (5) a Strudel voice missing its `.analyze('hydra')` tag so every bin reads zero; (6) a buffer object (`o0`/`s0`) chained bare instead of wrapped in `src(...)`; (7) a chain rendered to `o1` that never appears because `render(o1)` was not called; (8) a `.rotate().kaleid()` vs `.kaleid().rotate()` transform-order mistake; and (9) an array argument the author expected to ramp smoothly but that steps once per BPM cycle. Without looking up solutions, diagnose each failure using the two-surface model — check `#err` first, and where it is empty read the canvas (black / frozen / blown-out) and match it to its pattern class — then fix all nine bugs. Because the rig shim exposes no onset/RMS/centroid, add one audio-reactive element that derives a pseudo-onset from a threshold on `a.fft[0]`. Finally, from memory, write a panic sketch satisfying all four safety constraints (guaranteed `.out()`, every reactive value in a `() =>` thunk, FFT reads clamped to 0..3, non-zero base terms), and — leaning on the fact that re-eval runs `hush()` then re-evaluates the whole file on the same GL context so frame buffers survive — verify it recovers the canvas live in under five seconds. Deliver one annotated Hydra file naming, per bug, the error class and the canvas symptom that led you there, and labelling each panic-sketch line with the safety constraint it satisfies.
Prerequisite modules
This module is built around a single professional reality: in an algorave or club set, a Hydra crash does not give you a dialog box or a stack trace. It gives you a black screen, a frozen frame, or a canvas washed out to white — and an audience. The ability to read that canvas like a diagnostic display, trace the failure to its class, fix it in seconds, and keep the set alive is what separates a working Hydra performer from someone who stops and restarts.
The twenty atoms here fall into two interlocking layers. The first layer (L1 gotchas) covers the bugs you hit on day one: chains that silently build textures into the void without .out(), reactive values that bake in as constants because the thunk wrapper is missing, FFT reads that return NaN because the index is out of the rig’s 4-bin range, feedback that races to white because gain is not contracted below 1, and buffers rendered to o1..o3 that never appear because render() was not called. These are not conceptually subtle — they are mechanical invariants the rig enforces silently — so the first drills are simple recognition-and-fix pairs timed under two minutes each.
The second layer (L5 debug) teaches you to use the rig’s error surface systematically. Hydra errors split into two classes: those that throw a JavaScript exception (visible in the on-page #err element, canvas frozen on the previous frame) and those that produce no throw at all (canvas goes black, frozen, or blown-out, #err stays empty). This matters because the debugging procedure is different for each: a throw tells you what broke; a silent failure tells you what the canvas is doing, and you must reason backward to the cause from the five known patterns. “Check #err first; if empty, read the canvas and match it to the pattern” is the complete diagnostic loop.
The rig-specific FFT layer introduces a constraint that most Hydra tutorials ignore: the a object here is a 4-bin shim fed from Strudel, not a native microphone FFT. Native tutorials that call a.setBins(8) and read a.fft[7] silently return undefined → NaN, blanking the output. The fix is enforcing the 0..3 range contract and tagging the Strudel pattern with .analyze('hydra') — without which all bins read zero regardless of what the audio is doing. Higher-level features (onset, tempo/beat-phase, RMS, spectral centroid) are absent from the shim; a performer who needs them must synthesize an approximation from the four bins, for example using a threshold on a.fft[0] as a pseudo-onset.
Re-eval semantics enter here because they explain why the panic recovery works the way it does. Each save calls hush() then re-evaluates the whole file on the same GL context — there is no page reload. Frame buffers o0..o3 survive across evals (which is why feedback loops keep running after you edit the file), but JS state does not. A JS syntax error throws and freezes the canvas on the last frame, which means that even a broken file is recoverable: fix the syntax and save to resume. The panic pattern exploits this — the minimal solid(0.05, 0.05, 0.08).out() can always be typed or pasted in under five seconds and will always succeed, resetting the canvas to a dark, non-erroring state from which the performer can rebuild.
The capstone exercises all four objectives together under no-scaffold conditions. The learner receives a seeded bug file (available in context/L5-debug/hydra-bugfile.hydra), works through the diagnostic loop without hints, and must write their own panic sketch from memory. The annotation requirement forces explicit reasoning: the learner names the error class for each bug, states which canvas symptom led them there, and labels each line of the panic sketch with the safety constraint it satisfies. This documentation doubles as a personal recovery protocol the performer can revisit before any set.
Atoms in this module
Required — these gate the capstone
Supporting — enrichment, not gating
Part of curricula
- Audio-Visual Performer — integrated, synced live AV — The integrated set (north star) required
- Live Visualist — zero to performing live-coded & generative visuals — Perform the set — live-coded, generative, audio-reactive visuals for an audience required
- VJ — visual performance with projection, light & video — Play out: the full VJ show at scale recommended