Chris Dilger

← Writing · · workflow, agents, beads

Planning with beads: how Physical Soccer and Joystick Jammers get built

My loop for new projects is deliberately boring.

  1. Write the plan. A real document: what the thing is, who it is for, what “done” means, and how we will know.
  2. Turn it into beads. Every requirement becomes an issue in beads, stored in the repo next to the code, with real dependencies between them.
  3. Let the graph decide. br ready lists only the beads with no open blockers. That is the whole scheduler.
  4. Run a herd. With herdr and ntm I keep a few agent panes open side by side, each claiming one ready bead, so the work fans out and the graph keeps it honest.
  5. Review, playtest, write the next beads. My job is steering and taste.

Two of my current projects show what that looks like, and they show two quite different shapes.

Physical Soccer: plan first, then let it flow

Physical Soccer is a party football game where anything can be a controller: phones, pads, keyboards, half a touchscreen. Before a single bead existed, it had a plan: plan.md, now on its fifteenth revision. Each revision closed real gaps. Revision 3 decided who owns the room state. By revision 4 the plan had a journey matrix and dependency cuts, and it said, in so many words, that it was “ready to convert into small, testable tasks”. The revisions kept coming anyway: revision 7 pinned the physics clock (the original game runs at 0.85x wall-clock, so the port carries an explicit time scale).

Then it was converted: a coverage index (plan-beads-map.md) maps every requirement to a bead ID, and every bead carries its own contract (what to build, which checks prove it, which evidence a parent bead needs from its children).

Physical Soccer: beads created vs closed, hour by hour

created (total)closed (total)open right now
050100150 010203040 hours since the first bead beads
About 130 beads were written in the first afternoon, straight from the plan. Closing started almost immediately and ran as a steady stream: 64 closed in the first 42 hours, with the open count falling as soon as the planning burst ended. That is what a good plan buys you: agents never ran out of well-specified, unblocked work.

Physical Soccer: 194 beads, 451 blocking links, 24 layers deep

closed 64in progress 3blocked 6open 91deferred 30
no blockers 24 layers deep
Each dot is a bead, placed further right the more beads must close before it can start. Filled dots are closed. You can see the work moving through the graph as a wave from left to right. 162 of the 194 beads wait on at least one other, and the longest chain is 24 beads long: the real critical path, which no number of agents makes shorter. Grey outlines are ideas deferred on purpose. Titles are left out deliberately; the shape is the point.

Why did this one flow so well?

Joystick Jammers: an ongoing swarm

Joystick Jammers is a party racer and demolition derby: the TV is the arena, phones are the pads. It is in a different phase. The game works, and the job now is polish: player readability, controller latency and reconnect confidence, tutorial and onboarding, wheelies and stunt payoff. That kind of work is discovered by playing, not planned up front.

Joystick Jammers: beads created vs closed

created (total)closed (total)open right now
050100150200 051015 days since the first bead beads
A small start in mid June, then a single review day (day 15) that filed 151 polishing beads at once. Since then the swarm has closed 10 to 27 a day, speeding up as the polishing beads got sorted and claimed. 89 are still open: this one is very much still going.

Joystick Jammers: 207 beads, 313 blocking links, 10 layers deep

closed 114blocked 3open 89deferred 1
no blockers 10 layers deep
A much shallower graph than Physical Soccer: 10 layers instead of 24. Polish work is wide, not deep, so the herd can attack it in parallel. 4 different authors created beads, including agent identities like OliveFox and SilverBass: the swarm files follow-up work for itself as it finds it.

The coordination rules are written into the repo, so every agent reads them on start:

Deep vs wide

ProjectBeadsBlocking linksLongest chainClosedShape
Physical Soccer1944512464planned, deep
Joystick Jammers20731310114polishing, wide
This site (previous version)99117785small, quick

The longest chain is the number I watch now. A herd of agents makes a graph wide cheaply: more panes, more parallel beads. Only planning makes it shallow, by finding the dependencies early and cutting them where they are not real. Physical Soccer’s 24-deep chain is the honest critical path of a networked physics game with a relay, two hosts and owner playtests in the loop; Jammers’ 10 layers is what lets a five-pane swarm close two dozen beads a day.

The part that surprised me is how much the graph helps me. When something goes wrong, the fix is usually a better bead (clearer acceptance checks, a missing dependency), not a better prompt. I wrote about that shift in Your Prompts Do Not Matter (Anymore).