docs: rewrite README — full feature coverage from 52 merged PRs

This commit is contained in:
KoalaTrapLord committed 2026-04-03 20:04:32 +00:00
1 parent 018852c92d
commit 45a413837b
1 file changed
+343 -89
+343 -89
View File
@@ -1,46 +1,179 @@
# Commander AI Lab
A full-stack MTG Commander AI research platform. Simulate hundreds of games overnight, train ML models on the results, and let simulation data automatically shape the AI deck builder — all from a web UI or CLI.
A full-stack Magic: The Gathering Commander research platform. Run thousands of simulated games, train neural networks on the outcomes, build decks with AI that learns from simulation data, get LLM-powered coaching, and play live 4-player battles — all from a single unified system.
## What It Does
---
| Layer | What it is |
|---|---|
| **Monte Carlo Engine** | Pure-Python headless sim — runs thousands of games in minutes, no JVM needed |
| **Forge Engine** | Java/Forge rules-complete sim for ground-truth validation |
| **Overnight Runner** | Unattended batch runner — runs sims, updates sim weights, trains neural net |
| **ML Pipeline** | Outcome-weighted RL nudges card scoring weights; neural net trains on decision logs |
| **Deck Builder** | 7-step LLM pipeline (EDHrec → Scryfall → Ollama) now injected with sim-learned insights |
| **AI Coach** | LLM-powered coaching sessions (Anthropic/Ollama) with streaming support |
| **Web UI** | React + FastAPI dashboard for decks, sims, training, and deck building |
## Overview
Commander AI Lab connects a rules-complete Forge engine, a fast Monte Carlo simulator, an LLM deck builder, an ML training pipeline, and multiple game clients (web, LAN, Unity) into one closed-loop platform. Simulation results feed back into deck building and AI decision-making, so the system improves the more it plays.
### Key Capabilities
- **Batch Simulation** — Run hundreds or thousands of Commander games unattended using Forge (rules-complete) or a headless Python Monte Carlo engine
- **ML Training Pipeline** — Reinforcement learning (PPO) trains a neural net on game decision logs; outcome-weighted scoring nudges card weights automatically
- **AI Deck Builder** — 7-step LLM pipeline (EDHrec → Scryfall → Ollama) with simulation-learned insights injected into prompts
- **LLM Coach** — Streaming coaching sessions powered by Anthropic Claude or local Ollama models, enriched with RAG-retrieved card knowledge
- **RAG Card Knowledge** — ChromaDB vector store over 30,000+ Scryfall cards with semantic search and auto-staleness monitoring
- **LAN Battlefield** — Browser-based 4-player Commander game client with ML-powered AI opponents and precon deck support
- **Unity Client** — Full Unity application with battleground scene, lobby system, WebSocket game state sync, and cross-platform builds
- **Card Scanner** — OCR pipeline for physical card recognition via Ximilar API
- **163 Precon Decks** — Complete preconstructed deck library in `.dck` format
---
## Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ Web UI (React/TypeScript — frontend/) │
│ Deck Builder · Sim Dashboard · Training · Coach │
└────────────────────────┬────────────────────────────────────────┘
│ HTTP/REST + WebSocket
┌────────────────────────┴────────────────────────────────────────┐
│ FastAPI Server (lab_api.py / routes/ — port 8080) │
│ /api/lab/* /api/ml/* /api/coach/* /api/deck-builder/* │
└────────┬──────────────────┬──────────────────┬──────────────────┘
│ │ │
Java subprocess Python sim engine Ollama (local LLM)
(Forge rules) (Monte Carlo) qwen2.5:7b + others
│ │
┌────────┴───────┐ ┌───────┴────────────────────────────────────┐
│ Forge Engine │ │ src/commander_ai_lab/ │
│ (rules- │ │ sim/ — engine, models, rules │
│ complete) │ │ deck_builder/ — 7-step LLM pipeline │
└────────────────┘ │ coach/ — streaming LLM coach │
└────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ Clients │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────────┐ │
│ │ Web UI │ │ LAN Client │ │ Unity Client │ │
│ │ (React/TS) │ │ (HTML/JS) │ │ (C# / URP) │ │
│ │ /ui │ │ /lan │ │ /unity-client │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────────────────────┘ │
│ └────────────────┼────────────────┘ │
│ │ HTTP/REST + WebSocket │
│ ┌───────────────────────┴─────────────────────────────────────────┐│
│ │ FastAPI Backend (lab_api.py — port 8080) ││
│ │ ││
│ │ /api/lab/* Batch simulation (Forge + Monte Carlo) ││
│ │ /api/deck-builder/* 7-step LLM deck construction ││
│ │ /api/coach/* Streaming LLM coaching sessions ││
│ │ /api/ml/* Neural net training + policy server ││
│ │ /api/rag/* ChromaDB vector search ││
│ │ /api/game/* Live game sessions (Forge IPC) ││
│ │ /api/policy/* ML policy decisions for AI players ││
│ │ /ws/game/{id} WebSocket game state streaming ││
│ └───────┬──────────────┬──────────────┬──────────────┬────────────┘│
│ │ │ │ │ │
│ ┌──────┴──────┐ ┌────┴─────┐ ┌──────┴──────┐ ┌────┴──────┐ │
│ │ Forge │ │ Monte │ │ Ollama │ │ ChromaDB │ │
│ │ Engine │ │ Carlo │ │ (local LLM) │ │ (vector │ │
│ │ (Java/JVM) │ │ Engine │ │ qwen2.5:7b │ │ store) │ │
│ └─────────────┘ │ (Python) │ └─────────────┘ └───────────┘ │
│ └──────────┘ │
│ ┌──────────────────────────────────────────────────────────────────┐│
│ │ ML Pipeline ││
│ │ decisions_*.jsonl → update_weights.py → learned_weights.json ││
│ │ → /api/ml/train → neural net checkpoints ││
│ └──────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────┘
```
## Quick Start (Windows)
---
**Prerequisites:** Java 17+, Python 3.10+, Maven 3.8+, [Forge](https://github.com/Card-Forge/forge) built at `D:\ForgeCommander\forge-repo`
## Features
### Simulation Engines
| Engine | Description | Speed |
|---|---|---|
| **Forge** | Rules-complete Java engine — handles the stack, instants, triggered abilities, and all Commander rules. Each game spawns a JVM subprocess. | ~0.04 sims/sec (single-threaded) |
| **Monte Carlo** | Headless Python engine — models combat keywords (flying, trample, deathtouch, lifelink, menace, reach, haste), summoning sickness, tapped state, commander zone, multiplayer targeting, and board wipes. No JVM required. | Thousands of games in minutes |
Both engines feed structured results into the same ML pipeline.
### Deck Builder
The `POST /api/deck-builder/build` endpoint runs a 7-step pipeline:
1. Resolve commander via Scryfall
2. Fetch EDHrec recommendations
3. Fetch Scryfall candidates by category (ramp, removal, draw, lands)
4. Ollama suggests synergy/protection/wincon cards — **simulation insights injected here**
5. Filter by color identity, collection, and ban list
6. Ollama enforces ratios (trim/expand to 99) — **simulation insights injected here**
7. Assemble final deck with smart substitution (guarantees 99-card output)
### AI Coach
LLM-powered coaching with two modes:
- **Full Session** — Deep analysis including removal coverage, ramp quality, draw engine profiling, win conditions, anti-synergy detection, pod meta evaluation, and tempo assessment
- **Quick Digest** — Fast ~5-second summary for rapid feedback
Coaching prompts are enriched with semantically relevant cards from the ChromaDB RAG store (15 cards for full sessions, 8 for quick digests). Supports both Anthropic Claude and local Ollama models with streaming responses.
### RAG Card Knowledge
- **SQLite FTS5** bulk card database from Scryfall data
- **ChromaDB** vector index with natural-language card embeddings
- Automatic staleness monitoring (checks every 6 hours, auto-rebuilds if >14 days old)
- Graceful fallback — RAG failures never block coaching or deck building
### ML Training Pipeline
```
Overnight sims → decisions_*.jsonl
↓
update_weights.py → learned_weights.json (feeds deck builder)
↓
/api/ml/train → neural net training on decision dataset
↓
/api/policy/decide → ML policy serves AI decisions in live games
```
- **Outcome-weighted RL** nudges card scoring weights from game results
- **Neural net** trains on the full decision log dataset
- **Distillation loop** — self-play → collect data → retrain → repeat
- **ELO tracking** and model tournaments for comparing AI versions
- Weights clamped to `[-20.0, 20.0]`, stored in `learned_weights.json`
### Win Condition Tracking
Games are classified by win type — not just "Combat" vs "Other":
- **Combat** — standard creature damage wins
- **Combo** — Approach of the Second Sun, Felidar Sovereign, Happily Ever After, and 30+ known alternate-win cards
- **Drain** — life drain effects
- **Mill** — library depletion
- **Poison** — infect/poison counter wins
Draw games (timeout) are analyzed separately with per-player life-at-timeout snapshots and likely cause identification.
### LAN Battlefield Client
Browser-based 4-player Commander game at `/lan`:
- **AI Bridge** — REST + WebSocket connectivity with ML policy decisions as Priority 1 (falls back to local heuristic AI)
- **Deck System** — 3-tab selector: Precons (163 decks, grouped by set), EDHREC search, and custom deck import
- **Player Panels** — Life counters, commander damage bars, poison/energy/experience/rad counters, emblem management
- **Backend Detection** — Auto-detects the Commander AI Lab backend; works offline with local precon data
### Unity Client
Full Unity application (URP, .NET Standard 2.1) with:
- **Battleground Scene** — 4-seat layout with rotated perspectives, life/poison/commander damage widgets, phase tracker, turn order bar
- **Card System** — Hand, battlefield, graveyard, exile zones with card art, tapped rotation, face-down state, summoning sickness indicators
- **Stack & Mana** — LIFO stack display and 6-pip mana pool
- **Lobby System** — Configure 4 seats (human/AI), POST to backend, WebSocket game state sync
- **Elimination** — Grayscale shader overlay on eliminated players
- **Token System** — Create, tap, add counters, delete tokens
- **Cross-Platform** — Windows, WebGL, Android, iOS build targets
- **Scenes** — MainMenu, Collection, DeckBuilder, DeckGenerator, Simulator, Coach, Scanner, Training, Precon, Battleground
### Card Scanner
OCR pipeline for physical Magic cards using the Ximilar API. Scan cards from photos and match them to the Scryfall database.
---
## Quick Start
### Prerequisites
| Tool | Version |
|---|---|
| Python | 3.10+ |
| Java | 17+ |
| Maven | 3.8+ |
| Node.js | 18+ (for LAN client scripts) |
| Ollama | Latest (for local LLM inference) |
| [Forge](https://github.com/Card-Forge/forge) | Built at `D:\ForgeCommander\forge-repo` |
### Setup (Windows)
```powershell
# 1. Build Forge (one-time)
@@ -51,17 +184,29 @@ mvn package -pl forge-gui-desktop "-DskipTests" "-Drevision=2.0.12-SNAPSHOT" -am
cd D:\ForgeCommander\commander-ai-lab
mvn package "-DskipTests"
# 3. Install Python deps
pip install -e .
# 3. Install Python dependencies
pip install -e ".[rag,dev]"
# 4. Launch
# 4. Pull an Ollama model for the deck builder
ollama pull qwen2.5:7b
# 5. Launch
.\start-lab.bat
# → open http://localhost:8080
# → Web UI: http://localhost:8080
# → LAN Client: http://localhost:8080/lan/
```
Or use the automated installer:
```powershell
.\install-commander-ai-lab.ps1
```
---
## Overnight AFK Runner
Runs batch sims unattended, then updates card weights and trains the neural net:
Run batch simulations unattended, then automatically update card weights and train the neural net:
```powershell
python overnight-run.py # default: 11.5h DeepSeek sims
@@ -74,9 +219,9 @@ python overnight-run.py --no-train # skip neural net training
1. `update_weights.py` — nudges `learned_weights.json` from decision logs (feeds deck builder)
2. `/api/ml/train` — trains the neural net on the full decision dataset
## Sim → Deck Builder Feedback Loop
---
Simulation outcomes automatically improve deck recommendations:
## Simulation → Deck Builder Feedback Loop
```
Overnight sims → decisions_*.jsonl
@@ -90,24 +235,63 @@ Ollama prompts (suggest_cards + enforce_deck_ratios)
Better card recommendations
```
When active, `BuildResult.sources_consulted` includes `"sim_weights"`. No-op until real sim data exists.
When active, `BuildResult.sources_consulted` includes `"sim_weights"`. The loop is a no-op until real sim data exists.
## Deck Builder Pipeline
---
The `POST /api/deck-builder/build` endpoint runs 7 steps:
## API Reference
1. Resolve commander via Scryfall
2. Fetch EDHrec recommendations
3. Fetch Scryfall candidates by category (ramp, removal, draw, lands)
4. Ollama suggests synergy/protection/wincon cards ← **sim insights injected here**
5. Filter by color identity, collection, ban list
6. Ollama enforces ratios (trim/expand to 99) ← **sim insights injected here**
7. Assemble final deck
### Simulation
## ML Pipeline
| Endpoint | Method | Description |
|---|---|---|
| `/api/lab/decks` | GET | List available Commander decks |
| `/api/lab/start` | POST | Start Forge batch (returns batchId) |
| `/api/lab/start-deepseek` | POST | Start Python/DeepSeek batch |
| `/api/lab/status?batchId=X` | GET | Poll batch progress |
| `/api/lab/result?batchId=X` | GET | Get completed batch JSON |
| `/api/lab/history` | GET | List past batch runs |
| `/api/lab/precons/deck` | GET | Fetch precon `.dck` file content |
### Deck Builder & Coach
| Endpoint | Method | Description |
|---|---|---|
| `/api/deck-builder/build` | POST | Build a 99-card Commander deck |
| `/api/coach/chat` | POST | Full coaching session (streaming) |
| `/api/coach/quick-digest` | POST | Fast ~5s coaching summary |
### ML & Policy
| Endpoint | Method | Description |
|---|---|---|
| `/api/ml/train` | POST | Start neural net training |
| `/api/ml/train/status` | GET | Poll training progress |
| `/api/policy/decide` | POST | Get ML policy decision for game state |
### RAG
| Endpoint | Method | Description |
|---|---|---|
| `/api/rag/build` | POST | Build/rebuild ChromaDB index |
| `/api/rag/search` | POST | Semantic card search |
| `/api/rag/status` | GET | Index health and staleness |
### Live Game
| Endpoint | Method | Description |
|---|---|---|
| `/api/game/start` | POST | Create a live game session |
| `/api/game/action` | POST | Submit a player action |
| `/api/game/{id}/actions` | GET | Poll Forge IPC actions |
| `/ws/game/{game_id}` | WS | Real-time game state streaming |
---
## ML Scripts
```powershell
# Update sim card weights from decision logs (runs automatically in overnight-run.py)
# Update card weights from decision logs
python -m ml.scripts.update_weights --min-games 10 --lr 0.05 --dry-run
# Reset weights to defaults
@@ -117,7 +301,7 @@ python -m ml.scripts.update_weights --reset
python ml/scripts/generate_synthetic_data.py
```
Learned weights are clamped to `[-20.0, 20.0]` and stored in `src/commander_ai_lab/sim/learned_weights.json`.
---
## Python Simulator API
@@ -129,52 +313,122 @@ stats = run_simulation(deck, num_games=100, name_a="My Deck")
print(f"Win rate: {stats['win_rate']:.1%}, Avg turns: {stats['avg_turns']:.1f}")
```
The Monte Carlo engine models: combat keywords (flying, trample, deathtouch, lifelink, menace, reach, haste), summoning sickness, tapped/untap state, commander zone, multiplayer attack targeting, and board wipes. It does **not** model the stack, instants, or continuous type-changing effects.
## API Reference
| Endpoint | Method | Description |
|---|---|---|
| `/api/lab/decks` | GET | List available Commander decks |
| `/api/lab/start` | POST | Start Forge batch (returns batchId) |
| `/api/lab/start-deepseek` | POST | Start Python/DeepSeek batch |
| `/api/lab/status?batchId=X` | GET | Poll batch progress |
| `/api/lab/result?batchId=X` | GET | Get completed batch JSON |
| `/api/lab/history` | GET | List past batch runs |
| `/api/ml/train` | POST | Start neural net training |
| `/api/ml/train/status` | GET | Poll training progress |
| `/api/coach/chat` | POST | LLM coaching session (streaming) |
| `/api/deck-builder/build` | POST | Build a 99-card Commander deck |
---
## Project Structure
```
commander-ai-lab/
├── lab_api.py # FastAPI server entry point
├── overnight-run.py # AFK batch runner
├── start-lab.bat # Windows one-click launcher
├── lab_api.py # FastAPI server entry point
├── frontend/ # React + TypeScript web UI
├── ui/ # Legacy static HTML UI
├── install-commander-ai-lab.ps1 # Automated setup script
├── pom.xml # Maven build (Java/Forge components)
├── pyproject.toml # Python package config
│
├── routes/ # FastAPI route modules
│ ├── lab.py # Batch simulation
│ ├── deckbuilder.py # Deck builder pipeline
│ ├── coach.py # LLM coaching
│ ├── ml.py # ML training
│ ├── rag.py # ChromaDB vector search
│ ├── game.py # Live game sessions
│ ├── policy.py # ML policy server
│ ├── precon.py # Precon deck serving
│ ├── scanner.py # Card OCR
│ └── ws_game.py # WebSocket game state
│
├── services/ # Core service layer
│ ├── forge_runner.py # Forge subprocess management
│ ├── draw_game_analyzer.py # Draw/timeout analysis
│ ├── rag_store.py # ChromaDB vector store
│ └── card_text.py # Shared card text builder
│
├── src/commander_ai_lab/
│ ├── sim/ # Monte Carlo engine (engine, models, rules)
│ ├── deck_builder/ # LLM deck builder pipeline
│ │ ├── api/ # Scryfall, EDHrec, Ollama, sim_insights
│ │ ├── core/ # Models, rules engine, assembler
│ │ └── pipeline/ # build_deck.py (7-step orchestrator)
│ └── coach/ # LLM coaching (Anthropic + Ollama)
├── ml/
│ ├── scripts/ # update_weights.py, ml_cli.py
│ ├── training/ # Neural net trainer
│ ├── encoder/ # Feature encoding
│ └── models/ # Saved model checkpoints
├── scanner/ # Card OCR pipeline
├── logs/decisions/ # ML decision logs (gitignored)
└── src/main/java/commanderailab/ # Java/Forge batch runner
│ ├── sim/ # Monte Carlo engine
│ │ ├── engine.py # Game loop
│ │ ├── models.py # GameResult, Card, Player
│ │ ├── rules.py # Combat, keywords, commander rules
│ │ ├── win_condition_parser.py # Alternate win detection
│ │ └── learned_weights.json # ML-learned card weights
│ ├── deck_builder/ # 7-step LLM pipeline
│ │ ├── api/ # Scryfall, EDHrec, Ollama, sim_insights
│ │ ├── core/ # Models, rules engine, assembler
│ │ └── pipeline/ # build_deck.py orchestrator
│ └── coach/ # LLM coaching
│ ├── coach_service.py # Session + quick digest
│ ├── prompt_template.py # System/user prompts
│ └── embeddings.py # Card embedding utilities
│
├── ml/ # ML training pipeline
│ ├── scripts/ # update_weights.py, ml_cli.py
│ ├── training/ # Neural net trainer
│ ├── encoder/ # Feature encoding
│ └── models/ # Saved checkpoints
│
├── lan-client/ # Browser-based LAN battlefield
│ ├── index.html # Entry point
│ ├── engine.js # Game engine + ML AI turns
│ ├── ai-bridge.js # Backend connector + policy bridge
│ ├── player-panels.js # Enhanced player panels
│ ├── ui.js # 3-tab deck selector + setup
│ └── precons.js # 163 precon deck data
│
├── unity-client/ # Unity game client
│ └── Assets/
│ ├── Scenes/ # 11 scenes (MainMenu → Battleground)
│ ├── Scripts/ # C# controllers, models, services
│ ├── Prefabs/ # Card, deck slot, chat bubble
│ └── Materials/ # URP materials + grayscale shader
│
├── scanner/ # Card OCR pipeline (Ximilar)
├── precon-decks/ # 163 preconstructed decks (.dck)
├── sample-decks/ # Sample deck files
├── data/ # Runtime data (ChromaDB, bulk DB)
├── logs/ # Simulation + decision logs
├── docs/ # Architecture docs + schemas
├── tests/ # Test suite
├── scripts/ # Utility scripts
├── .github/workflows/ # CI + Unity build automation
└── src/main/java/ # Java/Forge batch runner
└── commanderailab/
```
---
## Tech Stack
| Layer | Technology |
|---|---|
| Backend | Python 3.10+, FastAPI, Uvicorn |
| Simulation (rules-complete) | Java 17, Maven, Forge |
| Simulation (fast) | Python Monte Carlo engine |
| LLM Inference | Ollama (qwen2.5:7b), Anthropic Claude |
| Vector Store | ChromaDB with all-MiniLM-L6-v2 embeddings |
| Card Database | SQLite FTS5 (Scryfall bulk data) |
| ML Training | PyTorch, PPO reinforcement learning |
| Web Client | HTML/CSS/JS |
| Unity Client | Unity 2022 LTS, URP, C# |
| CI/CD | GitHub Actions |
---
## Known Limitations
- **Monte Carlo engine** — no stack, no instants, no continuous type changes (animated lands don't attack)
- **Forge engine** — each game spawns a new JVM (~2-3s overhead), ~0.04 sims/sec single-threaded
- **Forge winner life total** not captured (quiet mode only reports losers)
- **Deck builder** — Ollama suggestions are only as good as the local model; `qwen2.5:7b` works well
- **Monte Carlo engine** — no stack, no instants, no continuous type-changing effects (animated lands don't attack)
- **Forge engine** — each game spawns a new JVM (~2–3s overhead); ~0.04 sims/sec single-threaded
- **Forge** — winner life total not captured in quiet mode (only reports losers)
- **Deck builder** — Ollama suggestions depend on the local model quality; `qwen2.5:7b` works well
- **LAN client** — EDHREC commander search is a stub (backend-powered, not yet fully wired)
---
## Contributing
Commander AI Lab is an active research project. Check the [open issues](https://github.com/KoalaTrapLord/commander-ai-lab/issues) for areas where contributions are welcome.
---
## License
See repository for license details.