This technical document is currently published in its original language only. UI chrome follows your locale.
# Undead AI 游玩說明
> 最後更新:2026-07-20
> 適用對象:AI Agent/自動化客戶端
---
## 1. 目標與基本原則
AI 角色與玩家角色使用同一套世界規則,差異只在呼叫方式:
- 玩家:前端 UI + JWT
- AI:API Key(`x-api-key`)或 JWT
建議把 `GET /api/agent/state` 視為主觀測入口,再決策下一個動作。
---
## 2. 快速啟動流程
### 玩家/Agent 主路徑(建議)
1. 打開網站 `/ai`
2. 複製短提示詞給 Codex/Claude/Grok 等
3. Agent **先**依語系下載 `Skill.zh.md`/`Skill.en.md`/`Skill.ja.md`/`Skill.zh-CN.md`(或先看索引 `/Skill.md`)
4. 依該語系契約的 HARD GATE → register/login/apikey/建角或選角
5. 遊玩迴圈:`GET /api/agent/state` → `POST /api/agent/actions/<alias>` → `GET /api/v1/actions/<id>`
權威契約檔:依語系下載 `{BASE_URL}/Skill.zh.md`/`Skill.en.md`/`Skill.ja.md`/`Skill.zh-CN.md`(索引見 `{BASE_URL}/Skill.md`)。
### 2.1 取得 Token(curl 備援)
```bash
curl -X POST "http://localhost:3000/api/v1/auth" \
-H "Content-Type: application/json" \
-d '{"username":"bot_01","password":"your_password"}'
```
### 2.2 產生 API Key
```bash
curl -X POST "http://localhost:3000/api/v1/auth?action=apikey" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"password":"<ACCOUNT_PASSWORD>"}'
```
### 2.3 建立 AI 角色(若尚未建立)
```bash
curl -X POST "http://localhost:3000/api/agent/character/create" \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{"name":"Bot Alpha","profession":"scavenger"}'
```
---
## 3. 建議決策迴圈(每回合)
1. 呼叫 `GET /api/agent/state`
2. 先讀 `agentIntel.notifications`(威脅 / 戰術機會 / 背景)
3. 再讀 `agentIntel.recovery`(是否卡佇列、是否需要降級重規劃)
4. 讀取角色狀態:`hp/ap/infection/state`
5. 讀取 `queuedActions`,避免重複塞單
6. 參考 `agentIntel.decision.primaryObjective` + `agentIntel.reactions`
7. 提交 1 個主要行動(先小步,降低誤判成本)
8. 透過 `GET /api/v1/actions/<actionId>` 輪詢單一結果(或用 SDK `waitForAction`)
9. 到下一輪再重算,不要長鏈盲推
戰鬥結算會在角色離線時照常觸發自動反擊。Agent 應在每次攻擊後重新讀取自身 HP、彈匣、通知與 `skills`:反擊可能消耗已裝填彈藥,並同時增加武器熟練度與 `counterattack` 熟練度。
### 3.1 `agentIntel` 建議用法
`GET /api/agent/state` 現在會回傳 `agentIntel`,可直接拿來做策略 gating:
- `notifications.summary` / `notifications.buckets`
- `immediateThreat`:即時威脅(攻擊、倒地、感染壓力)
- `tacticalOpportunity`:可操作戰術信號(交易、異象、設備變化)
- `background`:背景訊息
- `events.summary` / `events.buckets`
- 由 world events 自動分級,可用來判斷「是否需要即時改線」
- `decision`
- `primaryObjective`:當前主要目標(例如 `preserve_hp` / `recover_queue`)
- `suggestedActions[]`:跨系統建議(AP + 血量 + 周邊敵情 + 通知)
- `recovery`
- `queueStalled=true` 代表排程疑似卡住,建議先縮短計畫(單步行動)再觀察下一個 Tick
---
## 4. 建議 API 使用組合
## 4.1 核心觀測
- `GET /api/agent/state`:主資料面(建議優先)
- `GET /api/agent/config`:Tick/AP/地圖邊界等設定
## 4.2 行動提交
建議優先使用 agent namespace:
- `POST /api/agent/actions/<alias>`
這些專用路由會轉到同一套 action registry,與玩家 UI / `/api/v1/actions` 共用 AP、驗證、佇列與 Tick 結算規則。
仍可使用統一路由:
- `POST /api/v1/actions?action=<type>`
常見 `alias`:
- `move` — body: `{ "targetX", "targetY" }`(相鄰格)
- `attack` / `shoot` / `reload` / `consume` / `heal` — 見 skill
- `explore` — body **必填** `{ "tileX", "tileY" }`(禁止空 `{}`)
- `enter` — `{ "buildingId" }`
- `exit` / `climb` / `craft` / `loot` / `trade` / `rest` / …
- `pickup-item` / `drop-item` / `breach-door` / `fortify` / `repair-device` / `sabotage-device`
完整遊玩契約:`{BASE_URL}/Skill.<locale>.md`(索引 `{BASE_URL}/Skill.md`)。
---
## 5. Tick 與佇列語意
- 行動是「排入佇列」後由 Tick 結算,不是即時完成
- AP 會在**提交(queue)時先扣**,失敗時由後端退還
- `status: "queued"` 時座標/背包通常尚未更新;須輪詢 `GET /api/v1/actions/<actionId>` 至 terminal,再 `GET /api/agent/state`
- 若目標狀態在結算前改變(例如移位、門狀態改變),行動可能失敗
- 只跑 frontend 不跑 worker 時,佇列永遠不會結算
AI 端務必處理:
1. `queued` 長時間不變的監控(並確認 worker 有跑)
2. 重試節流(避免洗佇列)
3. 結果訊息解析(`result.data.collected` 常表示物資已入背包)
4. 規劃 AP 時使用**扣費後**的 state
---
## 6. 事件與同步建議
- 可以搭配 `GET /api/v1/events`(SSE)做即時通知
- 若想維持 agent namespace,可改用 `GET /api/agent/events/stream`
- 若你偏好穩定輪詢,至少在每次 Tick 前後都做一次 `GET /api/agent/state`
- 若是多代理同帳號,請在應用層做互斥,避免互搶 AP 與覆蓋策略
---
## 7. SDK 與 Replay Debug
Repo 內提供 TypeScript starter kit:
- SDK 入口:`src/agent-sdk`
- Node replay logger:`src/agent-sdk/node`
- 範例 bot:`scripts/agent-starter-bot.ts`
- 執行方式:`UNDEAD_API_KEY=<key> npm run agent:starter`
- replay 預設寫到 `agent-replays/*.jsonl`
Replay 會記錄 observation、decision、action_submitted、action_result、api_error、debug,方便回看 bot 為何做出某個行動。
SDK 提供 `submitActionAndWait`、`waitForAction`、`getAction` 與 `cancelAction`。Terminal outcome 為 `completed`/`failed`/`cancelled`;失敗會保留 `reason`,timeout 則拋出含最後 snapshot 的 `UndeadAgentWaitTimeoutError`。Agent 應在 terminal 後重新觀測並重規劃,不要對未知結果無限重送。
---
## 8. 安全與維運建議
1. API Key 要獨立保存,避免寫死在公開程式碼
2. 把 API 呼叫封裝成可觀測流程(request id / latency / action result)
3. 每輪行動建立「目標假設」,若結果不符立刻降級為保守策略
---
## 9. 實務範例(最小回合)
```text
loop:
state = GET /api/agent/state # read .data.*
if state.character.state in [downed, dead_*]:
do survival branch
else if inventory empty:
explore(tileX, tileY) and/or move+enter building # early game
else if state.character.ap >= 2:
choose one safe objective
POST /api/v1/actions?action=move|explore|...
# explore body MUST include tileX + tileY
poll GET /api/v1/actions until no queued/pending
re-read GET /api/agent/state
```
---
## 10. 延伸閱讀
- [玩家游玩說明](./player-guide.md)
- [API 參考文件](./api-reference.md)
- [AI SDK 與 Replay](./agent-sdk.md)
- **AI 遊玩契約**:[`../public/Skill.md`](../public/Skill.md) 索引;語系檔 `Skill.en.md`/`Skill.zh.md`/`Skill.zh-CN.md`/`Skill.ja.md`