Phase 4 of 8
A Roman legion in battle formation on a dry plain, with a thin cyan diagrammatic layer annotating the formations and tracing an arc toward the enemy's exposed left flank
Comstar Game AI

An opponent that plays Rome
rather than cheating at it.

A fogged, no-cheat AI faction for Total War: Rome Remastered, reasoning through Agentic Orchestration and acting through the same console and input surface a person uses.

IN PROGRESS · PHASE 4 OF 8 · CAMPAIGN UI ATLAS
4 of 8 complete phase 4, campaign ui atlas, in progress Build tracker →
The question

Every Total War player knows the AI cheats, and knowing it takes something out of the win.

You bait it into a river crossing and it walks in anyway. You leave a city undefended for fifteen turns and nobody comes. When it does beat you, it usually had a resource bonus to do it with.

So the question here is narrow: can you build an opponent that is hard to beat without giving it anything a human does not have? Not fog of war switched off and a gold cheat running — one that sees what you see, learns from what happens, and has to earn it.

What it is

The shape of it

A local application on a Windows machine reads Rome Remastered through its own scripting and console interfaces, drives it with synthetic keyboard and mouse, and consults a language model for strategy through Agentic Orchestration running on a second box.

The game process is the host and AO is a service it consults, never the other way around. A move is never blocked waiting on a model — a timeout, an error or a malformed response all resolve to a neutral directive and play continues.

Windows box
Total War: Rome Remastered
Process A · game I/O
Process B · agent runtime
Process C · overlay UI
Reach · WebSocket · mTLS
Ada server
AO engine · :8765
The model · RTX 4000 Ada
Doctrine and experience
NO MEMORY READING NO PROCESS INJECTION NO CHEAT COMMANDS
The overlay in use over a Rome Remastered battle: an edge glow, a virtual keyboard, a cursor with an intent marker, and a translucent AO cycle window
What the screen looks like while it plays. The overlay is excluded from every frame the model sees.
Three ideas

What makes it work

Time stops so the machine can think

FREEZE READ DECIDE ORDER RESUME

toggle_game_update freezes the battle sim, turning a real-time fight into an effectively turn-based one. The agent thinks in seconds; the battle never notices.

The model picks the objective, not the moves

{
  "objective": "bleed_and_withdraw",
  "acceptable_own_losses": 0.35,
  "required_enemy_losses": 0.90,
  "abort_if": { "general_dies": true }
}

It never selects an action. It declares a target result, and aggression is computed from that — which also makes the intent checkable after the fact.

Nobody writes down what a good move is

dump_fac_scorefaction strength
UnitHasRoutedbattle event
I_BattleEndoutcome signal
set_ranking_intervalfaction rank

No hand-tuned evaluation function. Rome computes scores, casualties and rankings itself — the agent's opinions are hypotheses, the outcome log is the judge.

What is being built

The component map

Three processes on the Windows box and an engine on a second machine. The split exists so a stalled agent or a hung interface can never leave a key held down.

Process A

Game I/O. Owns the kill switch, never allowed to stall

  • WGC window capture P0 done
  • Ring buffer and frame selection P0 done
  • SendInput actuator P2 done
  • RomeShell console channel P2 done
  • Log tailers P1 done
  • Game state machine P1 done
  • Control state machine P3 done
  • Intent record writer P2 done

Process B

Agent runtime. Allowed to stall

  • Belief store P1 done
  • Deterministic predictors P5 not started
  • View compositor P6 not started
  • Reach client P6 not started

Process C

Overlay UI. Allowed to crash

  • Edge glow P3 done
  • Virtual keyboard P3 done
  • Cursor indicator P3 done
  • AO cycle window P3 done

On ada

The engine and the model, on the same LAN

  • AO session overlay P6 not started
  • The model P6 not started
  • The corpora P7 not started
done in progress not started
Build tracker

How far along it is

4 of 8 complete 0 blocked phase 4 in progress updated 5 September 2026
00

Preconditions and capture DONE

Window detection, WGC window capture of the game window, ring buffer, all three startup self tests.

AcceptSelf tests pass, frames captured at target rate with the overlay stub absent from them.
01

Observation DONE

Background script emitting state and transitions, log tailers, console query channel, belief store with provenance, age and confidence.

AcceptCampaign state reconstructed externally and matching the screen for 20 consecutive turns. No AI involved.
02

Actuation DONE

Console wrapper with the fair play gate, SendInput actuator with dwell and hover, diff based order computation, verification tiers, intent record, vision located HUD controls and modal dismissal.

Accept20 consecutive turns driven end to end, hardcoded, no reasoning, zero desyncs between intended and actual.

Result4 Sep 2026: drove a Julii campaign from turn 1 to turn 25, hardcoded and unattended, verified against Rome's own turn autosaves rather than the run's counters. The run ended when a battle was entered, which belongs to the battle loop phase.

03

Overlay DONE

Process C, four surfaces, event stream, takeover handshake, three control transitions.

AcceptCapture exclusion, click through and non activation self tests all pass with the full overlay live. Kill switch releases everything from any state.

Result5 Sep 2026: `comstar-overlay --self-test` passed against a live game with all five surfaces up — window styles on all five, non-activation, click through at 7 sampled points, and capture exclusion with 0 stray pixels in a 1920x1080 frame. The kill switch half was met first, and mattered more: takeover() deadlocked on a non-reentrant lock and left the lock held, so the kill switch could not run at all. With that fixed, kill releases input from all four control modes.

04

Campaign UI atlas IN PROGRESS

Parse the game's own string tables and join them to measured on-screen geometry, so every panel has both a meaning and a locator. Catalogue every panel, dialog, control and cursor action on the campaign map: what it is, what it means, what it is for, how it opens, how it closes, and whether it blocks.

AcceptZero unknowns across the captured frame corpus, each frame resolved to a named panel carrying a purpose and a close affordance. Every campaign cursor action in the game's own tooltips represented in the atlas, and a held-out frame set named correctly.

Result5 Sep 2026: Julii turn 1 atlas pass — Building Browser opener and unlock line; live Arretium spends (Practice Range 1080, Peasants 100, Hastati 440) with treasury 5000→2300; Lists Military Forces + Family Tree hazard; FIELD CONSTRUCTION (watchtower 200 / fort 500) from Construction <6> with a named general in the field; map orders are left-click once the cursor glyph changes (sword for an army). Phase 4 accept (zero unknowns, every cursor action in atlas, held-out frames) is not closed.

05

Battle loop NOT STARTED

toggle_game_update freeze cycle, output_unit_positions parse, deployment phase handling, post battle harvest.

AcceptA complete battle fought at a fixed tick with no manual intervention, and an after action record written.
06

Deterministic predictors NOT STARTED

Built from Battle_and_Campaign_Formulae.md: melee and charge resolution, fatigue and morale, auto resolve estimate, siege duration, economy projection, movement reachability.

AcceptEvery predictor output paired with an observed outcome in the log.
07

AO integration NOT STARTED

Reach session overlay, mTLS enrolment, direct_agent calls, view compositor, neutral directive fallback, cancellation on stale.

AcceptDirectives influence play, a move is never blocked, every failure path resolves to neutral.
08

Learning NOT STARTED

After action records, the experience corpus, offline consolidation into doctrine.

AcceptRecords written and retrievable, consolidation produces doctrine.
The rules it plays by

Enforced in code, not by good intentions

RuleWhat it means
Fog of warIt sees what a player sees. Every belief carries an age and a confidence that decays.
No cheats, everadd_money, auto_win, force_battle_victory and the rest sit in a hard-blocked set. A run that touches them is tainted and marked.
Declares intentEvery action is declared before it executes. No approval gate, nothing waits — but the record exists.
Single player onlyAutomating multiplayer is cheating other people, which is a different thing entirely.
One advantage it does take, on purpose: it freezes and micros every unit on every tick, faster than any human. That's a deliberate mechanical choice, not an oversight — and the tick rate stays a configurable dial.
The hard part

Windows will lie to you

The interesting engineering here is not the model. It is that the platform reports success for things that did not happen. SendInput blocked by UIPI returns success and does nothing, and Microsoft document that neither the return value nor GetLastError will tell you.

SendInput under UIPI Reports success. Nothing happens. The API can never tell you which.
An overlay that is not click-through Synthetic clicks land on the overlay instead of the game. Identical symptom.
An overlay that activates It takes foreground and receives the input meant for the game. Identical symptom again.
Acting in the wrong game state Clicks during a loading screen do nothing, or queue and fire unpredictably. Map orders with a modal open land on the modal.
WDA_EXCLUDEFROMCAPTURE before build 19041 Degrades silently to WDA_MONITOR, which renders the window blank rather than absent. A black rectangle inside the frame the model reasons over.
SendInput and held keys It does not reset keyboard state. Keys already held interfere with the events it generates.
AO's answer cache AGENTIC_ANSWER_CACHE short-circuits a repeated goal to a cached answer. The same question in a different board state returns the old reply.

Which is why every action in this system is a closed loop: declare, execute, verify by observation, retry. Not because it is elegant, but because the alternative is a system that appears to work and does not.

A battle line seen from a low wide angle, with flat cyan annotation boxes labelling each formation
Built on

Agentic Orchestration

The design set

Ten documents behind the build

Architecture, constraints and acceptance tests live here. The code follows them; when the two disagree, the brief wins until it is revised.

cursor-handoff.md The build brief. Constraints, architecture, build order, open questions
decisions.md Twelve architecture decisions with their consequences, and the risk register
working-agreement.md Roles, the decision rule, the label key
rtw-remastered-integration.md Observation channels, actuation tiers, game state machine, fair play boundary
host-app-architecture.md Capture, input injection, process split, safety layer
host-overlay-ui.md The on screen overlay, and how it stays out of the screenshots
reach-overlay-design.md Session overlay, run modes, connection config, call patterns
bottlenecks.md Eight constraints with the arithmetic behind each
smart-player-architecture.md The general design this one specialises
agentic-orchestration-platform-context.md AO and AO Reach reference
What happens next

Phase 4

Campaign UI atlas

Parse the game's own string tables and join them to measured on-screen geometry, so every panel has both a meaning and a locator. Catalogue every panel, dialog, control and cursor action on the campaign map: what it is, what it means, what it is for, how it opens, how it closes, and whether it blocks.

Done when Zero unknowns across the captured frame corpus, each frame resolved to a named panel carrying a purpose and a close affordance. Every campaign cursor action in the game's own tooltips represented in the atlas, and a held-out frame set named correctly.

No decisions are open. The six from the build brief are settled and recorded there.