Kenshi Agent Environment lets a language model play a supervised game of Kenshi.
A native mod reads the game state and performs gameplay actions. The Python runtime captures screenshots, builds a list of actions that are valid right now, asks the model to choose from that list, checks the choice against fresh game state, and records what happened.
The model does not write key presses, screen coordinates, native commands, or retry loops. Gameplay actions offered to the model go through the native mod and do not use mouse coordinates. Native requests dispatch when their atomic request file changes; there is no trigger hotkey. The supported launcher starts Kenshi's installed bootstrap, routes its exact Win32 dialog command without synthesizing input, and uses native title commands for Continue, exact save load, and exact Game Start creation. Emergency stop and final host-safety fallback remain a separate input boundary when the native side cannot be trusted to stop itself.
This is experimental software for supervised runs with disposable saves. It is not a general-purpose Kenshi bot.
The current action set covers:
- selecting characters and issuing movement, regroup, building-exit, and map-travel orders;
- approaching people and issuing character orders that Kenshi itself reports as available;
- opening local trade, looting, squadmate, and resource inventories only after a conservative pre-render distance check, followed by Kenshi's exact range result;
- buying, selling, looting, collecting resource output, and moving items between open inventories through Kenshi's own inventory code;
- reading exact resource operator capacity and accepted identities, starting or adopting productive resource work with 1x approach and accepted-operator-gated fastest playback, and monitoring until exact output inventory exists;
- reading a local resource survey;
- pausing, restoring normal game speed, operation-gated stationary acceleration, bounded observation waits, and stopping a run;
- electively shifting into an eligible nearby body; the operation is authorable with an empty roster, while live end-to-end recovery after true total party loss remains unproven; and
- using campaign memory, the fieldbook, and the read-only strategy advisor.
The current 2.0 telemetry contract separately exports the complete player
roster, named platoons and exact membership, active_platoon_id,
primary_character_id, and the complete selected_character_ids set. The
primary is never inferred from roster order. The former squad, per-character
selection flag, and UI-owned selection fields are not compatibility aliases.
The named player-topology-20260809T161112Z live bundle proves two authored
nonempty platoons, tab and exact-selection changes, and save/load restoration
of membership, primary, and selection. Kenshi reset the active tab on load, so
the exporter reports active separately instead of claiming it persisted.
Each character's work record also keeps Kenshi's ordinary order queue,
configured Jobs, permanent Jobs, and current activity separate. Empty Jobs do
not prove that ordinary work is absent, and a matching Job or activity name is
not treated as proof that a controller-issued order remains. Unknown task
targets, queue positions, and unenumerable ordinary-queue totals remain null.
The named task-channels-20260809T172100Z bundle proves one retained ordinary
order beside separate current activity while Jobs and permanent Jobs remain
empty; it does not infer general controller ownership from that similarity.
Natural resources now separately report the engine's exact operator capacity,
complete current accepted-operator identity set, and exact output stacks. A
selected recipient or queued OPERATE_MACHINERY order is not an operator. In
the named resource-operators-20260809T201826Z live bundle, Ribs and Hand were
both selected and both received the exact resource order, but a capacity-one
deposit accepted only Ribs. No work-progress percentage is exported because
the available progress-like native fields do not have a proven
natural-resource meaning, range, or rollover contract.
Live acceptance runs have covered representative movement, trade-window opening, purchases, equipped-item looting, squadmate and resource-output transfers, resource production, human handoff, emergency stop, and a confirmed final pause. Character orders and body shifting were observed in supervised sessions, but no exact named run bundle preserves either complete proof chain. The exact durable classification for each operation is recorded in the proof ledger.
The named native-mining-local-trade-regression-20260810-r1 run proves the
current complete economic loop. Native productive work created one Copper while
plural clock acknowledgements remained visible, collection moved it into
Slowline, physical approach reduced Barman distance from 312.47 to 16.73 before
the trade request, and the sale raised funds from c.20,000 to c.20,195. All 12
action receipts recorded zero primitive input and no plan used a generic
resource operate or planner-authored wait. The committed
reduced evidence artifact
preserves exact requests, acknowledgements, decisive telemetry, binary identity,
raw-file hashes, and the movement-stall caveat.
The later playback-phase-policy-20260810-r4 run proves the narrower playback
policy: a 1,887-unit resource approach remained at 1x while accepted-operator
state was empty, 5x began only after Ruka appeared in the resource's exact
operator set, and a separate 1x request completed before the productive
terminal. The runtime now archives every exact native request in its ignored run
bundle before publication; the committed
reduced playback artifact
preserves those request payloads, matching acknowledgements, decisive frames,
raw hashes, and the excluded interrupted attempts.
There are still important limits:
controller_commands.commandsis plural at both producer and consumer. The temporary one-record producer bridge carried a deletion deadline of 2026-09-20 and was removed early on 2026-08-10; the bounded retained registry is now emitted directly.- Some group behavior is still unproven, including group dialogue participation, mixed-building exits, threat-response scope, and delayed map-travel continuation after changing selection.
- Many controls visible in Kenshi are intentionally not offered to the model. The old pointer-based gameplay handlers were removed instead of being kept as a fallback.
close_active_interfaceis planner-visible when fresh telemetry proves a blocking Prospecting, dialogue, modal, inventory, stats, or management interface.
The exact Protocol 2.0 ownership and retired producer bridge are recorded in the Protocol 2.0 world-model decision.
- The native mod publishes current Kenshi state, including roster and platoon topology, active platoon, primary and complete selection, nearby targets, inventories, dialogue, visible controls, and command results.
- The runtime captures a matching screenshot and builds the actions available from that state.
- The planner chooses one of those actions.
- The runtime reads fresh state and refuses the action if its target, selection, or other requirements changed.
- The native mod performs the action and reports whether Kenshi accepted it and what happened afterward.
- The runtime writes the observation, decision, command, and result to the run log. A live run finishes by returning control and confirming that the game is paused.
Mock and replay runs use the same planner and operation path without controlling a live game.
CPython 3.11, 3.12, 3.13, and 3.14 are supported. The package metadata rejects older and newer feature releases until they are covered by the portable matrix. uv is recommended.
uv sync --extra dev
uv run kenshi-agent doctor --config config/default.yaml
uv run kenshi-agent run --config config/default.yaml --mode mock --steps 8The default config uses a seeded mock world and the built-in heuristic planner. It
does not send input to Windows or Kenshi. Run files are written under runs/.
KAE exposes an optional kenshi subject plugin for EvoGen API 1.1. It is
isolated from ordinary kenshi_agent imports and uses KAE's generated
docs/generated/CAPABILITY_MANIFEST.json as its read-only capability
authority. Install it only on Python 3.11 through 3.13:
uv sync --extra evogen
uv run evogen subject doctor kenshiThe portable gate installs this extra on Python 3.11 through 3.13, so the G15 tests and host conformance checks run there. On Python 3.14 the dependency marker intentionally excludes EvoGen; ordinary KAE tests remain supported and only EvoGen-dependent tests are skipped.
The G15 adapter is synthetic, deterministic, read-only, and conformance-only. Its runner emits typed trajectory evidence with a receipt followed by a later outcome observation, and rejects scenarios outside its opaque conformance suite. It does not launch or control Kenshi, read replay data, touch saves or DLLs, or claim live gameplay capability. G16 observer and run-bundle ingestion remain withheld.
The supported live setup currently runs Kenshi on Windows from this repository under WSL. It expects:
- Kenshi installed through Steam;
- RE_Kenshi and the
KenshiAgentTelemetrynative mod; - CPython 3.11, 3.12, 3.13, or 3.14 on Windows for the live host process;
- the display, graphics, and memory setup checked by
config/live.yaml; and - an OpenRouter API key for the default live planner, or credentials for another configured planner.
Copy the environment template and add the credentials you use:
cp .env.example .envFrom Windows PowerShell, install the editable live runtime:
.\scripts\bootstrap_live_windows.ps1 -WithOpenAIBuild and install the native mod by following its setup instructions. The mod is the main gameplay control interface as well as the source of live telemetry.
Then prepare and check the host:
./dev scenario install-starts
./dev setup graphics
./dev doctor
./dev launch --title./dev doctor only checks the system; it does not send input. ./dev launch stops if
the required Steam login, graphics profile, display, memory, telemetry, or requested
start state cannot be confirmed. Launch itself does not take over the mouse or
keyboard: the settings handoff is a strict native WM_COMMAND, and title/load/pause
transitions are request-file commands handled by the mod.
./dev run is the normal live entrypoint. Start with a planning-only run:
./dev run \
--game-start kae-03-broke-pair \
--objective 'Assess the pair and make one grounded plan.' \
--campaign first-pair-run \
--steps 3 \
--control plan-onlyplan-only reads the game and calls the planner but sends no gameplay actions.
To let the agent act, use a disposable save and choose live:
./dev run \
--game-start kae-03-broke-pair \
--objective 'Find useful work and improve their situation.' \
--campaign first-pair-run \
--steps 12 \
--control liveThe live action path asks for explicit confirmation before entering its supervised control session. Launch does not take desktop input. Press F12 for an emergency stop; ordinary human input hands any active supervised control session back to the operator.
If a run or terminal is interrupted, use:
./dev recoverThis pauses Kenshi and releases display ownership. Use ./dev stop to pause and close
the game through the supported path.
For an interactive terminal launcher, run ./dev tui. Other useful read-only tools
are:
./dev telemetry --watch
./dev affordances --watch
./dev snapshot --label before-testSee the generated ./dev command reference for every
option.
Every run gets a directory under runs/<run-id>/. Its events.jsonl file records
observations, planner choices, action binding, native commands, monitor state,
results, safety events, and finalization. Sending a command is not treated as proof
that the game changed; later telemetry supplies that proof when it is available.
Campaign memory and fieldbook entries are stored in SQLite. Pass --campaign when
runs belong to the same ongoing save. Runs without the same campaign name cannot read
each other's saved claims. The kenshi-agent memory and kenshi-agent fieldbook
commands inspect those records without changing them.
Scenario fixtures are also checked against current telemetry. Naming a scenario or save is not enough by itself to claim that the expected world is loaded.
Run the complete portable gate from the repository root:
./dev verify-portableThe command installs the locked development dependencies, runs tests, Ruff, and
mypy, validates reverse-engineering evidence, regenerates schemas and documentation,
checks their bytes for staleness, and rejects whitespace errors. GitHub Actions runs
that same command on every supported Python version. Files under schemas/ and
docs/generated/ are generated from the current models and registries. Do not edit
them by hand.
Before adding controller-authored behavior for an inferred engine rule, start from the reverse-engineering evidence guide and the reverse-engineering issue form. Each subsystem gets the same validated six-file package; the generated research index shows the current conclusions and withheld boundaries.
Useful current references:
- operation definitions
- interaction catalog
- proof ledger
- native mod and protocol
- Protocol 2.0 world-model decision
The older architecture reconstruction plan, interaction-scope plan, body-shift plan, and Stage 8 acceptance report are historical records, not current authority.
src/kenshi_agent/ Python runtime, planning, actions, and tools
native/ Kenshi native mod and command protocol
game_sources/ Captured Kenshi declarations and research evidence
config/ Mock and live configuration
prompts/ Planner and memory prompts
knowledge/ Strategy reference material
scenarios/ Authored starts and saved fixtures
schemas/ Generated data schemas
docs/generated/ Generated action and interface reports
tests/ Portable tests
runs/ Local run logs; ignored by Git
Use disposable saves and stay present during live runs. Keep unrelated private windows off the captured display. Mock runs, replay runs, and live Kenshi runs provide different kinds of evidence and are not treated as interchangeable.
GPL-3.0-or-later. The native mod links against GPL-licensed KenshiLib. Kenshi is owned by Lo-Fi Games. This unofficial project does not include Kenshi game assets or game binaries.