完整世界状态,零等待
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 个已验证接口。
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 和手册交给它。接口用的是游戏里的叫法(四字码、技能名),模型一读就懂。
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 从代码生成,每个接口都标了实测状态、延迟档位和底层机制,模型不必猜;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:诊断、工人配比、优先出什么、这一分钟的姿态。规则层白名单 + 钳位后执行。
任意单位、任意身份头顶弹出气泡,接本地大模型流式输出:农民茶话会、英雄对白、战况解说。
Claude Code、Claude Desktop 或任何支持 MCP 的客户端挂上一个服务器,大模型就能直接看局面、下命令、在屏幕上跟玩家说话、弹卡片问玩家、截图看画面。不用先写代码。
WebSocket / JSON 网关把公开接口原样搬出来:JS、C#、Go、浏览器页面、另一台机器上的程序,都能看局面、下命令、订阅事件、往游戏里放按钮。选手角色只指挥自己、只看自己的视野。
对战平台:裁判按视野过滤观察、校验单位归属、按游戏时间出拍,让两个外部 AI 在同一局里分出胜负。任何语言、任何模型,都能直接对打。
往画面上画你自己的界面,画出来的按钮能点、热键能响;从外面调用地图作者的全部函数,在 RPG 地图里配一个陪你打的 AI 伙伴;一整套新玩法写成模组,和 AI 方案一样一键切换、随手分享。
文字框、面板、进度条、图片、贴着地形的圈、带箭头的路线。跟着单位走,中文字体、圆角、半透明随你定;只画在本机画面上,多人局也安全。
地图作者能用的函数,按名字直接调:造单位、特效、面板、对话框、声音、镜头、迷雾……远见控制台、命令行、HTTP、Python 都能用;聊天命令、按钮菜单、方向键也接得上。
跟着你、帮你打怪、残血时给你加血、陪你说话,台词可以接本地大模型。盟友、我方、接管地图单位、只说话,四种形态;自定义单位的名字直接从地图里读。
一套 AI 一个文件夹。一键切换,正在打的这一局也能换人接管;导出 zip 就是分享,别人的方案确认信任后再跑;每个方案的战绩自动统计。
画出来的按钮、选项卡能点,悬停自动高亮;登记热键、点地面选位置、读鼠标指着哪儿。玩家选中了谁、放了什么技能、聊天打了什么字,都进事件流。按钮画在鼠标指针下面,点它的那一下游戏收不到。
你自己玩,模组出题:开局布置、按时间刷怪、升级三选一、按热键叫波、点地面放塔、定胜负。继承 openwar3.Mod,写几个函数;内置英雄肉鸽、无尽守城两个示例。
跨进程本身不慢,慢的是「一个请求等一次消息泵」和「全机一把锁」。快车道让每个客户端独占一条车道、不加锁,在游戏线程的事件分发里成批执行。
从起一局、看 AI 在想什么,到复盘和直播解说,都有现成的工具。
P0 ~ P3、P5、玩法扩展、网关与 MCP 已在 1.27 上跑通;接下来是多版本适配和对战平台。
本机、局域网、自建游戏。不修改磁盘上的 Game.dll,不分发任何暴雪文件(游戏数据从你自己的游戏里提取),不得用于 Battle.net 或任何带反作弊的服务器。