AN EMBODIED, GAME-INDEPENDENT AI TEAMMATE

Player 2 has entered the game.

Eyes, hands, ears, and memory — wired to ordinary player I/O. It watches the screen and holds a controller, the same way you do. No game APIs. No memory reading. No injection. If it can't see it or press it, it doesn't know it.

neutral (0,0) chunk accepted preempted preempted again no fresh chunk arrives deadman: pad released
Silence means stop. The pad holds whatever was last commanded — it never invents motion between decisions. The instant fresh intent stops arriving, a deadman timer releases every input. That is the difference between a teammate and a character sprinting into a lake because the model went quiet.

Two reasons to plug in

Play together, or measure against it

Play

An AI teammate, not a walkthrough

Local co-op, campaigns, mod-friendly worlds. It accumulates a shared history with you across a session, argues about strategy, develops favorite tactics, and occasionally saves you — and occasionally does not. The framing is closer to "I gave an AI a controller and taught it how to play" than to a bot that beats a game for you.

Not built for ranked competitive multiplayer, and not intended for it. This is for private matches, co-op, campaigns, local play — the parts of gaming that are about the people (or the teammate) in the room with you.

Benchmark

A motor cortex for evaluating agents

Screen capture, a virtual Xbox pad, one shared clock, a deadman safety boundary, and a recorder that logs what the controller actually did — not what a model proposed. Point any vision-capable model at it through IFastPolicy and you get a real perception-to-action harness with no game-specific glue to write.

Transport is the real cost. One decision through a CLI-shelled agent runs ~12.5k tokens before a single pixel is added — a downscaled JPEG frame is nearly free by comparison. Full numbers in docs/STORAGE.md.

The body, not the brain

Eyes. Hands. Ears. Voice. Memory.

Every capability maps to a channel a human player already has. None of it knows what game it's in — game understanding lives entirely in the model sitting behind these channels.

Eyes

Windows Graphics Capture into a ring buffer, downscaled and perceptually deduplicated before anything reads it.

done
Hands

A virtual Xbox pad over ViGEm. One thread is the sole writer, always — nothing else touches the device.

done
Ears

Game audio and microphone input, timestamped on the same clock as everything else.

planned
Voice

Local faster-whisper and Piper for the loop that must never stall; a cloud model for the words themselves. Opt-in — nothing in core imports it.

planned
Memory

SQLite plus model-curated rules — what it learned about a game and about playing with you, kept across sessions.

planned

No game-specific knowledge in the runtime

The hard constraint

There is no heal_party(). No seek_cover(). No aim_at_enemy(). The lowest abstraction the runtime knows is the human input device: make the pad have these states at these times.

Facts about a specific game — which window to capture, that controller-x mines in Factorio, that ^/ is a forbidden chat prefix — live in a profile TOML file, never in code. A test greps the entire runtime for game names on every change. It has already caught three real leaks. The question for every new piece of code is the same one: could this run unmodified in Factorio, Baldur's Gate 3, and a game that doesn't exist yet?

Five threads, one queue, one bus

Nothing cognitive can stall the hands

Cognition only ever submits. A dedicated scheduler thread is the only thing that ever writes to the controller, which is what makes "it keeps moving while it talks" true by construction — not by hope.

Capture Fast Policy Conversation Command queue Scheduler sole writer, 120Hz tick Pad Event bus Recorder frames submits submits drains emits drains executed history, never proposals writes
  1. The scheduler is the sole writer to the controller. Everything else submits through its queue.
  2. A new chunk resolves against neutral, not live state. Anything it doesn't mention gets released — nothing inherits a held stick by accident.
  3. Absent is not empty. buttons=None inherits; buttons=frozenset() releases everything.
  4. One clock. Everything timestamps from player2.clock; audio drifts against measured sample count, never arrival time.
  5. The recorder captures what happened, not what was proposed. Proposals get preempted, rejected, and overridden constantly.
  6. MCP is the control plane, never the servo bus. Frames and action chunks never travel over it.
  7. Voice is opt-in. Nothing in core imports player2.audio.
  8. Silence means stop. No fresh chunk, no held input — the deadman always wins.

Milestone 1 — reached 2026-08-09

A real game, a real controller, on the record

An agent process manipulated a live copy of Factorio 2.0.7 through the same virtual-pad path a human uses — no API, no memory reading, no injection. In the recorded run: 6 chunks accepted, 5 preemptions as each new intent replaced the last, and the deadman releasing the pad at 6706ms the moment the agent went quiet. The property that matters most held in a real game, not just in tests.

SubsystemState
Clock & action-chunk contractsDone, hardened
Motor system — scheduler, virtual padDone, hardened, verified on hardware
Profiles — game facts as configDone
Window find / focusDone
Eyes — capture, ring buffer, fingerprintDone, hardened
Recorder — synchronized demonstrationsDone, hardened
Agent seam — Observation, policy, loopDone, hardened
Direct SDK transport — Anthropic, OpenAI, CLI, OllamaDone, not yet live-tested
Budget governor — token-rate degrade ladderDone, not yet live-tested
Keyboard / mouse + text entryPlanned
Ears, voice, memory, MCP control planePlanned
414
tests, stable across repeat runs
120Hz
scheduler tick rate
0
game names inside player2/
strict
mypy, clean ruff

Built by adversarial review, not vibes

Every line has an author and a reviewer

Claude — lead engineer

Owns architecture, the tests, the final diff, and validation. Writes the test file first, always — it becomes the spec the implementer works against, not documentation written after the fact.

Codex — consultant

Three tiers routed by stakes: cheap and tightly-specified work, a default implementer, and an escalation for concurrency, lifetimes, and anything that must be released correctly. Implements against Claude's tests, or reviews a diff — never told which model wrote it.

Every finding gets adjudicated — reproduced, or rejected with a one-line reason — and every round is logged with its token cost in docs/DEV-PROCESS.md. That log is treated as a deliverable, not overhead: the goal is a routing policy backed by real numbers instead of vendor benchmarks.

"Unit 2 passed 194/194 with strict types and clean lint — and still had four critical defects that could strand a held controller. A green suite is evidence about the tests, not the code."
"Sol/high found four criticals in Terra's scheduler code, invisible to the full green suite, on two separate units. Anything touching threads, locks, or a resource that must be released gets routed there regardless of diff size."
"The worst bug of the project lived in no diff at all: a virtual controller destroyed and recreated on every CLI run, which the game reads as a controller unplugging — and titles with console ports pause when that happens. Found by a human watching the real system, not by review."