iT邦幫忙

2026 iThome 鐵人賽

DAY 20
0

前面 19 天,幾乎每一篇都提到某個踩過的坑、某個修法背後的推導。到了 Day20,剛好可以正面談這件事:AI 在《九重燼》裡到底幫了什麼?它不是把遊戲「自動做出來」的工具,也不是每次一句「幫我寫」就能產出可用內容。

比較準確的說法是:AI 幫我把已經寫清楚的規格,快速推進到可檢查的草稿或實作;真正決定它能不能用的,是旁邊那套文件、邊界、測試和 review 流程。

先把 AI 放回正確的位置

《九重燼》是一款劇情量很重的互動敘事遊戲。這種專案如果直接叫 AI「幫我寫一章古風權謀劇情」,通常會得到一段看起來很像古風、但和系統完全接不起來的文字:角色口吻可能不對,選項 ID 不存在,數值沒有回寫,甚至劇情會和前後章衝突。

所以我在這個專案裡沒有把 AI 當成「創作主腦」,而是把它放在三個比較可控的位置:

  • 把已經定稿的企劃文件轉成更接近實作的草稿
  • 協助閱讀程式碼、找出可能的邊界條件和漏接處
  • 幫我整理文章,把技術決策講成能被人讀懂的開發紀錄

這三件事有一個共通點:它們都有材料可以核對。AI 不是憑空替我決定世界觀,而是在 docs/src/scripts/ 這些已經存在的東西之間來回對照。

AGENTS.md:寫給 AI 代理看的規格書

專案根目錄的 AGENTS.md 開頭就寫明:「本文件供 Codex 與其他程式代理在《九重燼》專案中執行開發任務時使用。」這份文件不是普通 README,而是一份寫給 AI 代理的工作規則。

它最重要的部分不是語氣,而是順序和禁止事項。

例如文件優先級寫得很死:規格衝突時,先看 AGENTS.md,再看 GAME_SYSTEM_PRD.mdDEVELOPMENT_TASKS.mdINK_SCRIPT_GUIDE.mdCHOICE_BRANCHES.mdENDING_CONDITIONS.md,再往下看劇本、角色、場景和故事聖經。這代表 AI 代理遇到「程式碼看起來可以這樣寫,但選項規格不是這樣定」時,不能自己猜,要回到文件順序判斷。

AGENTS.md 也規定了動工方式:

  • 每次只處理一個主要 Task ID
  • 開始前要讀對應文件、確認前置任務、檢查既有程式碼
  • 不修改無關內容
  • 完成後列出修改檔案、主要實作、型別檢查與測試結果

這些規則看起來很像專案管理碎念,但對 AI 協作很重要。因為 AI 最大的風險之一,就是它很容易「順手」改太多東西。人類開發者可能只是想修一個選項狀態,AI 卻順便重構 store、改 UI、補一段劇情,最後 diff 變成一團。把工作方式寫進 AGENTS.md,就是先把可接受的行動範圍圈起來。

禁止事項比能力清單更重要

我覺得 AGENTS.md 裡最有價值的不是「可以做什麼」,而是「不可以做什麼」。

幾條關鍵限制直接影響 AI 協作的品質:

  • 不得把劇情正文直接寫進 Vue 元件
  • 不得在 Ink 中直接寫 /assets/... 路徑
  • 不得使用 v-html 顯示劇情
  • 不得用 any 規避型別問題
  • 不得刪除既有測試以讓建置通過
  • 不得靜默忽略資產缺失
  • 不得讓 Vue 與 Ink 各自修改同一數值而無同步

這些限制不是形式上的潔癖。Day9 講過,Vue 不應該直接碰 inkjs;Day16 講的是 Pinia 和 Ink 變數同步。如果某次 AI 修改時把數值邏輯塞回 Vue 元件,短期看起來可能能動,長期就會破壞整個架構分工。

同樣地,「不得刪除既有測試以讓建置通過」這條也很現實。AI 有時候會傾向把錯誤變少:型別錯,就放寬型別;測試錯,就調整測試期待;資料缺,就把檢查略過。但遊戲開發真正需要的是找出錯誤原因,而不是讓錯誤訊息消失。

文件本身就是 Prompt

Day5 談過,docs/FULL_SCRIPT/ 底下逐章的劇本檔才是唯一劇情正本。CHAPTER_01_SCRIPT.mdCHAPTER_08_SCRIPT.md,加上 ENDINGS_SCRIPT.md,裡面寫的是場景、選項 ID、數值旗標效果、CG、BGM 和演出需求。DEMO_SCRIPT.md 只是早期草稿,一旦正本存在,就不能再回去引用草稿當依據。

這件事對 AI 協作非常關鍵。

如果我只說「幫我寫第一章藏鋒」,AI 會自己補很多東西。它可能寫得很順,但它不知道哪個選項要加 rel_liu_trust,不知道哪個場景要解鎖證據,不知道這段該接到哪個 knot。可是如果我把對應的正本、CHOICE_BRANCHES.mdENDING_CONDITIONS.md 一起給它,它就不是在自由創作,而是在轉寫規格。

這也是為什麼我會說文件本身就是 prompt。Prompt 不只是聊天框裡那一句指令,而是整個 repo 提供給 AI 的上下文。

一份好的 AI 協作提示,大概會長得像這樣:

先讀 AGENTS.md、docs/FULL_SCRIPT/CHAPTER_02_SCRIPT.md、
docs/CHOICE_BRANCHES.md 中 CH02 相關段落,
再檢查 src/narrative/chapters/chapter_02.ink 既有寫法。

只處理 CH02 的指定場景。
保留既有 tag 格式。
每個新增選項都要有唯一 choice id。
改完後跑 build:ink、validate:story、typecheck、test。

這段話不漂亮,但可執行。它告訴 AI 要讀什麼、不能碰什麼、產出後怎麼驗證。這比「請幫我優化劇本」穩太多。

劇情開發:AI 適合做轉寫,不適合改設定

在劇情工作上,AI 最適合處理的是「有明確來源的轉寫」。

例如把劇本正本轉成 Ink 時,真正麻煩的地方不是寫幾句台詞,而是把所有結構接上:

  • # chapter# scene# line# speaker 這些 tag 要放對
  • 選項要有唯一 # choice ID
  • 數值調整要寫在 Ink 的 ~ 語句裡
  • 章節完成、結局判定、證據解鎖要接到既有系統
  • knot 之間要能離開,不能寫成無出口迴圈

AI 可以幫忙把這些重複、細碎、但需要耐心的事情做得快一點。尤其是大量 scene / line / choice ID 的補齊,人工做久了很容易眼花。

但我不會讓 AI 自己決定「這個角色在這裡應該背叛」、「這個結局條件應該改成信任 70」、「這段劇情應該多一條復仇線」。這些是企劃層決策,必須回到 CHARACTERS.mdCHARACTER_RELATIONSHIP.mdENDING_CONDITIONS.md 和劇本正本。AI 可以提出建議,但不能直接變成 canon。

程式開發:讓 AI 接在邊界後面

程式這邊也一樣。AI 最好用的地方不是叫它從零發明架構,而是在既有邊界裡補實作、找漏接、寫測試。

Day9 提過的 StoryRuntime.ts 就是一個很適合 AI 協作的邊界。Vue 元件不直接 import inkjs,而是透過 StoryRuntimecontinueLine()choose()exportState()importState() 溝通。這代表修改劇情整合時,AI 不需要翻整個 UI,只要先理解 StoryRuntime 對外暴露了什麼。

InkTagParser.ts 也是一個典型例子。它把 inkjs 吐出的純字串 tag 解析成 typed command,並且用 REQUIRED_ARG_COUNTS 檢查必要參數。# char tag 還支援三個參數和四個參數兩種寫法:省略 outfit 時預設成 default,有 outfit 時就照 tag 指定。

接著 StoryCommandRouter.ts 把這些 command 分派到不同系統:

  • chapterscenelinespeaker 進 Pinia
  • bgcharcgvfx 進 Pixi
  • bgmambiencesfx 進 audio
  • autosavecheckpoint 進存檔流程
  • endingunlock 進系統層

這種邊界越清楚,AI 越不容易亂改。因為它可以被要求:「只新增一種 tag 的解析與 routing,測試也補在 test-ink-tag-parser.mjstest-story-command-router.mjs。」任務範圍一小,review 起來就清楚。

Debug:AI 要有證據才能幫上忙

AI 協作除錯最有效的場景,不是「我覺得哪裡怪怪的」,而是「這裡有一個可重現現象,這裡有相關檔案,這裡有驗證方式」。

Day10 的對話框連點優化就是這種例子。問題不是抽象的「手感不好」,而是玩家在第二輪或測試分支時,想快速讀劇情會覺得每句要點兩次。修法最後落在 DialogueBox.vue:打字中點擊先補全文,如果瀏覽器的 event.detail > 1 代表這次是連點序列的一部分,就把「補全文」和「推進下一句」合併。

這種 bug 很適合 AI 協助推理,因為它有明確條件:

  • 狀態:isTypingisDone
  • 事件:滑鼠點擊與 event.detail
  • 邊界:不能破壞原本單擊補全文的行為
  • 驗證:手動試玩快速連點,並確認選項、小遊戲、面板開啟時不會誤推進

反過來,如果只是說「對話框不夠順」,AI 很可能會開始改動畫速度、改 CSS、改 store,甚至改出更多問題。越能把現象拆成可觀察條件,AI 越像一個好用的 pair programmer。

測試腳本是 AI 協作的煞車

Day6 講過,這個專案不只靠人工記憶進度,而是用一組腳本把檢查固定下來。package.json 裡目前有:

npm run build:ink        # 編譯 Ink
npm run validate:story   # 檢查劇本結構
npm run validate:assets  # 檢查資產引用
npm run typecheck        # TypeScript 型別
npm run test             # 存檔、runtime、tag parser、router、結局、分支等測試

npm run test 串了一整排腳本:存檔、migration、StoryRuntime、InkTagParser、StoryCommandRouter、EndingResolver、ExtraUnlockResolver、CH00 到 CH08 分支測試、證據系統、角色事件、Pixi stage。這不是完整覆蓋所有可能路線,但它至少讓「AI 改完之後有沒有把核心流程弄壞」有一條固定檢查線。

這就是我前面說的煞車。AI 很快,快到如果沒有測試,它會把錯誤也一起快速推進。測試腳本不會保證文章或劇情寫得好,但它會抓住很多不能壞的東西:Ink 編譯、tag 格式、選項分支、結局解析、存檔遷移。

Review:不是只看程式碼漂不漂亮

一般 code review 會看命名、型別、重複邏輯、錯誤處理。這個專案多了一層:實作有沒有對上企劃文件。

例如 review 一段 Ink 轉寫,不只看它能不能編譯,還要回頭對:

  • 場景 ID 是否和 docs/FULL_SCRIPT/ 一致
  • 選項 ID 是否和 CHOICE_BRANCHES.md 一致
  • 數值與旗標是否照規格調整
  • 結局判定是否仍由 ENDING_CONDITIONS.md 和 resolver 集中處理
  • UI tag 是否只描述畫面行為,不把資產路徑直接寫進 Ink

這種 review 很適合 AI 輔助,因為 AI 可以幫忙快速掃出「文件說 A,程式寫 B」的落差。但最後的判斷仍然要有人負責。尤其是劇情語氣、角色動機、章節節奏,這些東西不是測試腳本能完全判斷的。

我通常會先讓它做幾件事:

  • rg 找出對應的程式碼、文件和腳本
  • 把可檢查的 claim 一條一條對 repo 驗證

AI 加速的是迭代,不是責任

回頭看《九重燼》的 AI 協作,我覺得最重要的心得是:AI 加速的是迭代,不是責任。

它可以讓我更快把劇本正本轉成 Ink,可以更快整理出 tag parser 和 router 的漏接點,可以更快把 Debug 過程整理成文章。可是它不能替我決定哪份文件是正本,不能替我承擔授權風險,不能替我保證角色沒有走味,也不能在測試失敗時說「應該沒關係」。

所以我現在看 AI 協作,比較像看一條更快的工作流:

規格文件
  ↓
AI 協助轉寫 / 補實作 / 找問題
  ↓
人工 review 劇情與架構邊界
  ↓
腳本驗證與測試
  ↓
再回到文件修正

這條路跑得快,但每一站都要有人看。尤其是劇情遊戲,玩家最後感受到的是角色、選項、節奏和情緒,不是「這段是不是 AI 幫忙生成」。AI 可以當加速器,但方向盤還是要握在專案規格和開發者手上。


結論
AI 協作不是少寫文件,而是更需要文件。沒有 AGENTS.md、沒有劇本正本、沒有選項與結局規格、沒有測試腳本,AI 只會讓混亂發生得更快。

但當文件夠清楚、邊界夠明確、驗證流程夠固定,它就真的能幫一人開發省下大量往返時間。不是替我把遊戲做完,而是讓「規格 → 實作 → 驗證 → 修正」這個循環跑得更快,也比較不容易在半路忘記自己為什麼這樣做。


上一篇
Day19 AI 如何加速我的美術、CG、BGM 製作
系列文
《九重燼》Vue3 + PixiJS + Ink.js 視覺小說遊戲開發全紀錄20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言