docs: rewrite README — full feature coverage from 52 merged PRs
This commit is contained in:
1 parent
018852c92d
commit
45a413837b
1 file changed
+343
-89
@@ -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.
|
||||
Reference in new issue
Block a user