# 回執與原因碼

> 每條命令的回執都帶有狀態碼和原因碼。它們是 Bot 和 Agent 自我修正的依據：把「為什麼沒做成」變成機器可讀的數字。

來源: https://war3ai.com/zh-tw/docs/reason-codes/

```python
r = g.train(barracks, "hfoo")
bool(r)        # False
r.status       # 1              -> rejected
r.verdict      # 3              -> 人口不足
r.reason       # 'rejected（人口不够）'
r.exec_us      # 這條命令在遊戲執行緒上執行了幾微秒
```

`if r:` 等同於 `r.status == 0`（引擎接下了）。

## 狀態碼 `status`

| 碼 | 名稱 | 含義 | 常見原因 |
|---|---|---|---|
| 0 | `accepted` | 引擎接下了 | —（但接下 ≠ 做成，見下文） |
| 1 | `rejected` | 被引擎拒絕 | 看 `verdict` |
| 2 | `bad_unit` | 單位不存在或控制代碼對不上 | 單位已經陣亡；使用了過期的單位物件 |
| 3 | `not_owner` | 不是你的單位 | 以 `player` 身分指揮別人的單位 |
| 4 | `fault` | 執行時發生例外（執行環境已攔下，不會拖垮遊戲） | 請附上重現步驟回報 |
| 5 | `bad_args` | 參數錯誤 | 座標、格號、四字碼寫錯 |
| 6 | `unsupported` | 不支援 | 這個版本的執行環境沒有這項能力 |
| 7 | `bad_target` | 目標無效 | 目標已經不在了；目標類型不對 |
| 8 | `forbidden` | 車道角色不允許 | 以 `observer` 身分下令 |
| 97 | `cancelled` | 批次區塊內拋出例外，整批都沒送出 | `with g.batch():` 區塊裡的程式碼出錯 |
| 98 | `held` | 單位被更高優先順序的層佔用，沒有送出 | 參考大腦的毫秒層、指揮台的手動下令正佔用這個單位 |
| 99 | `timeout` | 逾時 | 遊戲暫停或卡頓時超過了截止時間（過期的命令不會再執行） |

## 原因碼 `verdict`

被拒時，執行環境會用引擎自己的可行性檢查說明原因。也可以先不下令、先詢問：`g.can_do(單位, 四字碼)` 會回傳同樣的碼。

| 碼 | 含義 | 怎麼辦 |
|---|---|---|
| 0 / 220 | 可以 | — |
| 3 | 人口不足 | 蓋人口建築；用 `g.production(b).blocked` 提早發現 |
| 8 | 黃金不足 | 等錢；下令前先用 `g.can_afford(code)` |
| 9 | 木材不足 | 多派人伐木 |
| 32 | 訓練佇列已滿（7 格） | 佇列只排 1 個：`g.queue(b)` 空了再排 |
| 183 | 缺少前置科技／建築 | 先蓋前置建築、升級主堡 |
| 185 | 建築忙碌中 | 祭壇正在復活英雄；大廳佇列沒空時不能升級 |
| 221 | 沒有這一項／建造中／升級中／已存在 | 英雄已經有了（陣亡要用 `revive`）；這家商店不賣這個 |
| 89 | 商店還沒進貨 | 開局要等到物品表的上架時間才有貨；新蓋的商店從蓋好那一刻才開始計算 |
| 1001 | 目標看不見 | 目標在戰爭迷霧或黑色遮罩區裡；對它的位置用 `attack_move` |

## 接下 ≠ 做成

回執只說明「引擎接下了這條命令」，是在同一幀裡讀回來的。之後可能發生的事它管不到：

| 命令 | 回執接下之後仍可能失敗 | 怎麼確認 |
|---|---|---|
| 建造 | 樹林裡的點也會當場接下，工人走到了才失敗 | 用 `build_near`（追蹤地基是否出現），或等 `production.done` |
| 施法 | 被打斷、魔力不足 | 下一拍看 `g.cooldown(u, 技能)` 有沒有進入冷卻 |
| 訓練 | 排進佇列但人口不足，一直不開始 | `g.production(b).blocked` |
| 移動／攻擊 | 被其他邏輯（或更高優先順序的層）改掉 | `g.current_target(u)`、`g.order_of(u)` |

## 查詢 API

以下 API 不下令，只詢問引擎，結果也放在回執的 `value` 裡（SDK 直接回傳值）：

| API | 回傳 |
|---|---|
| `g.can_do(u, code)` / `g.can_do_many([(u, code), ...])` | 上表的原因碼 |
| `g.tech(code, player=None)` / `g.tech_many([...])` | 研究等級／已建成的建築數（升級鏈也算在內） |
| `g.visible(x, y)` | 這一點我方看不看得見 |
| `g.gold_left(mine)` | 金礦還剩多少黃金 |
| `g.enemy_ai_plan(敵兵)` | 電腦對手的隊長要帶兵去哪裡（只對電腦 AI 有效） |
