posts
Seventeen Years Late
Seventeen years ago I made myself ill working 100+ hours a week for months on end. So ill that I was in hospital for six weeks. Luckily for me, the company I was working for did provide private health insurance, so it was a very nice hospital. It was also summer, so when we weren’t in group therapy sessions, we were out in the sun, enjoying the gardens. I also made friends with several other patients and we would spend our spare time together, mostly just chatting about the groups and the world and our lives.
The Activities room had some outdoor games, including a croquet set. Unfortunately, the rules were no longer in the box with the hoops, the mallets and the balls, and none of us knew the actual rules of croquet.
So we invented our own.
We shared out the hoops and went and put them wherever we wanted within the areas we had access to. The stake went in the centre of the big lawn. Then we had to get our ball through all the hoops and back to the stake. We’d put them under benches, on top of hills, in shrubberies (Ni!) and anywhere else we thought would be funny. Games often lasted an hour of more. We called it Extreme Croquet.
I thought, when I got home, I would create a videogame version of Extreme Croquet, but it turned out to be a while before I could think of coding again, and then I returned to work, and the idea slowly faded into vague memory. Until a couple of days ago, when I mentioned that episode of my life to a friend, and remembered the videogame idea. And now I have the tools to bring it to life. So I created a new repository and started yet another Claude Code session.
My “New Project” workflow
I have five skills I run in order when starting a new project; three of them mine, two from OpenSpec. Claude (Opus 5) wears two hats during this initial session: Analyst at first, then Architect. I am the Product Owner. The flow looks like this:
/dmons:discovery → /opsx:explore → /dmons:architecture → /opsx:propose → /dmons:scaffold
ANALYST ANALYST ARCHITECT ARCHITECT ARCHITECT
what & why record the what decide the how record the how build the crew
Once I’d completed this setup process I thought it would make a good blog post, so I asked Claude to summarize what we did. The tables and lists below were generated by Claude; the prose is 100% mine.
Step 1 — Discovery: the Analyst hat
This is the dmons:discovery skill, the first one invoked in every new project. Claude
becomes The Analyst.
The Analyst interviews me to dig into every detail of what I want to build. It has explicit
instructions not to worry about platforms, programming languages, frameworks, or any of the
technology decisions; those could pre-emptively restrict the flow of ideas. The product should
drive the technology choices, not the other way around. It’s harder than it sounds.
The Analyst interview, round by round
Here are the questions and answers from this step, laid out by Claude:
| # | Asked | You answered |
|---|---|---|
| 1 | What is it? Who has the problem? Why now? | A game; multiplayer; sync or async; origin story |
| 2 | What is Extreme Croquet as you played it? | Croquet set, no instructions, no phones, 2009. Split the hoops, place them anywhere, stake in the middle of the lawn. Ridiculous-but-achievable. Worms-style humour |
| 3 | Faithful recreation, or inspired? | Player placement is sacred; everything else free. Terrains: country house, then construction site, volcano, moon |
| 4 | Is determinism the requirement, or is async? | Async. Determinism was just the means |
| 5 | All three play modes day one? | Couch → online sync → async |
| 6 | What happens on your turn? | Aim + power. Skill in the aim, comedy in the terrain. Generous ~1 min timer |
| 7 | Do players interfere with each other? | Yes — rest against a ball, then smack it. Plus hazards: under cars, into bushes, water, drops, lava tubes |
| 8 | What’s async actually shaped like? | Words With Friends. Notification → watch their shot → take yours. Mobile. In-game messaging is part of it — “you jammy git” is the point |
| 9 | Name the real place, or not? | Not. Unnamed English country house |
| 10 | Player count? | 2–6 |
| 11 | Any single-player? | Practice mode. Bots out for v1 |
| 12 | What does success look like? | “I play it with my friends and we have fun.” Store and money would be a bonus |
| 13 | What’s explicitly out? | Ladders, cosmetics, progression, level editor, IAP. Power-ups in — hit them with your ball |
| 14 | Where’s the v1 line? | Couch only, Windows/Linux/Mac, plus power-ups |
| 15 | Hoop count and order? | 8 / 12 / 10 by player count. Numbered, taken in order — placing one as far as possible from the last was the joke |
| 16 | Round end? Teams? | First to finish wins; group chooses whether to play on for places. Individuals; pairs for even groups |
(The “determinism” question was because I had suggested that deterministic physics would be the best way of implementing remote play, which (a) violated my own rule about technology choices and (b) turned out to be wrong anyway.)
The late addition that changed the most
After all of that I added, almost as an afterthought:
“oh, one more thing: the orientation of the hoops is also important, so you have to be able to rotate them when placing, and they are one-way only, going through the wrong way doesn’t count.”
Claude, sycophant that it is, thought this was absolutely wonderful:
Oh, that the most load-bearing requirement of all, and it arrived last, unprompted. It doubles the placement mischief — not just where, but facing which way. It also creates a design problem nobody has solved yet: how do you read a hoop’s correct side from across the car park? That’s still an open task in the plan.
Result
When we do this step, Claude genuinely pushes me to think through the requirements systematically, in the way I try to run these sessions with customers. And it’s not only answering the questions: often something will trigger additional thoughts that also get recorded. With previous versions of the skills and the Claude models, it could get tedious and it would sometimes forget things I had already told it, but with Opus 5 it is a long but thorough process and I honestly enjoy it.
Step 2 — Explore: writing the what down
The opsx:explore skill comes from OpenSpec, and it records everything from discovery using
OpenSpec’s strict rules and file structures:
- Created the change
extreme-croquet-v1. - Output:
proposal.md+ 9 capability specs, 40 requirements, all in problem-space language. - Capabilities: match-setup, hoop-placement, shot-taking, hoop-progression, ball-interaction, power-ups, terrain-and-hazards, local-couch-play, practice-mode.
- Deliberately left empty:
design.mdandtasks.md— those belong to the Architect. - NB: it’s not always perfect. OpenSpec has a deterministic validation step and in this instance that failed first time. Every requirement needs a SHALL or MUST; ~40 of them had to be rewritten. The tooling has opinions.
Step 3 — Architecture: the Architect hat
One of my core values for this new way of building software is that I don’t need to be proficient in the technology used to build it. I can read code in pretty much any language except APL, Malbolge and the like. I don’t need to be able to write it anymore. So the shape of what we’re building should decide what tech to use. I’ve got projects in progress using Swift, Go, Zig, all sorts. I understand the code and I can diagnose issues (often in partnership with Claude).
That means the discovery phase completely ignored technology and system design choices: it just gathers and crystallizes the requirements.
The dmons:architecture phase is where those choices get made, and Claude’s Architect role is deliberately
opinionated: it makes recommendations and defends them, although obviously I get the final say. I
don’t override it very often.
Here’s how that went this time:
The decision that reframed the project
I’d assumed deterministic physics, because that’s how you get “watch their shot exactly as they saw it”. The Architect pushed back:
- Croquet is strictly turn-based. Exactly one ball is ever in motion. Nothing else moves.
- So the shooter’s device can simulate its own shot, record what happened, and send the recording. Everyone else plays it back rather than re-simulating.
- “Exactly as they saw it” stops being an engineering goal and becomes literally true.
- Cost: trust (the shooter’s device is authoritative) and a few kB per shot. Both fine when the threat model is your mates and there are no ladders.
- What it kills: hand-rolled fixed-point physics, which on a solo project is the most likely reason it never gets finished.
My reply, in full: “record-and-replay sounds fine tbh”
This highlights that “opinionated” thing: doing it my way would have been complicated, especially because floating-point sums don’t necessarily give the same answer across different hardware.
The recommendation that changed mid-session
Then the Architect changed its own mind on another decision. We’d agreed on Godot because it’s open source and free, but then an initial assumption based on Claude’s memories of other projects we’ve worked on turned out to be wrong. Here’s the Architect’s description:
- Initial lean was Godot + C#, because you work in .NET.
- Before recommending it, the model checked the Godot docs rather than asserting from memory.
- Finding: C# on Android and iOS is officially experimental (arm64 only). Mobile is a hard requirement for the async phase.
- Recommendation changed to GDScript before it ever reached you.
This is down to an explicit instruction in the Architect’s prompt: verify, don’t trust.
The decisions, as recorded
The Architect’s final decisions were recorded thusly:
| # | Decision |
|---|---|
| D1 | Record-and-replay shot authority (ADR-0001) |
| D2 | Godot 4 + GDScript, Jolt physics (ADR-0002) |
| D3 | 3D, single shared camera |
| D4 | Jolt |
| D5 | Local files only — no backend, no accounts in v1 |
| D6 | Simulation separated from presentation; a shot is a recordable unit |
| D7 | GUT for the sim core, Blender for assets, CI deferred |
- Unity was presented as genuinely defensible (better mobile, official Switch, first-party ads) and rejected on one argument: those wins land in phases 2–4, the cost is paid all through v1, and v1 is the part that must not fail.
- Also flagged, unprompted: the directory wasn’t a git repo yet. You ran
git initand added a remote.
Step 4 — Propose: writing the how down
After discovery, Claude moves on to the OpenSpec opsx:propose skill:
design.md— D1–D7, each with rationale and the alternatives rejected, plus a risk table.- Two ADRs, for the calls that are expensive to undo:
ADR-0001record-and-replay shot authorityADR-0002Godot 4 with GDScript
tasks.md— 14 sections, ~90 tasks, dependency-ordered.- Two risks written down as genuinely unsolved rather than smoothed over:
- “Ridiculous but achievable” is a feel problem — unsolvable on paper, needs playtesting.
- Hoop direction legibility at distance — specified, but nobody knows how yet.
That skill includes an instruction to record open questions or things that need spikes as part of the plan, so you don’t start building with assumptions or guesses.
Step 5 — Scaffold: building the crew
This is my favourite bit of what I made. Once the OpenSpec change is completely defined and
recorded, the dmons:scaffold skill creates a team of agents and some CLAUDE.md entries.
The main session, the one that I’m talking to, is able to switch freely between its Analyst
and Architect personalities, and it breaks the list of tasks into self-contained blocks and
briefs the agents on how to complete them.
There are three basic agents: worker writes the code and the tests; reviewer reviews
every block with it’s own session and context so it never knows what the worker was thinking;
and once every block in a section has been completed, the supervisor reviews the whole thing.
The agents use different Claude models for speed and to save tokens:
| Agent | Model | Runs |
|---|---|---|
worker | sonnet | per block |
reviewer | sonnet | per block |
supervisor | opus | per section |
Giving the supervisor the better model means I don’t worry about the worker or reviewer making mistakes. In practice, it finds something it pushes back on about 60-70% of the time.
Here’s how Claude describes this workflow:
- Two nested loops: section by section, block by block. A block is one deliverable, one review, one commit.
- The split that matters: the reviewer is diff-local; the supervisor is the only thing that ever sees more than one block at once.
- The supervisor’s top check is project-specific: does the recording still cover everything a shot mutates? Sections 7, 8 and 9 all add state; a block that adds state without extending the shot result breaks replay silently, and no single diff shows it.
- Two questions asked here, both because the Godot project didn’t exist yet so nothing could be
detected: the build gate (
godot --headless --import) and whether to add a format gate (gdtoolkit).
It also wants me to tell you that the ADRs are binding and enforced by the agents. They’re not just documentation, they’re part of the system of gates everything must pass through.
What existed at the end of the session
Nothing that runs. No code, no skeleton apps, not even a .gitignore file.
The one exception is if the Architect ran a spike to prove something, in which
case that is kept as a committed artifact.
Here’s what I ended up with for this project:
CLAUDE.md workflow + project facts + toolchain (Godot 4.7.1)
docs/adrs/
ADR-0001-record-and-replay-shot-authority.md
ADR-0002-godot-4-with-gdscript.md
openspec/changes/extreme-croquet-v1/
proposal.md the what & why, v1 boundary, future phases
design.md D1–D7 + risk table
tasks.md 14 sections, ~90 tasks
specs/ 9 capabilities, 40 requirements
.claude/agents/
worker.md reviewer.md supervisor.md
- 29 files, 3,233 lines, zero lines of game code.
- Two commits:
4014eab(baseline) and0d5d384(Godot 4.7.1 note).
All this took a couple of hours, but that’s a couple of hours up-front that saves me
potentially days of mistakes, backtracks, rewrites and who knows what else. I’m a good
way into the opsx:apply phase now, where stuff actually gets built, and it’s ticking
away quite happily, occasionally asking permission to run godot --headless with new
parameters, but I’m working on a solution to that. More on that in the next post.
Free stuff
If you want to try this workflow for yourself, it’s all wrapped up in a marketplace at daemonicai/dmon-dev. You can try it as-is, or fork it and make it work your way. And if you want to spend a couple of afternoons (or mornings if you’re across the Atlantic) check out the live online workshop linked below this post.
Oh, and if you want to follow the progress of Extreme Croquet, follow this blog, or follow me on LinkedIn.