The Agent That Built a Game While I Watched the Filesystem
The Agent That Built a Game While I Watched the Filesystem
Last week I did something that sounds reckless: I handed a whole task — "design and build a small physics game, then push it to a repo" — to an autonomous AI agent, walked away, and let it work. No gameplay spec. Just a scope and a few constraints.
The game exists. You can play it in your browser right now. But the game isn't the interesting part. The interesting part is the stretch in the middle where it looked completely dead — and what it took to find out it wasn't.
This is a story about how I actually build with AI. Which, it turns out, is mostly about refusing to believe the obvious thing.
The setup: an agent that works off a subscription
A while back I built roam — a small tool that dispatches an autonomous agent to a machine, lets you walk away, and lets you attach back to steer it. One static binary, it copies itself over SSH, and it journals every step.
roam's own agent loop talks to an LLM API, which means every step costs tokens. For a long, open-ended build — clone this, learn that, write a game, compile it, push it — that adds up fast. So I wired in a second option: instead of its own token-metered loop, roam can hand the entire goal to a coding agent running on a flat subscription. Same price whether it thinks for one minute or thirty. Dispatch the goal, let it grind, stop watching the meter.
That bridge was the thing I was really testing. The game was just the payload.
"They're dead"
I sent the goal to a remote box. Nine seconds later: done. Empty output. Nothing built.
I bumped a timeout and tried again. This time it ran — and produced nothing for five minutes, then got killed. I tried locally. Same silence. Two agent sessions sitting side by side, both frozen at zero bytes. Everything I could see said the same word: dead.
Here's the thing about "every signal says dead": it usually means you're reading the wrong signals.
Watching the disk instead
So I stopped trusting the output stream and the terminal, and I watched the one thing that can't lie: the filesystem. I ran the agent through a pseudo-terminal to defeat output buffering, and beside it a loop that did nothing but count files in the working directory every fifteen seconds.
For three minutes: zero. Then — twenty-eight files. Then thirty-one. The agent had been quietly provisioning a cloud sandbox the whole time, and the moment it started acting, it cloned a physics library, studied its API, and wrote code. It was never dead. It was quiet.
That flipped the whole problem. Three things were true that no tutorial warns you about:
- The agent is silent by design. It works server-side and lands results on disk in bursts. The filesystem is the only honest progress signal — not the logs, not the pane.
- The "finished in 9 seconds" was a babysitter bug. My wrapper declared the job done after a few seconds of quiet — right in the middle of the agent's silent startup. It was killing a healthy process for not talking.
- The agent does one bounded chunk of work per run. Hand it a giant brief and it does a slice and stops. Hand it focused slices and it delivers.
None of that is in the docs. All of it came from watching the disk instead of the dashboard.
The payoff
Once I fed it focused slices, it was genuinely good. Slice one: it studied machin's Box2D physics binding and got it linking. Slice two: it wrote a complete hill-climb driving game — a suspension car on procedural terrain, a title screen, win and game-over states, two levels — and compiled it to a native binary. I ran it on a real display and drove the car up a hill. It worked.
Then I asked for the harder thing: put it in a browser.
That has a trap in it. The desktop game uses a real C physics engine (Box2D) through a foreign-function bridge — and that bridge doesn't survive compilation to WebAssembly. So the agent did the right thing: it wrote a second, pure-machin physics simulation — a lightweight car-on-hills model with no C at all — and compiled that straight to WebAssembly. One game, two physics engines: the real one on the desktop, a hand-written one for the web, with a little JavaScript drawing what the WebAssembly computes. It's live.
Why this is the whole point
I didn't write the game. The agent did. But look at where the actual engineering happened.
I built the harness that ran it. I found the babysitter bug that was killing healthy work. I worked out that the filesystem was the only trustworthy signal. I broke the task into slices the agent could actually finish. And I verified every claim — I drove the desktop game on a screen, I loaded the WebAssembly module and drove the car through code to confirm the physics actually moved, and I checked the live URL rendered before I told anyone it was done.
That's the gap between "I prompted a chatbot and shipped whatever fell out" and building something you can stand behind. The AI is the engine. The engineering — the harness, the debugging, the verification, the refusal to accept "it's dead" from a signal that was simply the wrong one — is what makes the output trustworthy.
That combination is exactly what I bring to the systems I build for clients at Intrane: senior judgment as the guardrail, AI as the multiplier. Most teams get one or the other — speed without rigor, or rigor without speed. The reliable work lives where they meet, and that's the work I take on.
If you've got a hard problem and you want it built by someone who checks the bytes, let's talk.
Everything here is open. machin is the language the game is written in; roam is the agent runtime that dispatched the build; the game itself lives in the machin showcase — and you can drive it in your browser.