How it’s built
One person, an AI coding assistant, and a lot of machine-checked rules.
Prison Life is written by me together with Claude Code (Anthropic’s coding agent). I decide what the game is and which options we take; the assistant does most of the typing. Because nobody reviews the code but me and a review AI agent, I lean on automation: rules are enforced by automated checks and by the build, not by good intentions.
Delegation
The main Claude Code session plans the work and keeps the task tracker, the written record of design choices and the commits. It does not write code: it hands every change, even a tiny one, to a specialised AI agent. Each one has its own file that fixes its role and its model.
| Role | Model tier | Job |
|---|---|---|
| Architecture | Opus | data model, tick, threads, pathfinding, decisions |
| Simulation code | Opus | simulation systems, character AI, hot loops |
| Performance | Opus | profiling, benchmark regressions |
| Review (read-only) | Opus | reviews a diff; cannot edit files |
| Client and tools | Sonnet | Godot client, UI, tools |
| Tests | Sonnet | tests from acceptance criteria |
| Content data | Sonnet | JSON definitions from a schema |
| Search, running checks | Haiku | code search; running checks and summarising failures |
Hard work goes to the strongest model, routine work to cheaper ones. If a cheaper AI agent fails the checks twice, the task moves up a tier; if the top tier fails twice, it stops and asks me.
Hooks that say no
Claude Code hooks are scripts that run around the assistant’s actions. Mine enforce three rules:
- No finishing on red. When a session or an AI agent tries to stop after changing code, a hook runs the fast check (build plus the quick tests). If it fails, the stop is refused.
- The main session cannot edit code. A hook rejects writes to source, tests, content and tools from the main session.
- The reviewer is read-only. Its edit tools are removed and a hook rejects commands that change files or the repository.
These protect against mistakes, not against deliberate bypass: a determined shell trick can get around them, and one of the hooks sees a red check in an AI agent but cannot hold it back (the main session’s stop hook still catches it). I would rather say that plainly.
Written decisions and checks
- Every non-trivial choice is written down. Tasks, milestones and design decisions are kept as plain text next to the code, in a task tracker. When we pick between options that affect more than one task, the choice is written down with its context and consequences.
- Checks run on my machine. No cloud CI. One local script has four modes:
fast,test,benchandfull. Scripts and hooks are PowerShell 7 on both Windows and macOS. - The repository is the source of truth. A local memory tool indexes the project and past conversations for search, but anything that matters is also a task, a recorded decision or a document.
The deterministic core
The simulation lives in a plain .NET library with no Godot references; the Godot client only reads its state and sends commands. The core follows fixed rules: the world changes only through commands, time is integer ticks, randomness comes only from the world’s seeded generators. The same seed and the same command log must give the same world. These rules are checked by the compiler and by tests, not by review alone; see devlog #1 for how.
- Commands are the only way in. Each has a stable type id and a binary encoding, and every command is logged with its result, including rejected ones.
- The tick has three phases in a fixed order. The order of systems is set in one place in code, and changing it changes every hash.
- Randomness uses our own generators (SplitMix64 and xoshiro256**). Named streams are derived from the world seed and stored in the world state. A stateless keyed generator, driven by a domain, a key and the tick, serves order-independent work.
- The state hash is an order-sensitive 64-bit hash for determinism checks. It is not cryptographic.
The design target is up to 1,000 inmates and staff at 20 ticks per second. It is a target: there are no characters yet and nothing has been measured at that scale.