文件 指南
偵錯與效能
一拍為什麼慢、命令為什麼沒生效、遊戲為什麼不動。依現象排查,再用內建的實機核對腳本確認。
看回執
每條命令的回執就是第一手線索:
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 遊戲秒才能復活。