Inferring an engine from inside

Austin Wagner

A game ships as an obfuscated Java binary whose class names change between releases. I inject code into its running JVM to read real state and issue real orders, with no pixels and no synthetic input, and I made the result bit-identical per seed within one environment so a better strategy can be told apart from a lucky map.

Problem
Measure strategies against a closed engine, when the engine is deliberately scrambled and any claim about its internals rots on the next release.
Result
A headless harness reading real state from inside the JVM, with runs certified bit-identical 12 of 12 pairs over 250 samples each, same seed and same environment.
Scale
201 authored doctrine files and 235 sweep definitions committed, plus 554 generated candidates the repository refuses on purpose.
Stack
Java agent and bytecode patching, Python planning and evaluation, Postgres-backed match queue.
Full record
Its own wiki of 5 hubs and 56 pages, with a dated log of every measurement and verdict.

Inside the runtime, not looking at the screen

A Java agent injected into the game's own JVM dispatches orders and serializes simulation state out; a Python package does the planning. The game boots fully headless, so there is no virtual framebuffer, no screen scraping and no synthetic input anywhere in the loop.

That is the distinction against most work described as game AI: nothing here reads pixels or fakes clicks, so nothing here is measuring a vision pipeline by accident.

The obfuscation problem, gated rather than noted

The jar is obfuscated and class names change silently between releases, so every claim about engine internals carries the game version it was established against. An unpinned claim rots without announcing it.

The build patches the real jar and lets the JVM's own bytecode verifier check the result, so a moved obfuscated class fails at the build gate rather than inside a live engine. The verifier is someone else's, which is the point: it has no reason to agree with me.

The control that makes the rest mean anything

Seeded generators, lockstep world handoff and a pinned frame delta make a solo run bit-identical per seed, with a world digest in the trace that proves it. The digest is computed each sample from every visible entity's identity and position, so two traces that agree on it agreed about the whole board, and the frame where they stop agreeing names the leak.

WHY THE WORLD COLUMN AND NOT THE SCORECARD. A scorecard is an endpoint, and
two runs can reach the same verdict by different routes -- the determinism
campaign's forked pairs frequently ended alike. The trace's world digest is
computed per sample from every visible entity's identity and position, so two
traces agreeing on it agreed about the whole board at every step.

clients/RustedWarfareBot/src/rw_bot/harness/replication.py, module docstring.

The certified property is exact and narrower than it sounds: same seed, same environment, same match, held across a 24-member panel in Docker and on the cluster alike. The same members compared across the two environments diverge from frame 300, so cross-environment identity is an open question, and the pinned delta is a new regime whose numbers are not comparable to earlier batches.

Experiments are controlled by construction too: the file declaring behaviour flags has no optional fields, so an experimental arm differs from its control by exactly what the experiment says it does. Sweeps freeze a code snapshot per batch, which keeps the working tree editable while a run is in flight. Keeping the refutations is deliberate: a directory holding only the configurations that worked is not an experimental record.

Record

Every figure above is bound to a named section of the wiki page rustedwarfarebot and checked mechanically before this page can deploy. The project keeps a second, deeper wiki of its own for engine internals and mechanics, versioned against the jar it was read from, and it is public.

Known limits. The counts move fast and are dated rather than fixed. Until 2026-09-14 this page said 729 doctrine files; that was a working-tree count that summed the authored files with the search drivers' per-round candidates, which the repository ignores because a committed round would read as a hand-designed arm. The standing target, a measured win rate against the built-in AI at its hardest setting, is a goal on that page, not a result claimed here. The project was paused green in August and is active again; the source page said "paused" for three weeks after it was not.

Sources