Public preview New: UI & input · gameplay mods · gateway · MCP

Let any LLM agent design Warcraft III AI on its own

War3AI turns the game into an API designed for agents. The full state of the entire map every 50 ms, semantic commands that land in about one frame, and a receipt and reason code for every one. Hand the docs to Claude, GPT, Gemini, Qwen or any agent — it writes a bot, plays a game, reads back the results and improves on its own.

Windows 10/11 · Warcraft III 1.27a · Double-click start.bat, the rest installs itself

agent-session inst 20 1.27 2×
You

Human. Pull the hero home when its HP drops below 40%; after dark, once there are 3 soldiers, go clear the nearest creep camp.

Read llms.txt and api.json and generated night_raider.py, using only 8 verified APIs.

night_raider.py api.json BOT_HANDBOOK.md
from openwar3 import Bot

class NightRaider(Bot):
    def on_tick(self, g):                     # about 5 times per second
        halls = g.my_buildings({"htow", "hkee", "hcas"})
        army, camps = g.my_army(), g.creeps()
        if not halls:
            return
        home = halls[0]
        with g.batch():                       # submit this tick's commands at once
            for h in g.my_heroes():
                if h.hp < h.hp_max * 0.4:     # keep the hero alive
                    g.move(h, home.x, home.y)
            if g.is_night() and len(army) >= 3 and camps:
                camp = min(camps, key=lambda c: g.path_distance(home, c) or 1e9)
                g.attack_move(army, camp.x, camp.y)   # creep at night

    def on_event(self, g, ev):
        if ev.kind == "production.done" and ev.owner == g.me():
            print("done", ev.done_code, f"{ev.value:.1f}s")
Minimap 21:40 · Night
last_seen · 42s ago walk_path → attack_move
Event stream Live
  1. production.donehbar → hfoo · 14.9s
  2. order.changedHamg → attack
  3. damagehfoo → ngno −14 · normal
  4. receiptattack_move ×5 ✓ accepted · 6 µs
Connected Snapshot #18342 · 50 ms 12 commands this tick · one batch fair=True

Works with any model or agent that can write code or output JSON

Claude GPT Gemini DeepSeek Qwen Kimi GLM Llama Claude Code Cursor Codex LM Studio Ollama
50 ms
Full-map state push interval
Adjustable down to 16 ms; a client reads one in ~0.4 ms
~1 frame
Command latency
4~8 µs per command on the game thread
3,000 cmd/s
Command throughput
6 concurrent processes, median wait 0.06 ms
103
APIs
98 with the underlying path verified in live games
1,024
units with full state
HP/mana, orders, current target, cooldowns, buffs, inventory

Figures are live measurements on a 1.27 test instance (2026-09-23 / 24). See Platform · Performance for how they were measured.

Workflow

From one sentence to an AI that fights

No programming required. You explain how you want it to play; the agent writes the code, plays games, reviews the results and keeps iterating until you're happy.

  1. 01

    Describe your strategy in plain language

    “Human. Archmage first; two barracks making footmen and riflemen; at 12 units, go hit their expansion; pull the hero back below 30% HP.”

  2. 02

    The agent reads the docs and writes a bot

    Hand it llms.txt, api.json and the manual. The API uses the game's own names (four-character codes, ability names), so the model understands it right away.

  3. 03

    Play a game with one command

    tools/play.py launches the game, injects the runtime, starts the match and spins up the bot. Game speed, races, difficulty and fair mode are all flags.

  4. 04

    Read receipts and events, then iterate

    Every command returns a receipt and a reason code, and the event stream records every hit, every kill and every production. The agent uses them to pinpoint problems, fix the code and play again.

Steps 2–4 form a closed loop: receipts and events are structured data, so the agent knows what went wrong without looking at the screen. Autonomous agent loop
Capabilities

An API designed for agents

Zero-wait observation, a receipt for every command, events for every outcome — exactly the structured, verifiable, self-correcting feedback a model needs.

Full world state, zero wait

Resources and food for 16 players; HP/mana, orders, current target, cooldowns, buffs and inventory for up to 1024 units; ground items, trees, production queues, time of day. The runtime pushes it all to shared memory, and reading a copy takes ~0.4 ms.

Semantic commands, each with a receipt

Move, attack, gather, build, train, cast, learn skills, revive, use items, buy… Whether it was accepted, and why not, comes back in the same frame.

Event stream

Units appearing / dying, order changes, hero level-ups, items appearing; engine-level damage for every hit (source, attack type, pre-armor damage) and production completion — your opponent's too.

Batched, executed in one frame

Commands inside with g.batch() are submitted as a single batch. In testing, 8 moves dropped from 68 ms to 6.5 ms.

Combat math and pathfinding

stats / time_to_kill use the game's own counter table and live tech levels; path_distance / walk_path run A* on the engine's terrain grid.

Fair mode

See only the units, items, production and events within your vision; last_seen remembers enemies in the fog. That's the Arena rule.

Docs built for models

api.json is generated from code, and every API is labeled with its test status, latency tier and mechanism, so the model never has to guess. llms.txt / llms-full.txt let an agent read the whole site in one go.

Architecture

One runtime, one protocol, any AI

The runtime is injected into the original game, where it captures the whole world, executes commands and reports results on the game thread. Your AI talks to it through a versioned W3P protocol — with the Python SDK, or any language that can read and write shared memory.

Your agent / bot
Any model, any language
Claude CodeCursorChatGPTQwen local modelPython botReference AI
Decisions
import openwar3 · or the WebSocket / JSON gateway · MCP
OpenWar3 SDK
Python · openwar3
Game / Botw3world snapshotw3fast fast lanecombat calculatorpathingw3claim arbitrationcanvas overlayjass channelschemes
Interface
World pushed every 50 ms · commands land in ~1 frame · a receipt for every one
W3P protocol v2
Shared memory · zero-copy · versioned
War3WorldWar3EventsWar3MapWar3TreesWar3Fast command lanesWar3Canvas overlay
Protocol
Executed in batches on the game thread · 4~8 µs each · 4 ms budget per drain
W3 Runtime
Runs on the game thread
World state publisherEvent streamSemantic command executorQueriesPermissions and viewsSelf-drawn canvasJASS callsVersion supportHealth and circuit breakers
Runtime
War3.exe 1.27 · the original game, no files on disk modified
Code

Writing it feels
like commanding an army

The facade is just two classes. Bot drives the ticks; Game handles seeing and doing. Units use four-character codes and abilities use order strings, the same names the game uses.

  • Missing data is None, not 0
  • Commands take a single unit or a list
  • Shift-queue: queue='after'
  • Receipt accepted ≠ done: check effects in snapshots and events
Mental model: snapshots, commands, events, ticks
from openwar3 import Bot

class FocusFire(Bot):
    """Focus fire on the enemy that dies fastest, not the nearest one; pull wounded units home."""

    def on_tick(self, g):
        army, halls = g.my_army(), g.my_buildings()
        foes = [e for e in g.enemies(fighters_only=True) if e.visible_to(g.me())]
        if not army or not foes or not halls:
            return
        home = halls[0]
        # accounts for the counter table, armor, attack/armor upgrades and the target's live HP
        target = min(foes, key=lambda e: g.time_to_kill(army, e) or 1e9)
        with g.batch():                                   # dozens of commands, one wait on the game thread
            for u in army:
                if u.hp < u.hp_max * 0.35:
                    g.move(u, home.x, home.y)             # pull back the wounded
                elif (t := g.current_target(u)) is None or t.handle != target.handle:
                    g.attack(u, target)                   # only order units not already attacking it
The full runnable version is brains/examples/micro_bot.py (focus fire, pulling back wounded units, keeping the hero alive, creeping at night).
AI agents

Six ways to plug an LLM into Warcraft

Five work today; one is in progress. They aren't mutually exclusive — in the same game, an agent-written bot can execute while a local model advises, another model voices the units, and you chime in from Claude Code at any time.

Offline · writes code

Agent writes the bot

Claude Code, Cursor, Codex, ChatGPT… read the docs, write bot.py, play, check the receipts and events, then revise. The fastest way to get started, no programming required.

0 lines of code you write by hand
Learn more
Online · advises

LLM as strategy coach

Every few game seconds, the model gets a one-page summary of the game and returns strict JSON: a diagnosis, worker split, build priorities, and the stance for the next minute. The rule layer applies it after whitelisting and clamping.

1.09 s median, local Qwen3.6-35B-A3B
Learn more
Online · plays a character

Let units talk

Speech bubbles pop up over any unit, as any character, streamed from a local LLM: peasant break-room banter, hero dialogue, battle commentary.

0.3 s time to first token (local model)
Learn more
Online · as tools

LLM calls tools directly

Add one server to Claude Code, Claude Desktop or any MCP-capable client, and the LLM can read the game, issue commands, talk to the player on screen, ask the player with pop-up cards and look at screenshots. No code to write first.

10 tools, hooked up with one command
Learn more
Online · any language

Connect through the gateway

The WebSocket / JSON gateway exposes the public APIs as they are: JS, C#, Go, browser pages and programs on another machine can all read the game, issue commands, subscribe to events and put buttons into the game. The player role commands only its own side and sees only its own vision.

+1 ms extra latency on top of the fast lane
Learn more
Coming soon · plays directly

The agent takes the field

The Arena: the referee filters observations by vision, checks unit ownership and ticks on game time, so two external AIs can fight it out in the same game. Any language, any model can play head-to-head.

P6 Arena phase
Learn more
Gameplay extensions New

Beyond matches: build your own gameplay inside the game

Draw your own UI on screen, with buttons that click and hotkeys that respond; call every function map makers have from outside the game; bring an AI partner along to fight beside you in RPG maps; and write a whole new game mode as a mod that, like AI schemes, switches with one click and shares freely.

Runtime-drawn

Canvas

Text boxes, panels, progress bars, images, terrain-hugging circles, arrowed routes. They follow units, and fonts (CJK included), rounded corners and translucency are up to you; drawn only on your own screen, so it's safe in multiplayer.

0.3 ms per-frame cost (9 elements)
Learn more
1291 functions

JASS channel

Call any function map makers can use, directly by name: spawn units, effects, boards, dialogs, sounds, camera, fog… Works from the Farsight console, the command line, HTTP and Python; chat commands, button menus and arrow keys hook in too.

94 functions checked one by one in live games
Learn more
RPG / custom maps

AI companion

Follows you, helps you fight, heals you when you're low and chats with you — its lines can come from a local LLM. Four modes: ally, own unit, adopted map unit, voice only. Custom unit names are read straight from the map.

37 / 38 RPG maps with custom unit names read
Learn more
Switch · share · import

AI schemes

One folder per AI. Switch with one click, even to take over the game in progress; exporting a zip is how you share, and someone else's scheme runs only after you confirm you trust it. Every scheme's results are tallied automatically.

zip Export to share; confirm trust before importing
Learn more
Click · press

UI & input

Drawn buttons and choice cards are clickable and highlight on hover; register hotkeys, pick a spot by clicking the ground, read where the mouse is pointing. Who the player selected, what spell they cast and what they typed in chat all go into the event stream. Buttons are drawn under the mouse cursor, and the game never receives the click that lands on one.

16 / 16 checks passed in live games
Learn more
One file, one game mode

Gameplay mods

You play; the mod sets the challenges: the opening setup, timed enemy waves, pick-one-of-three upgrades, calling waves with a hotkey, placing towers by clicking the ground, deciding the winner. Subclass openwar3.Mod and write a few functions; two examples are built in: Hero Roguelike and Endless Defense.

~150 lines of code for a complete mod
Learn more
Measured

Low latency, measured

Crossing processes isn't slow in itself. What's slow is one message-pump wait per request and one lock for the whole machine. The fast lane gives each client its own lock-free lane, executed in batches inside the game thread's event dispatch.

Command throughput
was 88 3,000 cmd/s
6 concurrent processes
Median wait under concurrency
was 67 ms 0.06 ms
Old control channel → fast lane
16 commands
was 121 ms 13 ms
One by one → one batch
One reference-brain decision cycle
was 0.15~0.56 s 0.02~0.07 s
39-minute game, 0 errors
Roadmap

Every phase is verified in live games

P0–P3, P5, gameplay extensions, the gateway and MCP already run on 1.27. Next up are multi-version support and the Arena.

  1. P0 Fast lane + SDK facade Done
  2. P1 Semantic commands + receipts Done
  3. P2 Real-time information layer Done
  4. P3 Reference brain migration Done
  5. P5 Permissions and views Done
  6. EX Gameplay extensions: canvas · JASS · companion · schemes Done
  7. EX+ UI & input · mods · gateway · MCP Done
Full roadmap

Only for clients you legally own

Local, LAN and self-hosted games. It doesn't modify Game.dll on disk or distribute any Blizzard files (game data is extracted from your own game), and it must not be used on Battle.net or any server with anti-cheat.

Terms of use

Hand this sentence to your agent

Read https://war3ai.com/en/llms-full.txt, then use OpenWar3 to write me a Human bot: Archmage first, take the army creeping at night, and pull the hero back when its HP drops below 40%.