文档 指南

调试与性能

一拍为什么慢、命令为什么没生效、游戏为什么不动。按现象排查,再用自带的实机核对脚本确认。

看回执

每条命令的回执就是第一手线索:

r = g.cast(hero, "blizzard", x=tx, y=ty)
if not r:
    print(r.reason, r.verdict)     # rejected(…) 以及原因码
print(r.exec_us, r.engine_us)      # 这条在游戏线程上执行了多少微秒 / 其中引擎下令函数本身花了多少

正常情况下一条命令在游戏线程上花几微秒到几百微秒。批量块结束后,g.last_receipts 是这一批每条的回执。

在游戏里看

g.say(unit, "撤")          # 单位头顶冒一个聊天气泡(不影响游戏)
g.message("开始打野")        # 左下角消息区打一行字(只有本机看得见)

print 的内容会出现在运行 Bot 的终端里。把每拍的关键决策打印出来,配合头顶气泡,比看代码快得多。

一拍很慢

先看是不是这几种情况:

原因改法
一条一条发命令,每条都等一帧包进 with g.batch():,几十条只等一次
逐个调 g.visible() / g.can_do()(每次都走快车道等一帧)可见性用快照里的 u.visible_to();可行性用 g.can_do_many([...]) 一批问
在 on_tick 里 sleep 或等待记下游戏时间,下一拍再判断
每拍重算很贵的东西(寻路、全图扫描)缓存结果,隔几拍再算。g.grid() 自带 2 秒缓存,g.stats() 的科技等级 5 秒缓存一次

游戏不动 / Bot 等不到进局

现象多半是
一直「等进局」实例号不对;或者游戏窗口最小化了 —— 最小化时游戏模拟是停着的(时钟不走)
游戏在跑、Bot 下令没反应在给别人的单位下令(回执 not_owner);或者 Bot 以 observer 身份连接(forbidden)
命令被 held这个单位被更高优先级的层握着(参考大脑的毫秒层、指挥台的手动下令),没发出去
暂停后命令还能下正常:暂停时引擎时钟停住,但事件分发照跑、命令照常执行

连一下看状态

python -m openwar3 status --inst 5

输出连接状态:游戏 pid、世界发布周期和每次采集耗时、快车道计数、是否在局里、单位数、游戏时钟。

实机核对脚本

开一个演练实例,逐项核对 SDK 能力是否在你的机器上正常:

python tools/sdk_live_check.py --inst 20                 # 全部
python tools/sdk_live_check.py --inst 20 --only prod     # 只核对一节

分节:批量、时间、生产、排队下令、战斗属性、寻路、公平模式。每一节都会在真实对局里下命令、读回效果,打印通过数。

离线测试不需要开游戏:

python tools/run_tests.py

常见的「看起来像 bug」

  • 盖房子回执接下了,但一直没地基:树林里的点引擎也当场接下,工人走到才失败。用 build_near,它会跟踪并把失败的点拉黑一段时间。
  • 技能回执接下了,但没放出来:被打断了,或者没蓝。放完下一拍看 g.cooldown() 有没有进冷却。
  • 攻击令接下了,但兵去打别人:对具体目标攻击要用 g.attack(兵, 敌人)(右键语义)。原始的攻击令对目标只换订单、不记目标,会去打附近别的。
  • 工人数对不上:进了金矿的工人不在快照里。
  • 死了的英雄训练不出来:英雄唯一,要 g.revive(祭坛);复活要人口,死后约 3 游戏秒才能复活。