文件 指南

偵錯與效能

一拍為什麼慢、命令為什麼沒生效、遊戲為什麼不動。依現象排查,再用內建的實機核對腳本確認。

看回執

每條命令的回執就是第一手線索:

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 遊戲秒才能復活。