Skip to content
Vibecoding4 min read

Battle Drones: A Vibe-Coded RTS and the Agent Loop That Made It Fun

Simon Willison's Battle Drones went through 12 major iterations and 321 commits, mostly written by coding agents. The most useful parts for builders are how the agent tested its own game and why a deterministic simulation was needed.

By TRAGenX Desk

Share

Simon Willison's latest vibe-coding experiment is Battle Drones, a Command & Conquer-style real-time strategy game that runs in the browser on mobile and desktop. It is hosted as static files. Willison says he reviewed almost none of the code, which is TypeScript, a language he has hardly used. The more transferable lessons are about the engineering loop around the model, not the game.

What was built

The project went through 12 major iterations and 321 commits, mainly made by coding agents. The first prototype used the Phaser 2D framework with generated sprites, and Willison says it was not fun. Later versions added full sprites, five terrain maps, a port to three.js with 3D models, new unit types and seeded random maps. Willison used Claude Code throughout, with Claude Opus 5.5 from v3 onward.

'Make it a LOT more fun' only worked because the agent could measure fun

For v4, Willison sent a prompt from his phone: "This game isn't fun enough yet. Make it a LOT more fun." The run used Claude Code's Ultracode mode and took many hours overnight. It added openers, call-down powers, objectives, a Last Stand mode, an 8-mission campaign and mutators.

The prompt was vague, but the setup made it work. A game can be played against itself, so Claude ran 1,200 AI-vs-AI test matches. The share of games still undecided after 25 minutes fell from 14% to 0.9%. Stalemate rate is a crude proxy for fun, but it is a number an agent can optimise and check. Vague goals work better when the agent can turn them into a measurable loop.

Determinism is the hidden requirement

Replays and multiplayer both need a deterministic simulation. Willison reports that browsers returned slightly different values for Math.sin() and Math.cos(), which desynchronized replays. Claude replaced them with custom versions. This is a bug class that reading code rarely catches. The agent found it because replays diverged between runs.

  • Give the agent a way to reproduce failures, such as replay and match-JSON export.
  • Treat floating-point and platform differences as a design constraint from the start.
  • Let the agent build its own tooling. Willison notes that tools are now effectively free to build, and Claude built several for itself, including a 'Radio Probe' to measure bandwidth between devices.

Audio multiplayer, and where it stopped

Version 12 added multiplayer between two nearby devices, with game state synchronized over sound. Claude built an audio modem system, and Willison tested it across laptops, iPhones and iPads. He cites Siner and ggwave as prior art he found. The article does not say which library the game used. The audio caused a severe headache for a tester, so Willison added a warning, tried WebRTC without success, and had Claude build a small WebSocket relay. Players can now share a room URL or QR code for online play.

What this means for builders

Willison is candid about the limits. He has reviewed almost none of the code, multiplayer had not been widely tested at v12, and he does not consider the game ready for indie showcases. For a hobby game, that trade-off is fine. For fintech or trading software the same workflow needs tests, review gates and reproducible failures before any agent-written code ships. The Battle Drones loop of simulate, measure, replay and fix is exactly the part that carries over.

Willison also says Ultracode burns many tokens, but it can solve complex problems from one prompt. Budget for that cost, and put your effort into the evaluation harness rather than the prompt.

FAQ

Frequently asked questions

What is Battle Drones?
A browser-based, Command & Conquer-style real-time strategy game that Simon Willison built mostly through coding agents. It is hosted as static files and runs on mobile and desktop.
Why does a vibe-coded game need a deterministic simulation?
Replays and multiplayer require every device to compute identical game state. In Battle Drones, browsers returned slightly different Math.sin() and Math.cos() values, which desynchronized replays. Claude replaced them with custom versions.
Can you trust code the developer never reviewed?
Willison himself says he reviewed almost none of the code and does not consider the game ready for indie showcases. For anything that handles money or security, add automated tests, review and reproducible failure cases rather than relying on the model alone.

Sources

Share

Read next