Agentic friendly game engine

September 26, 2026
Tags: game llm agentic agent gamedev llm-generated

I have an inner conflict regarding agentic programming. On one side it removes the pride I had on the code I wrote. When I look at old complex projects I feel nostalgia from late night debugging sessions or just looking at my hand formatted files. On the other side, as a problem solver, agentic programming speeds things massively. I try to keep a balance between the two.

My most recent project is a game, where I fully embraced the agentic coding style and gave up pretty much all control I had over the codebase. Instead, I resigned to being the "director". This is a real project I want to succeed, so despite the potential slop I want a high quality product.

The game engine choice

I would have limited control if using a big commercial engine (unity or unreal) and with Godot there is more potential for extensibility, it is still something very big to customize. I want very easy agentic integration for quick iteration.

My solution: My own engine. Not my first rodeo. I won't go into detail about the game engine since it is simple and very basic. What is more interesting is how to make it easier for an agent to work with, and have it not be flaky or buggy.

The engine was built to integrate with the agent as much as possible. None of the items here are new. Most of them are industry standards. Fine tuning them for agent integration is the novelty (for me at least).

Agent integration

Development and Testing

The first thing the agent needs is a way to verify its changes. The fastest tool for this is unit tests. Smaller changes get a test and it is verified. Next level up are not-so-unit tests. These are more complex and may call entire subsystems, but since the system is very fast and lightweight this is still viable even in large numbers.

Another change, more relevant to the multiplayer part, is running an actual server and clients inside the not-so-unit tests. An example: Sending invalid/cheaty packets to the server, and then asserting it was handled correctly. Or even, run a server and another client, and then assert that the client has a valid state despite the cheating attempts from another player. For this, the server/clients and their state must be easily observable and the implementation performant.

Now, the main thing that enables the agent to truly test and verify the changes, especially complex ones: Lua scripting. This allows using lua for controlling the player and validating the changes. It also allows the changes to be verified using lua itself, turning this into an integration testing platform.

With scripting, more levels of testing can be built. A fuzzer was implemented where multiple clients are instantiated and fire multiple valid and invalid events, and then at the end the state for all clients and the server is asserted to be the same. For some noteworthy bugs, they were reproduced using lua and then became part of the CI. This was used especially for network related bugs since they are very annoying to reproduce.

Runtime

Another layer of integration is at runtime.

First thing: Aggressive defensive programming. Asserting very often that things are sane and correct. From null references, ranges, valid enum values, etc. Anything off we abort and dump for investigation. Zero tolerance for invalid states, or even suspicious ones.

For debugging the gameplay itself, an extensive logging system was implemented. It is split across modules, to reduce clutter. It is also hierarchical, containing a higher level event list, and then a very detailed. Failures generate a detailed dump with relevant information for the failure itself. Each run creates a log folder which the agent can then comb through.

The game was implemented to be fully deterministic and multiplayer runs in lockstep mode, where all clients and the server simulate everything and only inputs are sent across the network. This allows for very high reproducibility, making it easy for the agent to reproduce bugs found during gameplay.

Combining defensive programming with loud failures, extensive logging and a fully deterministic engine, when there is an issue, the agent has everything it needs to reproduce the issue and then have the best chance at solving it.

Process

The last thing, was using a more project-oriented approach. For this github issues were used. A labeling system tracks the difficulty and impact, along with labels for which sub system it targets. A type label tracks if it is a bug, performance issue, enhancement, etc. This allows small interactions like "scan for performance related gh issues and solve an easy one" to be made during a quick session.

The agent is instructed to file issues automatically as it finds them. So it might be adding a feature, then find a performance bug and a state drift. Those become gh issues, and thanks to extensive logging, the agent can document steps to reproduce very accurately.

Conclusion

With a custom engine, tailored for working with an agent, fast progress was possible while maintaining a decent amount of quality at the high level. Development still fun. Instead of being the craftsman writing code, now I take the role of a director, demanding results without compromising on quality.