An autonomous AI colony administrator for RimWorld. A demonstration of wrapping a complex, stateful simulation in a structured API and driving it with an LLM agent loop allegorical to complex human structures like city planning and resource management infrastructure.
The colony runs itself. The AI reads game state, formulates plans, issues commands, and adapts tick-to-tick without human input.
The goal isn't to win: it's to live long enough to foster a story and collapse in spectacle.
The result is best described as such:
The colony is an ant farm.
This project is a concrete example of the full stack required to put an LLM in the driver's seat of a real, complex system:
- Game ↔ API bridge: A C# RimWorld mod exposes a
localhostREST API, serializing live game state (colonists, map sectors, resources, events, research, designations) into structured JSON on every tick. Commands flow back in over the same channel and execute on the game's main thread. - Typed Python client: Pydantic v2 models mirror the full API surface. Every endpoint has a typed async method. The LLM never touches raw JSON for both safety and function.
- Agentic tick loop: Each game tick, LiteLLM drives a multi-round tool-calling loop against the game state. The agent gathers information, formulates a plan, issues commands, then writes a short handoff note for the next tick. Persistent context is maintained across an otherwise stateless LLM.
- Structured tool gating: Tools are filtered per-tick based on game state (no
set_researchwithout a research bench, nodraft_pawnwithout active threats). Command types are rate-limited within a tick to prevent thrashing. - Spatial awareness: Map sectors are rendered as ASCII grids for detail work and compact JSON for broad surveys. The agent navigates build placement, enclosure detection, and resource location from these representations.
- Error feedback loop: Build failures, footprint conflicts, and type violations flow back to the agent as structured errors within the same tick, and are summarized into the next tick's handoff note. This allows the agent to adapt to a world evolving in real time (or even 3x real time).
This pattern (wrap environment in API → typed client → agentic loop with memory and tool gating) is transferable to any stateful system you want an LLM to drive.
The architecture here uses a general-purpose LLM communicating in natural language. That works, but it carries overhead: every tick, game state must be described in prose and the model must reason through verbose natural language to produce commands. Two natural extensions reduce that cost significantly.
Domain fine-tuning: A model fine-tuned on labeled tick-state → optimal-action pairs would require less context to understand RimWorld-specific concepts (threat types, research dependencies, build constraints) and would produce fewer hallucinated commands. The API bridge already structures the data needed to generate such a dataset.
Compressed command protocol: Apollo mission controllers communicated with spacecraft over bandwidth-constrained channels using compact serial codes. Single bytes represented full operational concepts rather than verbose messages. The same principle can be applied here. A purpose-built model trained on a domain-specific protocol would operate at a fraction of the token cost of natural language while improving command precision. For example, a token represents a build command, a following token the structure type, and so on. Input state could be similarly compressed: rather than describing colonist status in prose, a trained tokenizer maps game state directly to dense protocol tokens the model reads natively.
The trade-offs are real: this approach requires a labeled training dataset (which must be generated), loses the model-agnostic flexibility LiteLLM provides, and makes logs harder to read. But for a production scale deployment, this is the obvious next step the architecture enables.
flowchart TD
subgraph RimWorld["RimWorld (C#)"]
SS["StateSerializer<br/>Serializes live game state to JSON"]
CE["CommandExecutor<br/>Executes queued commands on main thread"]
API["ApiServer<br/>localhost:8765"]
SS --> API
API --> CE
end
subgraph Administrator["Administrator (Python 3)"]
MC["ModClient<br/>Typed async HTTP client"]
AL["AdministratorLoop<br/>Tick / round loop<br/>Tool gating · Command validation<br/>Handoff summarization"]
LLM["LiteLLM<br/>Any compatible model<br/>(Claude, OpenAI, Ollama, etc)"]
MC --> AL
AL --> LLM
LLM --> AL
end
API -->|"GET state"| MC
AL -->|"POST commands"| API
The mod and administrator communicate over a local HTTP server.
The game never waits on the AI. Commands are queued and executed on the next available game tick.
- administrator/ contains all code for the Administrator's operation in Python 3. This should be run from project root.
- docs/ contains all documentation on the system including development setup, endpoint specifications, and more.
- rimworldInterface/ contains all code for the Rimworld mod that surfaces a
localhostAPI layer in C#. This must be compiled and copied into RimWorld'sMods/directory. - scripts/ contains utility scripts for the project in Python 3. These should be run from project root.
Important
Pre-requisites:
- Copy the example props file and set your local Rimworld installation path:
cd rimworldInterface/Source cp RimWorldPath.props.example RimWorldPath.props - Edit
RimWorldPath.propsand update<RimWorldPath>to match your installation:<!-- EXAMPLE PATH! --> <RimWorldPath>C:\Program Files (x86)\Steam\steamapps\common\RimWorld</RimWorldPath>
- Use the buildMod.py script to build the mod and add it to your Rimworld install:
uv run scripts/buildMod.py - Launch Rimworld and enable
Antfarm APIin the mod list. - Load or start a save.
- Verify the API is running:
curl http://localhost:8765/health # Expected: { "ok": true }
The server listens on http://localhost:8765/ and is only accessible from the local machine.
It starts when a save is loaded and stops when you return to the main menu. The API interface is only available while a game is running.
- Configure the Administrator config as desired.
- If using an API-based LLM model, add the API key to the CLI environment or to an
.envfile at the root of the project. - Start a Rimworld save with the API Interface Mod enabled.
- Verify the API is running:
curl http://localhost:8765/health # Expected: { "ok": true } - Start the Administrator:
uv run main.py
Additional documentation is available in the docs/ directory including development setup, endpoint specifications, and more.
Code is distributed under the AGPL-3.0 License.
This project was developed privately prior to open-sourcing under AGPL-3.0.
