Project · Documentation · User Guide · FAQ · Contributing · Status · Releases
BatLLM is a Python/Kivy game, a research artefact, and an educational project. Contributions should preserve all three roles: the application must remain usable, the recorded data must remain interpretable, and changes should not obscure the project's critical framing around AI mediation and literacy.
- Keep pull requests focused on one coherent change.
- Preserve current behaviour unless the change explicitly intends to alter it.
- Add or update tests when behaviour changes.
- Update the relevant documentation in the same pull request.
- Consider macOS, Linux, and Windows when changing paths, launchers, dependencies, or subprocesses.
- Keep destructive or expensive Ollama operations explicit and confirmed.
- Do not let tests write to a user's configuration or real saved sessions.
- Use British English in maintained prose documentation.
For larger features or architecture changes, open an issue before implementation.
BatLLM supports Python 3.10, 3.11, and 3.12. Python 3.12 is recommended.
macOS and Linux:
git clone https://github.com/krahd/BatLLM.git
cd BatLLM
python3 -m venv .venv_BatLLM
source .venv_BatLLM/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txtWindows PowerShell:
git clone https://github.com/krahd/BatLLM.git
cd BatLLM
py -m venv .venv_BatLLM
.\.venv_BatLLM\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txtMain application:
python run_batllm.pyStandalone Game Analyzer:
python run_game_analyzer.pyThe repository also contains scripts/cmr-r, a small Unix convenience launcher that selects the project virtual environment when available.
Most tests do not require Ollama. Live gameplay and the explicitly live test mode require:
- the
ollamaCLI; - a reachable local Ollama service; and
- at least one installed model.
BatLLM uses modelito for gameplay requests and model-management helpers. The repository-supported version is pinned in requirements.txt; contributors should install the complete requirements file rather than installing individual packages manually.
| Path | Purpose |
|---|---|
run_batllm.py |
main desktop launcher |
run_game_analyzer.py |
standalone analyser launcher |
run_tests.py |
cross-platform core, non-live, and full test runner |
src/main.py |
main Kivy application shell and startup/shutdown flow |
src/view/ |
screen controllers and KV layouts |
src/game/game_board.py |
live game, round, and turn coordination |
src/game/bot.py |
bot state and command execution |
src/game/bullet.py |
bullet travel and collision behaviour |
src/game/ollama_connector.py |
model request construction and conversation histories |
src/game/history_manager.py |
authoritative session, game, round, turn, and chat history |
src/game/replay_engine.py |
Kivy-free command parsing and deterministic transition logic |
src/game/session_schema.py |
user-facing saved-session v2 validation |
src/game/session_v3.py |
research trace-v3 structures |
src/analyzer_model.py |
analyser navigation and replay model |
src/llm/service.py |
BatLLM-specific Ollama/modelito lifecycle facade |
src/configs/ |
shipped defaults, alternate profiles, and config loader |
src/util/paths.py |
repository, asset, user-state, and saved-session path resolution |
src/tests/ |
automated tests and smoke helpers |
research/urucon2026/ |
research runtime, schema, experiments, corpus, results, and artefact |
create_release_bundles.py |
cross-platform release archive generator |
create_homebrew_formula.py |
Homebrew formula generator |
validate_packaging_smoke.py |
release-bundle and Homebrew validation |
flowchart LR
P1[Player 1 prompt] --> H[HomeScreen]
P2[Player 2 prompt] --> H
H --> G[GameBoard]
G --> O[OllamaConnector]
O --> M[modelito]
M --> L[Local Ollama model]
L --> O
O --> G
G --> R[Replay engine]
G --> HM[HistoryManager]
HM --> S[Saved session v2]
S --> A[Game Analyzer]
R --> A
HomeScreencollects one prompt per player.GameBoardstarts the round when both prompts are ready.OllamaConnectorbuilds the model messages and maintains independent or shared histories.modelitosends the request to Ollama.replay_engine.parse_model_response()converts the returned text into BatLLM's bounded command grammar.- The live bot executes the command.
HistoryManagerrecords prompts, responses, commands, states, and outcomes.
Each new game receives a fresh connector history. This prevents late responses from a retired game contaminating the next game's model context.
The graphical application exports session schema v2. Each saved round includes a frozen gameplay-settings snapshot; the top-level envelope also records model/runtime metadata. Only completed turns are exported.
The Game Analyzer validates the saved file, replays the ordered commands using the frozen rules, and reports state differences rather than silently approximating incompatible data. Legacy top-level list exports are intentionally rejected.
The URUCON research path is separate from the user-facing v2 export. It records schema-v3 traces through headless entry points and verifies them with the pure transition engine. See research/urucon2026/README.md.
The editable paper is not stored in this repository.
The shipped defaults are in src/configs/config.yaml. src/configs/app_config.py overlays hard-coded fallback values, the shipped YAML, and an optional user YAML.
The active location depends on how BatLLM is launched:
- Source checkout without
BATLLM_HOME: configuration changes write tosrc/configs/config.yaml; relative saved-session folders resolve inside the repository. BATLLM_HOMEset: mutable configuration writes to$BATLLM_HOME/config.yaml; relative saved-session folders resolve below$BATLLM_HOME.- Homebrew: the generated wrappers set
BATLLM_HOMEto~/Library/Application Support/BatLLMunless the user overrides it. - Release bundles: the launchers currently run from the extracted bundle and do not set
BATLLM_HOME; state therefore remains relative to that extracted directory unless the user sets the variable. - Tests:
src/tests/conftest.pysets an isolated temporaryBATLLM_HOMEbefore application configuration is imported.
See STATE_AND_INSTALLATION.md for the compact reference.
| Section | Important keys |
|---|---|
game |
rounds, turns, health, damage, dimensions, movement, context mode, prompt augmentation |
ui |
frame rate, exit behaviour, Ollama startup/shutdown behaviour, title and presentation defaults |
llm |
model, endpoint, request options, prompt files, timeouts, last served model |
data |
saved-session folder |
Do not copy the full YAML into prose documentation. Link to the shipped file and document only behaviour that readers need; this reduces configuration drift.
python run_tests.py coreThis runs the small history/configuration smoke module.
python run_tests.py non-livenon-live is the default mode, so this is equivalent:
python run_tests.pyDirect pytest invocation is also supported:
python -m pytest -q src/testsThe non-live suite is the normal validation path for gameplay, UI logic, analysis, path handling, packaging helpers, and research contracts.
python run_tests.py fullThis command starts the configured Ollama service, runs the suite with live smoke enabled, and then stops the service.
Warning
Use full only when it is acceptable for BatLLM to start and stop the real configured Ollama service.
CI uses:
export KIVY_WINDOW=mock
export KIVY_NO_ARGS=1
export KIVY_NO_CONSOLELOG=1
export PYTHONPATH=srcTests already set an isolated BATLLM_HOME; do not point tests at user state.
python -m compileall -q src run_batllm.py run_game_analyzer.py run_tests.py \
create_release_bundles.py create_homebrew_formula.py validate_packaging_smoke.py
python -m pylint src run_batllm.py run_game_analyzer.py \
create_release_bundles.py create_homebrew_formula.pyThe maintained Pylint gate is configured in .pylintrc and CI.
python tools/check_docs.pyThis checks required documentation, local Markdown and HTML links, the STATUS.md timestamp contract, repository-version references, and the absence of known temporary audit artefacts.
Regenerate Doxygen output only when the public API documentation intentionally changes:
doxygen docs/code/dox_config.propertiesReview generated changes carefully; docs/code/ is large and noisy.
Release bundles and formula rendering:
python validate_packaging_smoke.pyHomebrew-specific unit checks:
python create_homebrew_formula.py \
--create-worktree-archive /tmp/BatLLM-homebrew-source.tar.gz \
--formula-out /tmp/batllm.rb
python -m pytest -q src/tests/test_homebrew_packaging.pyOptional install-level modes mutate the current machine and should be run deliberately:
python validate_packaging_smoke.py --run-installer-smoke
python validate_packaging_smoke.py --run-homebrew-install-smokeCurrent pull requests to main are covered by:
- CI: the complete non-live suite on Python
3.10–3.12across Ubuntu, macOS, and Windows; compilation on every matrix job; Pylint on Ubuntu/Python 3.12. - Multiplatform Validation: release-bundle generation on all three operating systems, Homebrew formula/package tests, and a mock-Ollama integration smoke.
- Python dependency audit:
pip-auditagainstrequirements.txt. - Dependency review: high-severity dependency-diff review when the repository dependency graph is available.
- URUCON research validation: focused research-facing tests, schema validation, experiments, and research-artefact packaging on Ubuntu/Python 3.12 when relevant paths change.
Repository protection may require workflow-level checks rather than every matrix job individually. docs/RELEASE_CRITERIA_1_0.md records the current release gate.
The documentation has deliberately separated roles:
README.md: public project overview and installation.docs/README.md: documentation index.docs/USER_GUIDE.md: game and application use.docs/FAQ.md: recurring questions.docs/CONTRIBUTING.md: development and maintenance.STATUS.md: current snapshot only.docs/CHANGELOG.md: chronological history.
Update the relevant page whenever a change affects:
- UI labels or navigation;
- game terminology or rules;
- configuration keys, defaults, or state paths;
- model-management behaviour;
- session formats or analyzer compatibility;
- supported Python/platforms;
- test or release commands; or
- repository structure.
Do not append PR-by-PR audit narratives to STATUS.md. Record durable current facts there; put historical detail in the changelog, the pull request, or a research audit file whose purpose is explicitly historical.
The repository version is stored in VERSION and mirrored in CITATION.cff and maintained release-facing documentation.
Build release archives with:
python create_release_bundles.pyThe generator creates source, Windows, macOS, and Linux archives under dist/releases/.
Generate a Homebrew formula from a release tag with:
python create_homebrew_formula.py \
--github-tag v$(cat VERSION) \
--formula-out /path/to/homebrew-krahd/Formula/batllm.rbTagged publication to krahd/homebrew-tap is handled by .github/workflows/publish-homebrew-tap.yml when the repository secret HOMEBREW_TAP_TOKEN is configured.
Before a release candidate, use:
Use the root launchers rather than importing src modules directly. The launchers add src/ to sys.path and enforce the supported Python range.
- Confirm that the
ollamaCLI is installed. - Check the host and port in the active configuration.
- Run
python -m llm.service statuswithPYTHONPATH=src. - Inspect the output log in Ollama Config.
- Verify that the selected model exists locally.
Timeout precedence is:
llm.model_timeouts[model];llm.timeout;- built-in common-model defaults; and
- the generic fallback.
The service warm-up timeout is separate and uses llm.warmup_timeout, with a built-in 30-second default.
Use a current v2 session exported after at least one completed turn. Do not edit saved state manually unless testing validation behaviour. The analyzer rejects legacy list exports and malformed identity/state maps intentionally.
Remote catalogue retrieval requires network access. Local gameplay does not require remote catalogue access once an installed model is available.
Run Doxygen only when the source-level API docs should change, then inspect the generated diff before committing.
