Skip to content

Commit 8484ad1

Browse files
committed
chore: update CLAUDE.md with just the relevant info
1 parent 40a95f0 commit 8484ad1

1 file changed

Lines changed: 35 additions & 238 deletions

File tree

CLAUDE.md

Lines changed: 35 additions & 238 deletions
Original file line numberDiff line numberDiff line change
@@ -2,255 +2,52 @@
22

33
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
44

5-
## Project Overview
5+
## Overview
66

7-
BalatroLLM is an LLM-powered bot that plays Balatro (a roguelike poker deck-building game) using the BalatroBot client. The bot uses OpenAI-compatible APIs to communicate with various LLM providers and makes strategic decisions based on game state analysis.
7+
BalatroLLM is an LLM-powered bot that plays Balatro using the BalatroBot JSON-RPC API. It communicates with the game via HTTP/JSON-RPC 2.0 and uses OpenAI-compatible APIs (OpenAI, OpenRouter, etc.) for strategic decision making.
88

9-
## Development Commands
10-
11-
### Environment Setup
12-
13-
```bash
14-
uv sync --all-extras --group dev
15-
cp .envrc.example .envrc
16-
# edit .envrc with your OpenRouter API key
17-
source .envrc
18-
```
19-
20-
### Running the Application
21-
22-
**balatrollm** - Main bot CLI:
23-
24-
```
25-
usage: balatrollm [-h] [-m MODEL] [-l] [-s STRATEGY] [-u BASE_URL]
26-
[-k API_KEY] [-d RUNS_DIR] [-r RUNS_PER_SEED]
27-
[--seeds SEEDS] [-p PORTS] [--no-screenshot]
28-
[--use-default-paths]
29-
30-
LLM-powered Balatro bot
31-
32-
options:
33-
-h, --help show this help message and exit
34-
-m, --model MODEL Model name to use from OpenAI-compatible API (required, uses BALATROLLM_MODEL env var if set)
35-
-l, --list-models List available models from OpenAI-compatible API and exit
36-
-s, --strategy STRATEGY
37-
Name of the strategy to use (default: default)
38-
-u, --base-url BASE_URL
39-
OpenAI-compatible API base URL (required, uses BALATROLLM_BASE_URL env var if set)
40-
-k, --api-key API_KEY
41-
API key (default: BALATROLLM_API_KEY env var)
42-
-d, --runs-dir RUNS_DIR
43-
Base directory for storing run data (default: current directory)
44-
-r, --runs-per-seed RUNS_PER_SEED
45-
Number of runs per seed (default: 1)
46-
--seeds SEEDS Comma-separated list of seeds (e.g., AAAA123,BBBB456,CCCC789)
47-
-p, --ports PORTS Comma-separated list of ports for BalatroBot client connections (default: 12346, e.g., 12346,12347,12348)
48-
--no-screenshot Disable taking screenshots during gameplay
49-
--use-default-paths Use BalatroBot's default storage paths for screenshots and game logs
50-
```
51-
52-
**balatrobench** - Benchmark analysis CLI:
53-
54-
```
55-
usage: balatrobench [-h] (--models | --strategies) [--input-dir INPUT_DIR]
56-
[--output-dir OUTPUT_DIR] [--avif]
57-
58-
Analyze BalatroLLM runs and generate benchmark leaderboards
59-
60-
options:
61-
-h, --help show this help message and exit
62-
--models Analyze by models (compare models within strategies)
63-
--strategies Analyze by strategies (compare strategies for each model)
64-
--input-dir INPUT_DIR
65-
Input directory with run data (default: runs/v{version})
66-
--output-dir OUTPUT_DIR
67-
Output directory for benchmark results (default: benchmarks/[models|strategies]/v{version})
68-
--avif Convert PNG screenshots to AVIF format after analysis
69-
```
70-
71-
### Development
72-
73-
```
74-
BalatroLLM Development Makefile
75-
76-
Available targets:
77-
help Show this help message
78-
install Install dependencies
79-
lint Run ruff linter with auto-fixes
80-
format Run ruff formatter
81-
typecheck Run type checker
82-
quality Run all code quality checks
83-
setup Kill previous instances and start Balatro (INSTANCES=1)
84-
teardown Stop Balatro processes
85-
```
86-
87-
### Game Automation
88-
89-
```
90-
Usage: ./balatro.sh [OPTIONS]
91-
./balatro.sh -p PORT [OPTIONS]
92-
./balatro.sh --kill
93-
./balatro.sh --status
94-
95-
Options:
96-
-p, --port PORT Specify port for Balatro instance (can be used multiple times)
97-
Default: 12346 if no port specified
98-
--headless Enable headless mode (sets BALATROBOT_HEADLESS=1)
99-
--fast Enable fast mode (sets BALATROBOT_FAST=1)
100-
--audio Enable audio (disabled by default, sets BALATROBOT_AUDIO=1)
101-
--kill Kill all running Balatro instances and exit
102-
--status Show information about running Balatro instances
103-
-h, --help Show this help message
104-
105-
Examples:
106-
./balatro.sh # Start single instance on default port 12346
107-
./balatro.sh -p 12347 # Start single instance on port 12347
108-
./balatro.sh -p 12346 -p 12347 # Start two instances on ports 12346 and 12347
109-
./balatro.sh --headless --fast # Start with headless and fast mode on default port
110-
./balatro.sh --audio # Start with audio enabled on default port
111-
./balatro.sh --kill # Kill all running Balatro instances
112-
./balatro.sh --status # Show running instances
113-
```
1149

11510
## Architecture
11611

117-
**LLMBot (`src/balatrollm/bot.py`)**: Main bot class with clean architecture featuring Config integration, StrategyManager for template rendering, LLM decision-making with retry logic, response history tracking, and BalatroClient integration.
118-
119-
**CLI Entry Point (`src/balatrollm/__init__.py`)**: Simplified command-line interface with argument parsing and async game execution using modern Python patterns.
120-
121-
**Configuration (`src/balatrollm/config.py`)**: Config dataclass with metadata fields (name, description, author, tags) for enhanced run tracking and version management.
122-
123-
**Strategy System (`src/balatrollm/strategies.py`)**: Lightweight StrategyManager class for managing Jinja2-based strategy templates with built-in strategy support only.
124-
125-
**Data Collection (`src/balatrollm/data_collection.py`)**: RunStatsCollector for structured game execution logging, comprehensive performance tracking, and organized run data storage.
126-
127-
**Benchmarking (`src/balatrollm/benchmark.py`)**: Comprehensive benchmark analysis system with aggregated statistics, leaderboard generation, and hierarchical result organization.
128-
129-
**Strategies (`src/balatrollm/strategies/`)**: Strategy-based organization:
130-
131-
- `default/`: Conservative strategy (financial discipline)
132-
- `aggressive/`: High-risk, high-reward strategy
133-
134-
Each strategy contains:
135-
136-
- `STRATEGY.md.jinja`: Strategy-specific guide
137-
- `GAMESTATE.md.jinja`: Game state representation
138-
- `MEMORY.md.jinja`: Response history tracking
139-
- `TOOLS.json`: Strategy-specific function definitions
140-
141-
**Key Dependencies**: balatrobot, openai, jinja2, httpx
142-
143-
**Game Flow**:
144-
145-
1. Initialize game with run directory and data collection setup
146-
2. Main game loop: Get state → Render strategy templates → Send to LLM with retry logic → Parse response → Execute action
147-
3. Handle game states: BLIND_SELECT, SELECTING_HAND, SHOP, ROUND_EVAL, GAME_OVER
148-
4. Collect comprehensive statistics and generate run reports
149-
150-
**Available Models** (via OpenRouter):
151-
152-
- **OpenAI**: openai/gpt-oss-20b (default), openai/gpt-oss-120b
153-
- **Qwen**: qwen/qwen3-235b-a22b-thinking-2507, qwen/qwen3-235b-a22b-2507
154-
- **X-AI**: x-ai/grok-code-fast-1
155-
- **Google**: google/gemini-2.5-flash
156-
157-
**API Key**:
158-
159-
- `OPENROUTER_API_KEY` (provides access to all providers)
160-
161-
## Code Quality
162-
163-
Uses Ruff (linting/formatting), basedpyright (type checking), pytest (testing), conventional commits, and Release Please automation.
164-
165-
**Modern Type Hints**: Use built-in types for Python 3.9+ instead of typing module equivalents:
166-
167-
- Use `dict` instead of `Dict`
168-
- Use `list` instead of `List`
169-
- Use `tuple` instead of `Tuple`
170-
- Use `set` instead of `Set`
171-
- Use `str | None` instead of `Optional[str]`
172-
- Use `int | str` instead of `Union[int, str]`
173-
174-
## Project Structure
175-
176-
```
177-
src/balatrollm/
178-
├── __init__.py # CLI entry point with argument parsing
179-
├── bot.py # Main LLMBot class with game logic
180-
├── config.py # Configuration dataclass
181-
├── strategies.py # StrategyManager for Jinja2 templates
182-
├── data_collection.py # RunDataCollector for game logging
183-
└── strategies/ # Strategy-based templates
184-
├── default/ # Conservative strategy
185-
└── aggressive/ # High-risk strategy
186-
├── manifest.json # Strategy metadata
187-
├── STRATEGY.md.jinja # Strategy guide
188-
├── GAMESTATE.md.jinja # Game state representation
189-
├── MEMORY.md.jinja # Response history
190-
└── TOOLS.json # Function definitions
191-
192-
balatro.sh # Game automation script
193-
runs/ # Game execution logs (organized by version/strategy/provider/model)
194-
benchmarks/ # Benchmark results (organized by version/strategy/provider/model)
195-
tests/test_llm.py # Test suite
196-
```
197-
198-
## Context7 Library IDs
199-
200-
**Core**: `/coder/balatrobot`, `/pallets/jinja`, `/openai/openai-python`, `/encode/httpx`
201-
**Dev**: `/detachhead/basedpyright`, `/pytest-dev/pytest`, `/pytest-dev/pytest-asyncio`, `/astral-sh/ruff`, `/astral-sh/uv`
202-
203-
## Results Tracking
204-
205-
**Run Data Structure:**
206-
207-
- `runs/v{version}/{strategy}/{vendor}/{model}/{timestamp}_{deck}_s{stake}_{seed}/`
208-
- Each run directory contains: config.json, strategy.json, stats.json, gamestates.jsonl, requests.jsonl, responses.jsonl, run.log, screenshots/
209-
- Strategy-first organization enables easy comparison across vendors/models within strategies
210-
211-
**Benchmark Results Structure (Dual Modes):**
212-
213-
Benchmarks can be generated in two modes using the `balatrobench` CLI:
214-
215-
**By Models Mode** (`--models`):
216-
- `benchmarks/models/v{version}/{strategy}/leaderboard.json` - Models ranked within each strategy
217-
- `benchmarks/models/v{version}/{vendor}/{model}/{strategy}/stats.json` - Detailed model stats per strategy
218-
- Compare different models within each strategy
219-
220-
**By Strategies Mode** (`--strategies`):
221-
- `benchmarks/strategies/v{version}/{strategy}/leaderboard.json` - Models ranked within strategy
222-
- `benchmarks/strategies/v{version}/{vendor}/{model}.json` - Model stats across strategies
223-
- Compare different strategies for each model
224-
225-
## Strategy System
12+
### Core Components
22613

227-
The `--strategy` flag accepts built-in strategy names:
14+
1. **Client** (`src/balatrollm/client.py`):
15+
- JSON-RPC 2.0 over HTTP client using `httpx`.
16+
- Communicates with BalatroBot (Lua) on port 12346 request/response.
17+
- Handles `BalatroError` exceptions.
22818

229-
**Built-in Strategies**:
19+
2. **Bot** (`src/balatrollm/bot.py`):
20+
- Main game loop implementation.
21+
- Flow: Fetch state -> Render Strategy -> Query LLM -> Execute Action.
22+
- Manages game lifecycle (start, play, game over).
23023

231-
- **Default** (`--strategy default`): Conservative, financially disciplined approach
232-
- **Aggressive** (`--strategy aggressive`): High-risk, high-reward approach with aggressive spending
24+
3. **Strategies** (`src/balatrollm/strategies/`):
25+
- Template-based prompt generation system.
26+
- `GAMESTATE.md.jinja`: Renders current game state for LLM.
27+
- `STRATEGY.md.jinja`: High-level strategic guidance.
28+
- `TOOLS.json`: JSON-RPC tool definitions exposed to the LLM.
23329

234-
Each strategy directory must contain **5 required files**:
30+
### JSON-RPC Protocol
23531

236-
- `manifest.json`: Strategy metadata (name, description, author, version, tags)
237-
- `STRATEGY.md.jinja`: Strategy-specific guide
238-
- `GAMESTATE.md.jinja`: Game state representation
239-
- `MEMORY.md.jinja`: Response history tracking
240-
- `TOOLS.json`: Strategy-specific function definitions
32+
- **Transport**: HTTP POST to `http://127.0.0.1:12346`
33+
- **Format**: `{"jsonrpc": "2.0", "method": "...", "params": {...}, "id": 1}`
34+
- **Key Endpoints**:
35+
- `start`: Start a new run (params: `deck`, `stake`, `seed`).
36+
- `gamestate`: specific get state call.
37+
- `play` / `discard`: Action on selected cards.
38+
- `buy` / `sell` / `use`: Shop and consumable actions.
39+
- `select` / `skip`: Blind interactions.
24140

242-
**manifest.json Structure**:
41+
## Key Changes in V1
24342

244-
```json
245-
{
246-
"name": "Default",
247-
"description": "Conservative, financially disciplined approach to Balatro",
248-
"author": "BalatroBench",
249-
"version": "0.1.0",
250-
"tags": ["conservative", "financial"]
251-
}
252-
```
43+
- **State Enum**: Game states are now string enums (e.g., `SELECTING_HAND`, `SHOP`, `GAME_OVER`) instead of integers.
44+
- **Card Structure**: 0-based indexing. Structure is flattened with short codes (e.g., Suit "H", Rank "A", Edition "FOIL").
45+
- **Split Actions**: Complex actions are split (e.g., `shop` -> `buy`, `reroll`, `next_round`).
25346

254-
All 5 fields are required. Strategy versions are independent from BalatroLLM versions.
47+
## Key Files
25548

256-
For comprehensive strategy documentation including Jinja2 templates, validation, and contribution guidelines, see [docs/strategies.md](https://s1m0n38.github.io/balatrollm/strategies/).
49+
- `src/balatrollm/client.py`: JSON-RPC client implementation.
50+
- `src/balatrollm/bot.py`: Main bot logic.
51+
- `src/balatrollm/data_collection.py`: Run logging and stats.
52+
- `balatro.sh`: Helper script to manage Balatro game instances.
53+
- `runs/`: Directory where game execution logs and artifacts are stored.

0 commit comments

Comments
 (0)