完整世界狀態,零等待
16 位玩家的資源與人口;最多 1024 個單位的血量魔力、指令、正在攻擊誰、技能冷卻、buff、物品欄;地上物品、樹木、生產佇列、晝夜。執行環境推送到共用記憶體,讀一份約 0.4 ms。
War3AI 把遊戲變成一套為 Agent 設計的介面:每 50 ms 推送整張地圖的完整狀態,語意命令約一幀生效,每條都有回執和原因碼。把文件交給 Claude、GPT、Gemini、Qwen 或任何 Agent —— 它會寫出 Bot、上場對局、讀回結果、自我改進。
Windows 10/11 · 魔獸爭霸 III 1.27a · 按兩下 start.bat,其餘自動裝好
人類。英雄血量低於 40% 就撤回家;天黑後,兵湊滿 3 個就去打最近的野怪營地。
已讀取 llms.txt 與 api.json,產生 night_raider.py,只用到 8 個已驗證的 API。
from openwar3 import Bot
class NightRaider(Bot):
def on_tick(self, g): # 每秒約 5 次
halls = g.my_buildings({"htow", "hkee", "hcas"})
army, camps = g.my_army(), g.creeps()
if not halls:
return
home = halls[0]
with g.batch(): # 這一拍的命令一次送出
for h in g.my_heroes():
if h.hp < h.hp_max * 0.4: # 英雄保命
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) # 夜裡練功
def on_event(self, g, ev):
if ev.kind == "production.done" and ev.owner == g.me():
print("完成", ev.done_code, f"{ev.value:.1f}s") 相容任何能寫程式或輸出 JSON 的模型與 Agent
數字來自 1.27 測試實例上的實機量測(2026-09-23 / 24),量測方法請見 平台 · 效能。
不會寫程式也沒關係:你負責說清楚想要它怎麼打,Agent 負責寫程式碼、上場、看結果,一路改到你滿意為止。
「人類,先出大魔法師;兩座兵營出步兵和火槍兵;湊到 12 個兵就去打對面的分礦;英雄血量低於 30% 就撤退。」
把 llms.txt、api.json 和手冊交給它。API 用的是遊戲裡的叫法(四字碼、技能名稱),模型一讀就懂。
tools/play.py 負責啟動遊戲、注入、開局、啟動 Bot。遊戲速度、種族、難度、公平模式都是參數。
每條命令都有回執和原因碼,事件流記下每一下傷害、每一次擊殺和生產。Agent 據此定位問題、修改程式碼、再打一局。
觀察零等待、命令有回執、結果有事件 —— 模型需要的正是這種結構化、可驗證、能自我修正的回饋。
16 位玩家的資源與人口;最多 1024 個單位的血量魔力、指令、正在攻擊誰、技能冷卻、buff、物品欄;地上物品、樹木、生產佇列、晝夜。執行環境推送到共用記憶體,讀一份約 0.4 ms。
移動、攻擊、採集、建造、訓練、施法、學技能、復活、使用物品、購買物品……有沒有接下、為什麼沒接下,同一幀就告訴你。
單位出現/死亡、更換指令、英雄升級、物品出現;引擎層級的每一下傷害(來源、攻擊類型、護甲減免前傷害)與生產完成,連對手的也有。
with g.batch() 裡的命令會累積成一批送出。實測 8 條移動從 68 ms 降到 6.5 ms。
stats / time_to_kill 使用遊戲內建的克制表與即時科技;path_distance / walk_path 在引擎地形網格上跑 A*。
只看得見視野內的單位、物品、生產和事件;last_seen 會記住戰爭迷霧中的敵人。擂台用的就是這套規則。
api.json 由程式碼產生,每個 API 都標註了實測狀態、延遲等級和底層機制,模型不必猜;llms.txt / llms-full.txt 讓 Agent 一次讀完全站文件。
執行環境注入原版遊戲,在遊戲執行緒上擷取整個世界、執行命令、回報結果;你的 AI 透過一份帶版本號的 W3P 協定和它溝通 —— 使用 Python SDK,或任何能讀寫共用記憶體的語言。
門面只有兩個類別:Bot 負責節拍,Game 負責觀察和行動。單位用四字碼,技能用指令名,和遊戲裡的叫法一致。
None,不是 0 queue='after' from openwar3 import Bot
class FocusFire(Bot):
"""集火「最快能擊殺的」敵人,而不是最近的;殘血的兵拉回家。"""
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]
# 納入克制表、護甲、攻防升級和目標的即時血量
target = min(foes, key=lambda e: g.time_to_kill(army, e) or 1e9)
with g.batch(): # 幾十條命令只等一次遊戲執行緒
for u in army:
if u.hp < u.hp_max * 0.35:
g.move(u, home.x, home.y) # 拉回殘血
elif (t := g.current_target(u)) is None or t.handle != target.handle:
g.attack(u, target) # 只對還沒在打它的下令 brains/examples/micro_bot.py(集火、拉回殘血、英雄保命、夜裡練功)。 你要為《魔獸爭霸 III》1.27 寫一個 AI(Python)。只能使用 api.json 裡列出的 Game 方法,
不要編造不存在的方法。繼承 openwar3.Bot,實作 on_start(g) 和 on_tick(g)。
規則:
- on_tick 每秒大約呼叫 5 次,要快(別在裡面 sleep)。
- 讀不到的值是 None,不是 0,先判斷再使用。
- 命令會回傳回執:`if r:` 就代表引擎接下了;沒接下時 r.reason 會寫明原因。
- 攻擊特定的敵人用 g.attack(兵, 敵人);看不見的目標會被拒(1001)。
- 英雄陣亡後用 g.revive(祭壇) 復活,不能再訓練一個。
- 一拍要下很多條命令時,包在 with g.batch(): 裡。
我想要的打法:
人類,開局 5 個農民採金、1 個伐木;先出大魔法師;兩座兵營出步兵和火槍兵;
湊到 12 個兵就帶著英雄去打對面的分礦;英雄血量低於 30% 就撤回家。 >>> r = g.train(barracks, "hfoo")
>>> bool(r), r.reason
(False, 'rejected(人口不够)')
>>> r = g.attack(footmen, grunt_in_fog)
>>> r.verdict, r.reason
(1001, 'rejected(目标看不见(在迷雾/黑区里))')
>>> r = g.move(footmen, 1200, -800)
>>> bool(r), r.exec_us # 這條在遊戲執行緒上花了幾微秒
(True, 6)
>>> g.can_do(altar, "Hamg") # 下令前先問引擎:185 = 祭壇正在復活英雄
185 // 裁判每拍傳給 Bot 的觀察(只包含它視野內的東西)
{"t": "obs", "tick": 57, "gameMs": 11400, "me": 1,
"res": {"gold": 320, "lumber": 150, "food": [18, 30]},
"units": [
{"id": 101, "type": "hfoo", "owner": 1,
"x": -4500, "y": 2200, "hp": 380, "hpMax": 420}],
"visibleEnemies": [
{"id": 733, "type": "ogru", "owner": 2,
"x": -3900, "y": 2500, "hp": 700}],
"deadlineMs": 180}
// Bot 回傳的動作(任何語言、任何模型都能產出)
{"t": "act", "tick": 57, "actions": [
{"do": "attack", "unit": 101, "target": 733},
{"do": "train", "unit": 5, "code": "hfoo"},
{"do": "cast", "unit": 7, "spell": "thunderbolt", "target": 733}]} 五種今天就能用,一種正在開發中。它們並不互斥:同一局裡可以由 Agent 寫的 Bot 執行、本機模型當參謀、另一個模型為單位配音,你還能隨時在 Claude Code 裡插一句話。
Claude Code、Cursor、Codex、ChatGPT……讀文件寫出 bot.py,上場看回執和事件,再修改。最快的入門方式,不需要會寫程式。
每隔幾個遊戲秒把一頁局面資訊交給模型,拿回嚴格的 JSON:診斷、工人配比、優先生產什麼、這一分鐘的姿態。經規則層白名單 + 鉗制後才執行。
任意單位、任意身分都能在頭頂彈出氣泡,接上本機 LLM 串流輸出:農民茶話會、英雄對白、戰況解說。
Claude Code、Claude Desktop 或任何支援 MCP 的用戶端掛上一個伺服器,LLM 就能直接看局面、下命令、在螢幕上跟玩家說話、跳出卡片詢問玩家、截圖看畫面。不必先寫程式碼。
WebSocket / JSON 閘道把公開 API 原封不動搬出來:JS、C#、Go、瀏覽器頁面、另一台電腦上的程式,都能看局面、下命令、訂閱事件、在遊戲裡放按鈕。選手角色只能指揮自己、只看得到自己的視野。
對戰平台:裁判依視野過濾觀察、校驗單位歸屬、依遊戲時間出拍,讓兩個外部 AI 在同一局裡分出勝負。任何語言、任何模型,都能直接對戰。
在畫面上畫出你自己的介面,畫出來的按鈕能點、熱鍵按了有反應;從外部呼叫地圖作者能用的全部函式,在 RPG 地圖裡配一個陪你打的 AI 夥伴;一整套新玩法寫成模組,和 AI 方案一樣一鍵切換、隨手分享。
文字框、面板、進度條、圖片、貼合地形的圈、帶箭頭的路線。可以跟著單位移動,中文字型、圓角、半透明隨你設定;只畫在本機畫面上,多人局也安全。
地圖作者能用的函式,依名稱直接呼叫:建立單位、特效、面板、對話框、聲音、鏡頭、迷霧……遠見控制台、命令列、HTTP、Python 都能用;聊天命令、按鈕選單、方向鍵也接得上。
跟著你、幫你打怪、殘血時幫你補血、陪你說話,台詞可以接本機 LLM。盟友、我方、接管地圖單位、只說話,四種形態;自訂單位的名稱直接從地圖裡讀取。
一套 AI 一個資料夾。一鍵切換,正在進行的這一局也能換人接手;匯出 zip 就是分享,別人的方案確認信任後再執行;每個方案的戰績自動統計。
畫出來的按鈕、選項卡片能點,滑鼠停在上面會自動醒目顯示;登記熱鍵、點地面選位置、讀取滑鼠指著哪裡。玩家選取了誰、放了什麼技能、在聊天框打了什麼字,都會進入事件流。按鈕畫在滑鼠游標下面,點它的那一下遊戲收不到。
你自己玩,模組出題:開局布置、依時間刷怪、升級三選一、按熱鍵叫下一波、點地面放塔、判定勝負。繼承 openwar3.Mod,寫幾個函式;內建英雄 Roguelike、無盡守城兩個範例。
跨行程本身並不慢,慢的是「每個請求都等一次訊息迴圈」和「整台機器共用一把鎖」。快車道讓每個用戶端獨佔一條車道、不加鎖,在遊戲執行緒的事件分發中批次執行。
從開一局、看 AI 在想什麼,到覆盤和直播解說,都有現成的工具。
P0 ~ P3、P5、玩法擴展、閘道與 MCP 已在 1.27 上完整跑通;接下來是多版本相容與對戰平台。
本機、區域網路、自建遊戲。不修改磁碟上的 Game.dll,不散布任何暴雪檔案(遊戲資料從你自己的遊戲中擷取),不得用於 Battle.net 或任何有反作弊機制的伺服器。