Skip to content

Repository files navigation

Alpha4Gate

Python linux-tests pytest vitest Self-improvement

An AI agent that teaches itself to get better at a task with — zero human input.

It plays, diagnoses what went wrong, produces code-level proposals, and only keeps the ones that prove themselves in games. The task happens to be StarCraft II, but the loops are general. A live React dashboard streams every phase — every proposed fix, every rejection, every win-rate swing — while the agent runs unattended for hours. (Technically an iterative LLM-guided reinforcement learning model with a learned advisor.)

Two complementary learning loops:

  • Advised loop: signal comes from playing an external static opponent (Blizzard's stock SC2 AI). Claude reads the bot-vs-stock games and proposes fixes. Improvement is measured against a fixed bar that never moves.
  • Evolve loop: signal comes from self-play between our own bot versions. No external opponent. Improvement is measured against the bot's own ancestors — a moving target that gets stronger each generation.

Advised drives progress against a known benchmark; evolve keeps the bot improving past it. They catch each other's blind spots.

Advisor Control Panel showing a completed autonomous improvement run
Self-improvement loop
6 fixes proposed, validated, committed
Evolution tab showing a live improve-bot-evolve run with fitness pool, stack apply, and import check
Self-play arena
Live evolve run — fitness pool, stack apply, regression
Live capture — SC2 gameplay, dashboard Decision Log, and backend logs side-by-side
Live capture
Game, advisor decisions, and backend logs streaming together
Reward Trends — per-rule reward contribution over recent games
Monitoring
Per-rule reward contribution over recent games

50% → 83% win rate at SC2 difficulty 4 — reached via 6 code changes the advised loop wrote and validated itself.

v4 → v7 in one unattended 8-hour soak on headless Linux — three auto-promoted bot versions in one night (Splash readiness, defensive structures, stutter-step kiting), each validated head-to-head against its ancestor. Lineage has since extended to v10 under a parallelized 4-way evolve substrate.

What makes this different

Most self-improving ML systems need a human in the loop for reward design, tuning, or debugging. This one closes that loop:

  • Claude reads telemetry like a reviewer — names the specific failure ("attacked before the economy caught up"), not just a scalar reward. Ranked fixes with reasoning.
  • Proposals become real code. Both loops land real commits on master ([advised-auto] or [evo-auto]). Every change must pass pytest / mypy / ruff before shipping.
  • Every change is validated before commit. Advised auto-reverts fixes that don't hold up over N games; evolve rolls back promotions that lose to their own parent. No silent regressions.
  • You can watch it happen. The dashboard streams every phase — proposals, rejections, win-rate swings, generation outcomes — live while the agent runs unattended for hours.

The architecture is task-agnostic — SC2 is the test case because it gives fast, machine-readable outcomes.

Deep dives: Wiki · Active plan


The autonomous learning loop

                    ┌──────────────────────────────────────────────────────┐
                    │          /improve-bot-advised                        │
                    │       autonomous learning loop (4+ hours)            │
                    │                                                      │
  ┌─────────┐       │   ┌─────────┐    ┌─────────┐    ┌─────────┐          │
  │         │       │   │         │    │         │    │         │          │
  │   THE   │◄─────────►│  PLAY   │───►│  THINK  │───►│  FIX    │          │
  │   TASK  │       │   │         │    │         │    │         │          │
  │         │       │   └─────────┘    └─────────┘    └────┬────┘          │
  │ (SC2)   │◄──┐   │                                      │               │
  │         │   │   │   ┌─────────┐    ┌─────────┐    ┌────▼────┐          │
  │         │   └──────►│  TRAIN  │◄───│ COMMIT  │◄───│  TEST   │          │
  │         │       │   │         │    │         │    │         │          │
  └─────────┘       │   └─────────┘    └─────────┘    └─────────┘          │
                    │         │                                            │
                    │         └──────── loop back to PLAY ──────────────►  │
                    │                   (or stop if time's up / 3 fails)   │
                    └──────────────────────────────────────────────────────┘

The loop runs unattended for hours. Each cycle: play N games, Claude reads the results and proposes ranked fixes, apply one, re-run N games to validate, commit if it held, retrain the neural policy, repeat. Quality gates (pytest/mypy/ruff), auto-rollback, a wall-clock budget, and a 3-fail cap keep it safe.

Read the full architecture: improve-bot-advised-architecture.md


The self-play arena

  The bot grows by ancestor chain — each step requires two head-to-head wins:

         v0  →  v1  →  v2  →  v3  →  …

  Each generation plays out as a tournament in the SC2 sandbox:

         Fitness round                          Regression round
         ─────────────                          ────────────────
     imp_1 ⚔ parent (g games)
     imp_2 ⚔ parent (g games)    winners
        ⋮                        stacked  ────►  vN+1 ⚔ vN (g games)
     imp_k ⚔ parent (g games)    into vN+1             │
                                                       ▼
                                              majority wins?
                                              ┌──────┴──────┐
                                             yes           no
                                          commit vN+1   git revert
                                          (lineage      (lineage
                                           grows)       unchanged)

A different kind of loop from the advised one — instead of validating one improvement at a time, the arena generates a pool of orthogonal candidates per generation and lets them compete. Claude proposes the pool; fitness winners get stacked into a new snapshot (with an import-check gate catching bad combinations); regression gates the promotion. Close-losers retry against the next parent; evicted imps get replaced. Every arrow in the lineage is a real auto-commit on master.

Read the mechanism: improve-bot-evolve SKILL.md · gate-reduction plan


How we watch it run

      autonomous learning loop                  StarCraft II game
      ─────────────────────────                  ─────────────────
      PLAY → THINK → FIX →                       (THE TASK)
      TEST → COMMIT → TRAIN
               ▲                                        ▲
               │                                        │
        observe the loop                         observe the game
               │                                        │
      ┌────────┴────────┐                      ┌────────┴────────┐
      │ Advisor tab     │                      │ JSONL logs      │
      │ Evolution tab   │                      │ SC2 client      │
      │ state.json      │                      │ replays/        │
      └─────────────────┘                      └─────────────────┘

Two things are running: the loop and the task it's learning from. The dashboard has a tab tuned to each vantage point, plus a state file that's the single source of truth for which phase is executing right now. Stuck-loop detection, alert rules, and operator overrides all hang off these views.

For the advised loop that's the Advisor tab + data/advised_run_state.json; for evolve it's the Evolution tab + data/evolve_run_state.json (plus data/evolve_pool.json for the current pool and data/evolve_results.jsonl for per-phase outcomes). Same pattern, different loop.

Read the full monitoring guide: monitoring.md


Why not just have Claude do everything?

Claude is good at thinking and slow at acting; real-time games need the reverse. A Claude CLI call takes seconds to respond, but the bot observes the game every ~0.5s and issues dozens of actions per second during fights.

So the tight loop runs on rule-based strategy + a PPO policy network (both decide in milliseconds). Claude is used only where latency doesn't matter: mid-game advice (fire-and-forget, rate-limited), post-hoc diagnosis between batches, and writing the fix itself.

Fast-and-dumb does the playing. Slow-and-smart does the learning.


The Story So Far of Alpha4Gate

  • Original Motivation - Beat my friend at a video game using AI.
  • The basic bot - A rule-based bot player that built units and hoped for the best.
  • Teaching it to think - Added a neural network so it could learn.
  • Learning to fight - Targeted lessons: keep the army together, deny expansions, hold the line.
  • Bringing in a coach - Claude whispers strategy tips mid-match alongside human commands.
  • The observation deck - A live dashboard showing every decision, reward, and training run.
  • The robot that trains itself - A daemon that plays, scores, promotes winners, and rolls back duds overnight.
  • The first soak test - Left it alone — 17 things broke. Fixed them all.
  • Claude as personal trainer - Claude watches games, diagnoses problems, and writes the fixes itself.
  • The breakthrough - Self-improvement took win rate from 0% to 75% at difficulty 3.
  • Reality check - Harder opponents exposed that training scores lie — need honest exams.
  • The big merge - Three plans became one: every future bot is a snapshot that must beat its ancestors.
  • Memory matters - Added memory (LSTM) and a gentler training recipe — 19/20 wins at difficulty 3.
  • The arena - Bot versions fight each other in sandboxed self-play. Elo ladder + promotion gate decides who ships.
  • Overnight run, zero promotions - Three compound 60% filters made the math impossible, dropped the redundant composition check.
  • The arena produces winners - 7 hours, v0 → v1 → v2 — the self-play loop ships its first two auto-promotions.
  • Headless training substrate - Moved the heavy training off Windows onto a headless Linux runtime (massive speed increase)
  • Three promotions in one night, on Linux - First end-to-end successful headless evolve. v4 → v5 → v6 → v7 in one 8-hour unattended soak
  • Parallelizing the arena - Evolve now runs four candidates in parallel per generation (concurrency window + worker-slot recycling). Steps 1-7 plus iter-3 hardening shipped 2026-04-30; subsequent generations took the lineage to v10.
  • Now - Self-play evolution is producing auto-promotions unattended on a parallel substrate that scales beyond a single Windows desktop. Claude proposes orthogonal improvements, the arena filters, master advances. The platform from the earlier phases now has a working growth engine on top of it — and it runs anywhere Linux + SC2 will run.
  • Next - Phase O scripted Hydra v1 (themed expert sub-policies with a rule-based switcher), then multi-race support: Zerg first, then Terran. Each race gets its own bot lineage competing on the Elo ladder.

Stack
Layer Tool Why
Language Python 3.12 SC2 libraries are Python-native
SC2 interface burnysc2 v7.1.3 Async BotAI, actively maintained
AI advisor Claude CLI (OAuth or API key) Strategic advice mid-game, async subprocess
Build orders Spawning Tool API Community build order database
Backend FastAPI WebSocket + REST for dashboard
Frontend React + TypeScript + Vite Live dashboard with game state streaming
Deep learning PyTorch + Stable Baselines 3 PPO policy network for strategic decisions
Training data SQLite Structured (s,a,r,s') transition storage
Testing (Python) pytest 1448 unit tests, SC2 integration markers
Testing (Frontend) vitest + jsdom + @testing-library/react 119 component / hook / lib tests
Linting ruff + mypy Strict type checking, consistent style
Setup

Prerequisites

Install

  1. Install Python dependencies:

    cd Alpha4Gate
    uv sync
  2. Create .env from template and fill in your keys:

    cp .env.example .env
    # Edit .env: set SC2PATH, SPAWNING_TOOL_API_KEY
    # Claude advisor auth: claude CLI must be on PATH with OAuth token or API key
  3. Install frontend dependencies:

    cd frontend && npm install && cd ..

Dashboard

# One-shot: start backend + frontend together (Git Bash)
bash scripts/start-dev.sh

# Or in two terminals:
# Terminal 1: backend
uv run python -m bots.v0.runner --serve

# Terminal 2: frontend dev server
cd frontend && npm run dev
# Opens http://localhost:3000 proxying to :8765
Dashboard tabs
Tab Purpose
Advisor Live advised-run status, loop controls, strategic hints, reward injection
Evolution Live improve-bot-evolve run — fitness pool, stack apply, regression, generation outcomes
Improvements Unified timeline of advised + evolve improvements with source filter (refresh-on-demand)
Processes Live system process monitor, port status, state files, backend restart
Alerts Severity-filtered alert list with ack/dismiss + unread badge in nav
Help Renders documentation/wiki/operator-commands.md from disk

In-app AlertToast lives at the App root and shows new alerts as they fire, regardless of which tab is active.

Usage

Run a game

# Single game vs Easy AI
uv run python -m bots.v0.runner --map Simple64

# Options
--difficulty 3       # AI difficulty 1-10 (default: Easy)
--realtime           # Watch in realtime
--batch 5            # Run 5 games, aggregate stats
--build-order 4gate  # Select build order (default: 4gate)
--serve              # Start dashboard API server only
--no-claude          # Disable Claude advisor

Running without Claude

The Claude advisor is optional. Pass --no-claude (or simply don't install the claude CLI) and the bot runs entirely on its rule-based strategy + optional PPO policy. Skip step 2's Claude-auth note during setup.

What still works without Claude:

Feature Notes
Rule-based play vs SC2 AI uv run python -m bots.v0.runner --no-claude --difficulty 3
Batch runs + stats aggregation --batch 10 --no-claude
Neural (PPO) play and training Rule-based or hybrid decision mode; training loop is Claude-free
Dashboard — Evolution, Improvements, Processes, Alerts, Help All non-Advisor tabs render and update as normal
Daemon loop (auto-training, promotion, rollback) Does not call Claude

What needs Claude:

  • Advisor tab and the /improve-bot-advised autonomous improvement loop
  • Mid-game strategic advice — the bot's claude_advisor.py subprocess (visible in JSONL game logs and surfaced on the Advisor tab when an advised run is active)

Quick start without Claude:

uv sync
cd frontend && npm install && cd ..
uv run python -m bots.v0.runner --map Simple64 --difficulty 3 --no-claude --realtime
# In another terminal, watch the dashboard:
bash scripts/start-dev.sh
Testing & project structure

Testing

uv run pytest              # 1448 unit tests (no SC2 needed)
uv run pytest -m sc2       # SC2 integration tests (SC2 must be running)
uv run ruff check .        # Lint
uv run mypy src bots --strict  # Type check
cd frontend && npx tsc --noEmit  # TypeScript check

Project layout

Alpha4Gate/
├── bots/v0/                 # 55 Python modules (the lineage seed)
│   ├── commands/            # Strategic command system (parser, interpreter, executor, queue)
│   ├── learning/            # PPO training, neural_engine inference, features, rewards, imitation, winprob_heuristic
│   ├── bot.py               # Main BotAI subclass, game loop orchestration
│   ├── decision_engine.py   # Strategic state machine (6 states)
│   ├── give_up.py           # Win-prob-based resign trigger (Phase N)
│   ├── army_coherence.py    # Staging, grouping, engagement/retreat
│   ├── claude_advisor.py    # Async Claude CLI subprocess
│   ├── api.py               # FastAPI server (REST + WebSocket)
│   └── ...                  # scouting, config, macro, micro, etc.
├── bots/v1..v10/            # Promoted snapshots — each a self-contained stack with its own data/
├── bots/current/            # Thin pointer package (MetaPathFinder → active version, v10 today)
├── src/orchestrator/        # Version registry, snapshots, self-play, Elo ladder, evolve
├── tests/                   # 1448 unit tests across 88 files (+ SC2 integration markers)
├── frontend/                # React + TypeScript dashboard (Vite, 6 tabs)
├── scripts/                 # Live test, training analysis, evolve runner, sandbox hook
├── documentation/wiki/      # Project wiki (start with index.md)
├── documentation/plans/     # Active plans (alpha4gate-master-plan.md)
├── documentation/archived/  # Completed plans
├── bots/<v>/data/           # Per-version state: training.db, checkpoints/, reward_rules.json
├── data/                    # Cross-version state: ladder, evolve runs, advised state (gitignored)
├── logs/                    # JSONL game logs (gitignored)
└── replays/                 # SC2 replays (gitignored)
How the bot plays — layers & design decisions

Layered architecture

Claude Advisor (async, non-blocking subprocess)
        |
Neural Engine — PPO policy network (optional, hybrid or pure RL mode)
        |
Strategy Layer — state machine: opening -> expand -> attack -> defend -> fortify -> late_game
        |
Command System — parser -> interpreter -> executor (AI-Assisted / Human Only / Hybrid)
        |
Tactics Layer — macro manager, scouting, production balance
        |
Coherence — army staging, grouping, engagement/retreat decisions
        |
Micro Layer — army movement, kiting, focus fire, ability usage

The bot follows a build order during the opening, then transitions to dynamic decision-making. Claude provides optional strategic advice via async subprocess calls (rate-limited to 1 per 30 game-seconds). The neural engine can override or supplement rule-based strategy decisions using a PPO-trained policy.

Key design decisions

  • Layered separation: Strategy, tactics, coherence, and micro are independent modules with clear interfaces, testable in isolation
  • Async Claude advisor: Fire-and-forget subprocess call, bot never blocks waiting for AI advice
  • Deep learning pipeline: PPO policy via Stable Baselines 3, SQLite transition storage, imitation learning bootstrap, gymnasium environment wrapping SC2 state. Hybrid mode combines neural + rule-based decisions
  • Strategic command system: Three execution modes (AI-Assisted, Human Only, Hybrid), natural language parser with recipe library, command queue with priority and TTL
  • Defensive fortification: FORTIFY strategic state triggered by threat assessment, BuildBacklog for deferred production retry, FortificationManager places cannons and shield batteries at expansion choke points
  • Army coherence: Staging areas outside enemy range, group-based engagement with critical mass gate, retreat decisions based on relative army strength
  • JSONL logging: Extended schema with strategic_state, decision_queue, and claude_advice for decision debugging
  • Cross-game persistence: JSON files in data/ and SQLite for training transitions
  • Build order system: Named build orders importable from Spawning Tool API, sequenced by supply thresholds

Wiki: documentation/wiki/index.md — system diagram + page map Active plan: documentation/plans/alpha4gate-master-plan.md


Acknowledgments

Special thanks to my friends for their support:

  • Drew Goya
  • William Gathright
  • Willie Williams

Also thanks to all the creators and companies who made the mountain of tools this is built on (and anyone else I forgot).

About

Self-improving SC2 Protoss bot: rule-based + PPO + Claude advisor, with autonomous code-level self-improvement loop.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages