4.7 KiB
AGENTS.md
This repository is managed with uv. Use uv run ... for commands so the
project environment and Cython extensions are built/loaded consistently.
Project Layout
src/coolrl_lost_cities/games/classic/game.pyx: Cython Lost Cities engine.src/coolrl_lost_cities/games/classic/deep_cfr/: Deep CFR training, traversal, evaluation, analysis, and CLI code.configs/deep_cfr/: Deep CFR YAML configs.runs/: generated training runs. This path is gitignored and may be a symlink to larger storage.docs/: profiling notes, migration notes, and experiment documentation.
Core Commands
Run lint:
uv run ruff check .
Run all tests:
uv run pytest -q
Run focused Deep CFR tests:
uv run pytest -q tests/games/classic/test_deep_cfr_trainer.py
Run the CLI through the console script:
uv run lost-cities-deep-cfr --help
Equivalent module form:
uv run python -m coolrl_lost_cities.games.classic.deep_cfr.cli --help
Deep CFR Training
Main full config:
uv run lost-cities-deep-cfr train \
--config configs/deep_cfr/deep_cfr_selfplay_full_depth_slot_playability.yaml
Unbounded config:
uv run lost-cities-deep-cfr train \
--config configs/deep_cfr/deep_cfr_selfplay_full_depth_slot_playability_unbounded.yaml
Short capped run:
uv run lost-cities-deep-cfr train \
--config configs/deep_cfr/deep_cfr_selfplay_full_depth_slot_playability.yaml \
--max-iterations 100 \
--save-latest-only
Use explicit run directories for experiments. Put Deep CFR runs under
runs/deep_cfr/ and prefix generated run names with the date:
RUN_DIR="runs/deep_cfr/$(date +%Y-%m-%d_%H%M%S)_deep_cfr_experiment_name"
uv run lost-cities-deep-cfr train \
--config configs/deep_cfr/deep_cfr_selfplay_full_depth_slot_playability.yaml \
--checkpoint-dir "$RUN_DIR" \
--max-iterations 100
Date-prefixed examples:
runs/deep_cfr/2026-05-08_010000_deep_cfr_100iterruns/deep_cfr/2026-05-08_020000_deep_cfr_unbounded
Long Runs
Run long jobs in a real tmux session so the user can attach and stop them.
Do not rely on Codex command sessions for long user-observable training runs.
Start a long unbounded run:
tmux new-session -s coolrl-deepcfr-unbounded -c /home/coolguy/dev/coolrl-lost-cities
uv run lost-cities-deep-cfr train \
--config configs/deep_cfr/deep_cfr_selfplay_full_depth_slot_playability_unbounded.yaml
Attach later:
tmux attach -t coolrl-deepcfr-unbounded
Detach without stopping:
Ctrl+B, D
Stop training:
Ctrl+C
Follow logs from another terminal:
tail -f runs/deep_cfr/deep_cfr_selfplay_full_depth_slot_playability_unbounded/train.log
The unbounded config intentionally has:
run:
iterations: null
max_iterations: null
max_hours: null
checkpoint:
save_iteration_interval: 100
latest.pt is updated continuously; archive checkpoints are written every 100
iterations. If disk is tight, prefer --save-latest-only or increase
save_iteration_interval.
Evaluation And Analysis
Evaluate a checkpoint:
uv run lost-cities-deep-cfr eval \
--checkpoint runs/deep_cfr/<run-name>/latest.pt \
--opponent random \
--games 100 \
--device cpu
Generate analysis plots from metrics.jsonl:
uv run lost-cities-deep-cfr analyze \
--run runs/deep_cfr/<run-name>
Write plots to a separate directory:
uv run lost-cities-deep-cfr analyze \
--run runs/deep_cfr/<run-name> \
--output-dir runs/deep_cfr/<run-name>/analysis
The analyzer reads metrics.jsonl and writes PNG files such as:
analysis_<opponent>_action_distribution.pnganalysis_<opponent>_game_flow.pnganalysis_<opponent>_open_quality.pnganalysis_<opponent>_expedition_outcomes.pnganalysis_<opponent>_calibration.png
Runtime Artifacts
Each training run writes:
metrics.jsonl: structured metrics, one completed iteration per line.train.log: human-readable timestamped logs.runtime_progress.json: latest progress snapshot.latest.pt: latest checkpoint.iteration_*.pt: archive checkpoints when enabled.config.json: resolved config for the run.
If a run is stopped mid-iteration, the in-progress iteration may not appear in
metrics.jsonl. Analyze the latest completed metric row.
Notes For Future Agents
- Prefer
rg/rg --filesfor search. - Use
apply_patchfor manual edits. - Do not commit generated run artifacts from
runs/. - Cython-generated
.cfiles are gitignored; edit.pyx/.pxdsources. - Before committing, run
uv run ruff check .and at least the relevant pytest subset. For Deep CFR changes, runuv run pytest -q tests/games/classic/test_deep_cfr_trainer.py.