How cheap can a new game get? Designing the rulebook-PDF-to-engine experiment before building it¶
This is a forward-looking post. It designs an experiment I have not run yet, publishes the design before there is a result, and tells you exactly where I think it will break. If you came here for "and then the AI generated a working game engine," you will leave disappointed on purpose. The interesting thing is the experiment, not a number I do not have.
Here is the question underneath it. This project is a multi-device board game platform, and one of its stated economic bets is that adding games can get cheap. The go-to-market notes are blunt about why that matters: for the marketplace and white-label distribution paths, the real bottleneck is not advertising, it is per-game engine implementation cost (the overview docs, Section 7 -- "the actual bottleneck"). Indie designers do not write Python. The whole model only pencils out if the marginal cost of adding a game drops from "a phase of engineering work" to "a designer hands you a rulebook and a working engine comes out the other side."
A companion post, The cross-game compounding flywheel, argues the related claim that each game built through this loop is cheaper than the last, because the next game inherits the previous game's specs, conventions, and shared code. That post takes the forward direction as given and moves on. This post stops on the most mechanical step of all -- writing the engine itself -- and asks a narrower, more falsifiable question: how much of that step can a strong model do unaided, and what has to be true for accepting its output to be safe?
The bet¶
The experiment is one loop:
- Take a real game's rulebook PDF.
- Take the project's per-game design-doc template -- the structured the game docs that already exists for every shipped game (for example the game docs).
- Feed both to a strong model and ask it to emit two things: a candidate
GameEnginesubclass, and the failing engine tests for it. - Run the project's existing review and lint wall over the generated code.
That is the entire bet, and it is worth stating the claim plainly so it can be wrong: most of the cost of a new game is mechanical translation a model can do, and the existing wall is what makes accepting that output safe. The go-to-market doc says the same thing in one line -- "feed the rulebook PDF + per-game design template to a strong model and ask it to generate a candidate GameEngine subclass + tests ... genuinely feasible in 2026 in a way it wasn't two years ago." This post is that one line turned into an experiment with predictions attached.
Why is the bet even plausible? Because the target is small and fully specified. Every engine in this repo subclasses one abstract base class, GameEngine in the engine base contract, and implements a fixed set of methods: initial_state, get_valid_moves, apply_action, is_terminal, outcome, and three view methods. There is no framework to invent, no architecture to choose. A new game is a new subclass with the same shape as the last one. That is exactly the kind of constrained, pattern-matched translation a model is good at -- far closer to "port this spec into this interface" than to "design something from nothing."
The design doc is the prompt, not the rulebook¶
The most important design choice in the experiment is what you actually put in the prompt, and the answer is not "the rulebook." A rulebook is a blank-page problem. It is written for humans sitting at a table, it buries the state model in prose, and it leaves a thousand things implicit that a human player fills in without noticing. Hand a model only that, and you are asking it to do design and translation at the same time.
The per-game design doc is the fix, and it is the load-bearing idea in the whole pipeline. Open the game docs and look at what it already pins down: a one-paragraph box pitch (Section 1), a rules summary with setup, turn structure, and end-game (Section 2), an explicit state model that splits public, per-player private, and server-only fields (Section 4), an action vocabulary that maps every move onto the engine's Action = (player_id, action_type, data) tuple (Section 5), and the three views spelled out field by field (Section 6). That document is a human reading the rulebook and writing down the engine-facing shape of the game. It is, almost literally, a filled-in prompt template.
The reason that matters is integration time. When the model's target is a fixed shape -- "produce a subclass that fills these methods, with this state split, these action types, these three views" -- the variance in what it produces collapses. It is not guessing at the interface; the interface is handed to it. Using the design doc as the prompt template is what turns "generate a game engine" (open-ended, high-variance, hard to review) into "translate this specified game into this specified class" (bounded, comparable across games, reviewable against a reference the human already wrote). The go-to-market doc calls the per-game design structure "effectively the prompt-template for this pipeline," and that is the right way to read it: the design doc is the contract the generated code is measured against, authored by a human before the model runs.
What the contract asks that a model might get wrong¶
So what would I actually watch? The engine contract is small but it has three corners where I expect a model to slip, and naming them in advance is how the experiment stays honest -- these are predictions, not findings.
The three views. Every engine must build public_view, player_view, and full_view (the engine base contract). This is the load-bearing privacy mechanism of the whole platform: private data for one player must never leak into another player's view. On a perfect-information game the split is trivial -- everything is public. On a hidden-information game it is the entire ballgame, and it is subtle. The Bluff design doc warns in plain language that drift here "silently breaks the game" -- accidentally surfacing the pile's actual cards to a player's own view because "well, it's their own play" leaks exactly the information the game is built to hide (the game docs, Section 4). My prediction: a model gets the view split right on a perfect-information game almost every time, and gets it wrong on a hidden-information game often enough that this is the first thing a human must check.
get_valid_moves versus apply_action. These two methods have to agree. Every move get_valid_moves offers must be one apply_action can actually apply, and the disagreements live in the edge cases -- the move that is legal on the common path but mishandled when a hand is empty, a pile is mid-resolution, or a player has already passed. My prediction: the model produces code that agrees on the happy path and diverges on the corners, which is precisely what the failing tests are supposed to pin before any of it is trusted.
Immutability of apply_action. The architecture rule is that state transforms return a new GameState; the engine never mutates state in place. This is easy to state and easy for a model to violate, because mutating a dict in place is the default thing code does. My prediction: unless the prompt template leans on this hard, generated apply_action implementations will mutate, and the test that catches it is the one asserting the input state is unchanged after the call.
None of those are measured. They are the falsifiable shape of the experiment: run it, and either the model surprises me by getting the view split right unaided, or it confirms that hidden-information correctness is where the human gate has to sit.
Where the human gate sits¶
The review wall is real and it is already wired up. Before anything merges in this project, a review preflight runs a battery of checks -- the review.always_checks list in the review configuration, driven through the /dev-review slash command over the orchestration control plane control plane -- and the engine's own tests run via the project dev wrapper. The project's TDD rule already requires engine tests to be written before the implementation, so "emit the failing tests too" is not an extra ask; it is the house style.
But here is the honest limit, and it is the most important paragraph in this post. The wall checks that the code conforms to the contract and that the tests pass. It does not check that the rules are right. Nothing in the lint battery can tell you the model invented a scoring rule that is not in the rulebook, or quietly dropped the tie-breaker, or got the turn-progression backwards. Worse, if the same model writes both the engine and the tests, the tests can encode the same misreading as the code -- both confidently wrong in the same direction, both green. A passing suite would prove the model is self-consistent, not that it is faithful to the game.
That circularity is exactly where the human gate has to stand, and it is why the design doc is authored by a human first. The reference for "did this engine actually implement this game" is not the generated tests; it is the human-written design doc and, behind it, the rulebook. The human gate is a faithfulness check -- read the generated engine against the design doc's state model, action vocabulary, and edge cases, and confirm the model translated rather than improvised. The wall makes that review possible by guaranteeing the code is shaped correctly and the tests run; it does not make it unnecessary. A pipeline that ships a contract-conformant engine for the wrong game faster is not a win.
Why a subclass, and not a rules language¶
One design decision is worth defending because it is tempting to overreach. The experiment asks the model for an ordinary Python subclass -- not a rules-as-data description, not a step toward a game DSL. The engine composition study lays out three levels of ambition: code-level helpers, a declarative game DSL, and a no-code composer (the overview docs, "Three Levels Of Ambition"). It is explicit that the DSL is "a different architecture" that is "harder to test, not easier, because bugs hide in the interpreter."
That caution is the reason to keep this experiment at the lowest level. A generated subclass keeps every bug in ordinary Python that the existing test and lint wall already knows how to catch. A generated DSL program would move the bugs into an interpreter the wall does not understand. The cheap, safe, falsifiable version of "let the model write the engine" is the one where the output is the same kind of artifact a human would have written -- a pure-Python subclass conforming to the engine base contract, with no new machinery to trust. The grander composer vision stays a north star; this experiment deliberately does not reach for it.
The honest edge: this is not built¶
To be unambiguous, because the genre invites the opposite: I have not run this. There are no generated engines. There is no success rate. There is no "we tried it and it worked," and if you see one in a later draft of this post, it will be clearly marked as a result with a date, not smuggled in as backfill.
What the design buys, with no result yet, is a set of predictions a reader can hold me to:
- The model gets the public / private / full view split right on perfect-information games and wrong often enough on hidden-information games that the view split is the first human check.
apply_actionimmutability is violated unless the prompt template insists on it, and a single "state unchanged after the call" test catches it.get_valid_movesandapply_actionagree on the common path and disagree on edge cases -- which is what the failing tests exist to surface.- The lint and review wall passes contract-conformant code that may still be rule-unfaithful, so the wall is necessary but not sufficient and the human faithfulness gate is load-bearing.
- Integration time per game shrinks and its variance narrows as the design-doc template stabilizes, because the model is aiming at a fixed shape instead of a blank page.
Those are falsifiable. Running the experiment either confirms them or embarrasses them, and either outcome is worth more than a confident essay that asserts the pipeline works.
That is the experiment, designed in the open before it is built. If it holds, the economic question the go-to-market notes raise -- can a new game cost an afternoon instead of a phase? -- gets a real, measured answer instead of a hopeful one, and the cheap-catalog bet that the compounding flywheel rests on gets one more leg under it. And if you are new to working this way, the transferable lesson is the shape of the gate, not the magic of the model: give the model a fixed target it can translate into, let a mechanical wall guarantee the output is shaped right and runs, and keep a human standing exactly where the wall is blind -- on whether the thing the model built is faithful to the thing you actually meant. The on-ramp for getting to a repo where any of this is even possible is the subject of From an idea in a chat window to a repo the robot can build; this post is one step past it, asking what the robot can write once the repo is real.
Or: subscribe to hear whether the experiment, once run, confirms or breaks these predictions.