Creative Coding

Debugging Creative Code: Getting Started

Generative work fails differently from normal software: it runs fine and looks wrong. Seeds, visual debugging, bisecting a sketch, and how to catch the bug that only appears after forty minutes.

Most debugging advice assumes your program crashes or returns a wrong number. Creative code usually does neither. It runs perfectly and produces something ugly, or drifts slowly out of alignment over an hour, or works for six days in your studio and fails on the seventh in a gallery.

Those are different problems and they need different habits.

1. Make it reproducible: fix the seed

You cannot debug what you cannot repeat, and most generative work is random by construction.

Set the random seed explicitly at the start of every runrandomSeed(12345) in p5.js, np.random.seed(), whatever your environment offers — and print or display the seed you used. Then when something looks wrong, you can go back to exactly that output.

Better: when you find an interesting or broken result, save the seed with the image. A filename like output_seed48211.png turns “I can never get that one back” into a solved problem, and it’s the single highest-value habit in this whole list.

Note that noise functions usually have their own separate seed from the random generator. Set both.

2. Draw your debug information

Printing numbers for something spatial is doing yourself a disservice. Your output device is a screen; use it.

  • Draw vectors as arrows at the point they apply to
  • Draw bounding boxes, normals, and collision radii as outlines
  • Draw the path an agent took as a faint line, so you can see history rather than one frame
  • Colour-code by state: red for particles about to die, green for new ones
  • Put a debug overlay on a toggle key so it’s always available and never in the final render

A single frame with the forces drawn on it usually answers a question that an hour of console output won’t, because the bug is almost always geometric.

3. Bisect the sketch

When output is wrong and you have no idea why, comment out half the drawing code. Still wrong? The problem is in the half that remains. Right? It’s in the half you removed. Repeat.

This feels crude and it is dramatically faster than reading code hoping to spot it. The same applies to layered effects: turn off every post-processing stage and add them back one at a time.

The related habit: change one thing at a time. Creative coding tempts you into adjusting five parameters at once because it’s fun. When something breaks, you then have five suspects.

4. “No error, but wrong” — the usual causes

A checklist that covers most of it:

  • Degrees versus radians. Your language picked one; the function you copied assumed the other.
  • Y axis direction. Screen coordinates usually go down, maths convention goes up. Anything mirrored vertically is this.
  • Integer division, where 1/2 is 0 and everything collapses to zero or a straight line.
  • Order of transformations. Rotate-then-translate is not translate-then-rotate, and confusing them produces objects orbiting a point you didn’t intend.
  • Missing push/pop (or save/restore) around a transform, so it leaks into everything drawn afterwards.
  • Colour range mismatch, 0–1 against 0–255. Everything is black or blown out.
  • Frame-rate-dependent motion: adding a fixed amount per frame rather than scaling by elapsed time. Looks correct on your machine, wrong on any other.

5. Bugs that only appear after an hour

These are the ones that ruin installations, and you cannot find them by watching.

  • Accumulating drift. Values that grow slowly — an angle that never wraps, a position that creeps. Log min/max of key variables over time rather than watching them.
  • Memory leaks. Objects added to an array and never removed; framebuffers or textures created inside the draw loop. Print your array lengths and object counts once a second — a slow upward slope is the whole diagnosis.
  • Float precision. After enough accumulation, small additions stop registering. Wrap angles and reset counters periodically.
  • Resource exhaustion: file handles, sockets, or audio voices allocated and never freed.

Run a soak test. Leave the piece running overnight before it goes anywhere public, with counters logged to a file. Almost every installation failure is something that takes hours to manifest, and an overnight run in your studio is much cheaper than discovering it on site.

6. Keep a version you can go back to

Use git even for sketches, and commit when something looks good, not just when it works. Creative code has a specific failure mode where you improve a piece past the point where it was interesting and can’t find your way back. Tag the ones you liked.