How to Engineer an AI Harness for Game Development: Making Your Game Legible to LLM Agents
The core claim: your game is the harness
LLMs struggle with game development not because they are bad at code, but because games contain large amounts of non-code state that is opaque to a language model. The fix is architectural: make the game deterministic, addressable, and measurable so that the game itself becomes the harness an AI agent works through.
That is the argument of "Your Game Is A Harness," a blog post by game programmer Kyle Kukshtel, adapted from a 45-minute talk he gave at Indie Rodeo in Calgary. The post was published on October 10, 2026, and Kukshtel notes explicitly that it is 100% human-authored, written from his slides rather than transcribed.
Kukshtel's framing is blunt: "getting LLMs to work well with games is a context problem, not something that is intrinsically linked to how games or LLMs 'are' (or 'aren't')."
Why LLMs appear to be bad at games
LLMs are good at web stacks because in a web stack everything is code, and there is a large corpus of high-quality open-source web projects to learn from. Games break both of those conditions.
Kukshtel's argument has three parts:
- Games are not just code. A game contains assets, scenes, animation, audio, and data that are not easily representable as source code. Those components are effectively opaque to an LLM.
- There is far less training data. Kukshtel estimates there are orders of magnitude fewer high-quality open game projects than web projects, so the model's priors are weaker.
- There is no standard template. Game engines exist, but there is effectively no standardized tooling for game logic, because every game manifests its own needs differently.
This is why one-shot Three.js demos work: they reduce a game to plain primitives and code, skipping asset generation and conformance work. Kukshtel notes that this is also why many of those demos feel like "slop" — they lack authorial voice beyond the LLM median.
The practical consequence is that a game is a black box to an agent, and the only thing visible is the code as written. A harness alone does not solve that, because the harness does not change the fact that games are not just code.
The context engineering basics that motivate the approach
Every LLM call decomposes into three parts: a system prompt (generic text shared across all users), an assistant prompt (a sidecar that shapes the model's response vector), and the user prompt (where essentially all of your input lands).
Kukshtel's key mechanical point is that a session is not fresh on each turn. Every prior message is resubmitted on every new message, like the playground game where each player must restate everyone else's contribution before adding their own. That accumulated text is the context, and only the latest message is genuinely new.
Because earlier content keeps informing new work, bad content earlier in a session produces degenerate results — a failure mode Kukshtel calls context pollution. The emerging discipline of context engineering asks how to get the best information into the context with as little pollution as possible.
Kukshtel cites a blog post by Drew Breunig, "How Contexts Fail and How to Fix Them," as further reading on long-context failure modes.
Making a game legible to an AI agent
Kukshtel offers a concrete checklist. He notes that most of these practices are good game development in general — AI just supercharges the payoff.
Fixed randomness
Create a single source of seeded randomness at the start of the game, and route every non-deterministic call through it. If your code calls Random.Float in 30 places to determine gameplay behavior, the 30th call will then produce the same value every time, and the game can deterministically recreate almost any state.
Kukshtel's warning is about timing: retrofitting determinism at the end of production is very hard and likely requires fundamental changes in the eleventh hour. Assume the constraint before the first line of code.
Screenshots and image diffing
Most engines have a built-in screenshot API. Kukshtel also recommends toggling UI layers and gameplay layers on and off so the agent can reduce visual clutter when working on a specific layer.
But before/after screenshots alone do not work well. Even multimodal models struggle to identify what changed and whether the change moved toward the goal. Kukshtel treats this as another form of context rot: everything in the frame that is not the target of the change is pollution the model must still process.
The fix is image diffing. Kukshtel recommends odiff, a free command-line image-diffing tool. Given two images, odiff produces a diff image and a quantitative similarity value such as "85% similar." That number gives an agent a stable evaluation baseline it can try to improve across turns.
Deterministic state and save/load from day one
The test of how close you are to deterministic state is simple: how easily can you save and load an exact state in your game? Kukshtel argues that saving and loading is not a feature to add late — it is a development superpower when programmed in conjunction with the game from the very start.
Thing-driven development: one object type for everything
Kukshtel's central architectural recommendation is to treat every entity in the game as the same kind of object, possibly typed as Thing. In his example, a Thing carries stat-type values, an isAlive flag, and a type enum; implementing code branches on that enum.
The motivating observation is that in a mature object-oriented game codebase, "a tree is a dog" becomes effectively true: a tree is a mesh plus a collider, and a dog is a mesh plus a collider plus movement. From the code's perspective they are compositions of the same components.
The payoff for agents is a single source of truth for the object model. Kukshtel writes that with 100 classes of 100 types, an AI must understand all of them and their relationships to act, which fills context and creates ambiguity about whether to extend a class, morph a type, or add a new class. With one object type, "AI knows exactly where to make changes, every time."
Serialization also collapses to one path in and one path out, avoiding race conditions and polymorphic deserialization problems. A game becomes a giant list of Things; saving is saving all of them through one path, and loading is the reverse. Kukshtel also points to a Wookash podcast episode with creators of Dreams discussing a similar system, and cites Casey Muratori's argument that this is not as memory-expensive as it may appear.
Addressable state and the command pattern
With one object type, every state change targets the same structure, which makes the Command Pattern practical: capture changes as serializable command objects that pass through a processing class rather than mutating objects directly.
The benefit is exact reproduction. Given a starting state and a serialized command log, you can replay exactly what the player did instead of interrogating them about it. An AI agent can also replay commands to assess how its changes affect state.
Commands also do not have to originate from the game. They can be authored in a text editor or by the AI and played back on a running instance with no compiling required. Kukshtel emphasizes that the more a game can change without compiling, the tighter the agentic loop becomes.
External data management
Kukshtel argues that static operational data — the values that describe how things are, such as type, attackDamage, walkSpeed, and boatSpeed — should live outside the game rather than being compiled into it. Changing data then becomes a matter of editing a data source and deserializing, with no build required and no editor access needed.
He describes this as the exact workflow used on Cantata: roughly seven non-programmers on the team received builds plus a custom data editor called Depot, and iterated without him cutting new builds. He is now turning Depot into a standalone product at depot-editor.com. Other teams use Google Sheets or custom tools; Riot Games has published on its own game data server.
Standalone simulation (blackbox architecture)
Kukshtel recommends separating the game's simulation from the engine entirely, as its own DLL or library. The engine sends commands to the simulation and receives updated state back, then interprets the state or the diff against the previous state. The engine is deliberately "dumb": if the simulation says something moved, the engine moves it.
A concrete example: the engine sends a movement request for a Thing, the simulation decides whether the target is valid and resolves the movement, and the engine renders the result. Because anything can send commands to the core, network programming becomes far easier — state can come from the network, an LLM, or anywhere else.
Testing also becomes tractable. Kukshtel argues that game testing is painful largely because state, logic, and data are tightly coupled, and that a separated simulation can be tested with pure C# projects and standard tooling, with no engine running.
He calls this pattern "Blackbox Game Architecture" and cites a Roguelike Celebration talk by Brian Cronin about Monster Train, plus a Game Data Podcast episode with the team behind Solium Infernum.
Impact assessment: profiling that agents can read
Traditional profilers in Unity, Unreal, or IDEs like dotMemory are designed for human consumption — call stacks and graphs. Kukshtel observes that AI does not work well with these tools because they are not legible to the agent, though he notes Unity is doing work to make its profiler more agent-readable.
What agents want is text. Kukshtel recommends samply, a free profiler that can dump capture output to the console, so an agent can read the source and docs, run captures, and evaluate its own changes autonomously.
The full loop
Combining these techniques produces an agentic turn that can run the entire cycle — deterministic input, structured state modification without compilation, verification in isolation, and impact assessment — in seconds. Because the loop is fast, it can run against every change rather than being reserved for changes that "matter."
Kukshtel's conclusion is the title of the talk: the harness is your game. Any game is capable of all of this, meaning any game can be its own harness.
Caveats and counterpoints from the discussion
The Hacker News thread (158 points, 79 comments) surfaced substantial disagreement and several extensions.
The approach may not scale to large 3D games. Commenter avaer argued the Thing approach is "a dead end for a performance budget or layered subsystems," because iterating and copying 30 subsystems of thousands of Things is impossible in frame time, and the only fix is a total rewrite. They point to ECS and SOA as architectures that need a different kind of harness, and note that art dominates the production cycle of modern games, requiring its own category of harness. They also note samply will not diagnose overdraw, and GPU work needs its own ablation and attribution.
Determinism is confining. Commenter bob1029 wrote that "LLMs have completely solved the coding side of game development. But this was never the hard part. Not even close," and argued that maintaining determinism across many platforms is where things get nasty. They suggested diffusion models as an alternative that sidesteps engine integration entirely.
Agents can be inconsistent in ways that defy intuition. Commenter andai reported that frontier models could not change or add a feature to a simple Pong game without breaking something else over weeks of work, while a model one-shotted an entire game roughly 100x more complicated. They speculated about whether the difference is in-distribution behavior.
Some developers report strong results with the same techniques. Commenter vanyle wrote an automated testing system that takes screenshots and simulates input, then documented it in their engine's guide at vectarineengine.com. Commenter theptip said the post matches what they arrived at independently, with screenshots and separated simulation as the biggest wins, and added that agents are infinitely patient — so prompts like "build an interactive design doc with videos of each game mechanic" can make reviewing changes easier. They also flagged observability as underinvested in game dev, suggesting exported time-series metrics for DPS and health would benefit agents disproportionately.
Agents can instrument a game themselves. Commenter TeMPOraL described using Claude Code to get a 1997 PC game running on modern hardware in 30 minutes, then gradually decompiling most of it, extending a shimmed DirectX DLL to run headlessly using Windows' "Private Desktop" feature, and running several game instances in parallel. They concluded: "just let LLMs instrument your game and figure it out on its own."
The practices are old practices. Commenter hatthew observed: "It's kind of funny how it took inventing AI for people to start caring about good software engineering practices (debuggability, iteration speed, reliability, etc.)." Commenter KolibriFly made the same point: "building good architecture for agents just ends up mirroring time-tested software engineering practices." Commenter marcus_holohan described the post as "a tour through 'decouple your entities 101'" and asked whether games are really hard-coded spaghetti.
Skepticism about the creative ceiling. Commenter YesBox, a five-year game dev, predicted LLMs will not take over game development because polishing many small details will remain faster by hand, and because some parts of development cannot be described in words. Commenter dudeinhawaii, a former MMO and indie developer, argued that AI models always create "the mediocre middle," that making a game is not the same as making it fun, and that models are poor at building reusable large-scale architectures — recommending that humans structure the core architecture and use AI to write the code within it.
Domain expertise changes how you judge output. Commenter transitorykris described a specific form of Gell-Mann amnesia: catching bad assumptions in areas where they have expertise, then having to trust the model much more in areas where they do not.
The author's own caveat. Kukshtel closes the post by noting he is currently shipping a project that uses none of these techniques, because the project is very small. He frames the harness approach as relevant to larger projects, and invites readers to share what worked and what did not.
Sources
Related
- Dispatch
- Dispatch
- Project
- Dispatch