Skip to main content
Jonathan Andrei
Back to all posts
Jul. 202611 min read

Clatterfall: One Marble, One Subreddit, One Shared Run a Day, One Machine Nobody Can Build Alone

r/Clatterfall is one continuous descent, built by a crowd, one part per person per day. Every morning the entire committed machine re-runs as a single canonical simulation that everyone watches together, and the parts the marble abandons dissolve. Three rules do the load-bearing work: you can only build on the marble's actual path (the frontier), the daily run is server-simulated once and replayed pixel-identical everywhere, and parts the marble stops touching dissolve. Non-AI and proud: every pixel drawn from Phaser Graphics primitives at runtime.

RedditGamesHackathonReddit DevvitPhasermatter-jsGame DesignTypeScriptCommunity
I created this post and the Clatterfall project for the Reddit Games and Puzzles Hackathon. #RedditGamesHackathon

I collected marbles as a kid and kept a box of them, the kind of small private hoard you take out and admire by yourself. Clatterfall is the inverse of that box. There is one marble, and it belongs to everyone. A whole subreddit builds the machine it runs down, one part a day, and every morning we all watch the same marble together. I wanted to take the thing I loved alone as a kid and turn it into something a community does at the same time.

The daily run: a marble threading a hand-made cascade of wooden ramps, brass bouncers, and paper-cream chutes on a sunlit workbench-style board, with a depth ruler on the right
The daily run. Every morning the whole machine re-runs, and everyone watches the same marble.

The hook: the return reason is a cliffhanger, not a notification

  • Every morning a scheduled job re-simulates the entire committed machine and launches one marble down it. You open the post to watch the marble thread the whole community contraption and find out: did we set a new record, or did a bad part cap us short of the goal?
  • Then you spend your one part. You get exactly one part per day. You snap it onto the machine's live frontier, argue in the comments about what to build next, and your streak ticks up.
  • Tomorrow the marble runs again through everything, including your part, and everyone comes back to see how far it went.
The full machine seen from a wider zoom: dozens of parts placed by different redditors form a deliberate 2D contraption of ramps, chutes, bouncers, and funnels descending across the board
The machine. Every part is a redditor's daily contribution. Nobody could have built this alone.

The frontier is the marble's own fall corridor

The frontier is not a wide fan of cells below the machine's last contact. It's the actual path the marble drops through on its way out, widened by one column each side. This started as an aesthetic choice and turned out to be load-bearing. When the frontier was a wide cone, most legal cells were places the marble would never visit, so a part built there was touched by nothing, scored nothing, and dissolved. The game was inviting people to spend their one part a day where it could not possibly matter. Building where the marble genuinely goes is what makes a part able to matter.

The build view showing the frontier as a pulsing highlighted set of cells hugging the marble's actual path from the previous run, with the rest of the board dimmed and unbuildable
The frontier. You can only build where yesterday's marble actually reached, widened by one column each side.
The palette overlay showing the four static parts (Straight Ramp, Curved Chute, Bouncer, Funnel), the tap-rotate control, and a 'you have one part today' scarcity indicator with the placement countdown
One part per person per day. Scarcity makes each contribution matter. Never spam.

Every part is signed, and credited by exactly how far it carried the marble

Tap any placed part to see who built it and how far it carried the marble last run (u/alice's ramp, carried +118 px), then vote to keep it or cut it. The result card names the three redditors whose parts carried the marble furthest today, and the splash card shows 'built by N redditors'. The collective is visible, not abstract. The attribution uses a high-water-mark accumulator, so each part's credit sums exactly to REACH even when a bouncer sends the marble upward.

A placed part tapped open, showing the builder's Reddit handle, the exact px the part carried the marble last run, and up/down vote buttons
Every part is signed and credited to the exact px it moved the marble. The collective is visible, not abstract.

The daily result: NEW RECORD / TIED / CAPPED SHORT / GOAL

As the marble closes on the record line, playback dilates into slow motion and the camera leans in, so the moment the whole community is waiting for actually plays like a moment. Then the ruler fills toward the record pin and one of four resolutions lands: NEW RECORD, TIED, CAPPED SHORT, or GOAL. Camera-shake on a record break. Confetti drawn from Phaser Graphics primitives, not a sprite sheet.

The NEW RECORD resolution: the marble has passed the previous record pin on the ruler, the camera has zoomed in during a slow-mo moment, confetti is falling, and the depth number is highlighted
NEW RECORD. The whole community wakes up and finds out together.

The dissolve: no vote can save a useless part

Parts the marble stops touching dissolve overnight. A part that jams the marble dissolves the next morning. Nothing in the crowd-machine lineage prunes contributions by simulation outcome, so the machine is under constant negative selection: only what the marble actually uses survives. A part the marble did use last run can never be voted out.

A part fading out with a light sawdust burst underneath it, marked 'dissolved: the marble did not touch this part'
The dissolve. The artifact edits itself. Only parts the marble actually used survive the night.

Why it's Reddit-y (and not AI slop)

The Reddit brief warned against AI slop. So there is none in Clatterfall. Every pixel of the game (parts, marble, ruler, record line, confetti) is drawn from Phaser Graphics primitives at runtime. No sprite sheets, no stock art, no AI-generated images anywhere in the project. The feed card outside the game is hand-written HTML plus one inline SVG. It's non-AI and proud, which is the right answer to that brief. The community layer is Reddit-native by construction: the comment thread becomes the coordination arena (someone put a bouncer at 4,6 so we stop hugging the left wall), one placed part per person per day makes each contribution consequential and never spam, and the shared morning run is the r/place ritual repackaged as a running artifact.

The Reddit feed card view of a Clatterfall post: title, current day counter, deepest px, next-run countdown, and a preview of the machine, hand-written HTML plus one inline SVG, no Phaser needed at the feed layer
The post as it appears in the Reddit feed. Fast, no Phaser boot required to advertise the state. The full game boots only when the user opens it.

The two hard problems, engineered out

  • Coordination. Placement is grid-snapped, one part per cell (first commit wins, atomically via Redis hSetNX), one part per user per day, and gated to the marble's live frontier. Hundreds of daily parts become a deliberate 2D contraption, never a chaotic pile and never a one-wide line. A bad part can only cap distance, never permanently brick the chain (a soft catch-floor is always maintained below the machine). Dead or downvoted parts decay and free their cell, so the machine self-heals.
  • Determinism. The marble is simulated once, on the server, per daily run, and stored as a compact keyframe path. Every client just replays those keyframes as tweens. There's no client-side physics, so the run is pixel-identical for every player on every device. Cross-device drift is structurally impossible.
  • The balance claims are reproducible, not asserted. npx tsx tools/season-sim.mts plays out 20-day seasons with a seeded crowd and prints the record, the frontier size, and how much the marble pruned. It is also the script that caught two silent bugs: it proved an untouched part cannot move the record, and it is what showed that random players never improved the record once in 20 days under the old cone frontier.

Honest limitations

  • Seeded, not yet adopted. A freshly installed post ships with a real 26-part starter cascade (built by the same greedy 'extend the reach' logic the game rewards, so all 26 seed parts are genuinely on the marble's path). To make the record-chase real for judging, the machine needs a live cohort placing parts across several UTC days.
  • Physics feel is playtest-bound. The gravity, restitution, and friction values are tuned to feel weighty and reliably rest, but a bigger part vocabulary would need more tuning. The four-static-part palette is a deliberate scope choice that keeps the marble the only dynamic body (which also protects determinism).
  • Cut for scope, easy to add later: a zoomed-out minimap, a Hall of Machines gallery of finished seasons, and richer parts (a spinner and a seesaw were designed and deliberately deferred).
One machine. One marble. One shared run a day. The comment thread becomes the coordination arena, the frontier makes every part causally dependent on yesterday's marble, the dissolve prunes anything the marble stops touching, and the morning run is watched pixel-identical by everyone. It's the box of marbles I had as a kid, inverted: not private, not silent, not admired alone.
Related project

Clatterfall: A Whole Subreddit Builds One Marble Machine, One Part a Day, and Every Morning We All Watch the Same Marble

View the project