Skip to content

Repository files navigation

Kenshi Agent Environment

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.

What works today

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.commands is 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_interface is 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.

How a run works

  1. 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.
  2. The runtime captures a matching screenshot and builds the actions available from that state.
  3. The planner chooses one of those actions.
  4. The runtime reads fresh state and refuses the action if its target, selection, or other requirements changed.
  5. The native mod performs the action and reports whether Kenshi accepted it and what happened afterward.
  6. 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.

Try the mock environment

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 8

The 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/.

Optional EvoGen subject adapter

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 kenshi

The 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.

Set up live Kenshi

The supported live setup currently runs Kenshi on Windows from this repository under WSL. It expects:

  • Kenshi installed through Steam;
  • RE_Kenshi and the KenshiAgentTelemetry native 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 .env

From Windows PowerShell, install the editable live runtime:

.\scripts\bootstrap_live_windows.ps1 -WithOpenAI

Build 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.

Run the agent live

./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-only

plan-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 live

The 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 recover

This 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-test

See the generated ./dev command reference for every option.

Run records and campaign memory

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.

Development checks

Run the complete portable gate from the repository root:

./dev verify-portable

The 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:

The older architecture reconstruction plan, interaction-scope plan, body-shift plan, and Stage 8 acceptance report are historical records, not current authority.

Repository layout

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

Safety

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.

License

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.

About

Safety-first agent environment for Kenshi with telemetry, vision, memory, replay, and guarded Windows input

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages