Phase:M02 — Traditional Chinese / English Localization
類型:M Phase(Modification / Maintenance Phase)
插入時點:M01-C — SCAG / GoS Background Expansion closeout 後,暫停 M01;M02 closeout 後回到 M01-D。
本文件定義 M02 的具體實作契約:locale state、presentation boundary、localizable field policy、localized content resolver、resource layout、API / DTO 接線、translation authoring pipeline、搜尋與 completeness gate。完成後必須滿足實作規格.md;驗收流程見測試指南.md。
狀態:M02 已 closeout(2026-08-31)。M02-A~M02-H 全部完成,下一步為 M01-D。 Closeout evidence:
M02-C_CLOSEOUT.md、M02-D_CLOSEOUT.md、M02-E_CLOSEOUT.md、M02-F_CLOSEOUT.md、M02-G_CLOSEOUT.md、M02-H_CLOSEOUT.md。
最後更新:2026-08-31
M02 不是把目前頁面上的英文字串逐一替換成中文,而是建立可長期維護的 localization foundation,使後續新增 content / product surface 不再產生 English-only presentation debt。
核心設計目標:
zh-TW / en,不要預先設計多語 marketplace 或 user-authored language pack。正式 type / enum 僅允許:
zh-TW
en
禁止在程式中用自由字串任意傳 locale。
第一版:
zh-TWlocale storage key 必須由單一 module 定義,不得不同頁面各自 hardcode。
Frontend 提供單一全站 locale provider / context / store,頁面與 component 都從同一 runtime locale 取得目前語言。
切換 locale:
user action
→ update runtime locale
→ persist browser preference
→ React rerender
不得:
locale switch
→ window.location.reload()
也不得呼叫任何 Draft / Character mutation API。
目前 locale 改變時同步更新 document language metadata,例如 <html lang>,供 accessibility / browser semantics 使用。
任何 cache 若保存 locale-dependent presentation:
不得讓 zh-TW response 被 en 頁面沿用,反之亦然。
M02 必須明確區分三類文字。
例如:
全部走 UI translation resources,不再在 feature component 內新增 user-visible hardcoded English / Chinese literal。
例如:
這些以 StableKey 或其他穩定 content identity 解析 localized presentation。
例如:
不得因切換 locale 自動翻譯或改寫。
M02-C 必須建立正式 localizable field policy,供 M02-D / E / F / G 與後續 Phase 共用。
政策至少能回答:
pack / kind / field-path
→ localizable?
→ currently user-visible?
→ required locales
→ product surface / reason
具體可用 schema、typed table、JSON policy 或等價可機器讀取形式;不能只存在於人的印象或散落的測試清單。
M02 closeout 當下:
field 必須翻譯,當且僅當它在目前已存在的產品畫面/正常使用流程中會被顯示給使用者。
這是 field-level,不是 category-level。
例如現有 Inventory selector 會列出 SRD magic item name:
item.name → required
若當時沒有 UI 顯示該 item 的完整 description:
item.desc → not required yet
未來 M01-I 或其他 Subphase 新增畫面首次顯示 item.desc 時,該 Subphase 必須同步補齊所有 supported locales。
下列不因是 string 就自動翻譯:
新增 product surface 時,若讓既有 field 從 not user-visible 變成 required:
zh-TW / en。Canonical runtime pack 仍維持:
data/<pack>/...
例如:
srd5.1:spell:fireball
phb2014:background:acolyte
scag:background:city-watch
gos:background:marine
不得建立:
srd5.1-zhTW:spell:fireball
zh-TW:srd5.1:spell:fireball
每個正式 content pack 可有 locale overlay;建議 layout:
data/<pack>/locales/
├── en.json
└── zh-TW.json
資料量大時可按 category 拆檔,例如:
data/srd5.1/locales/zh-TW/
├── spells.json
├── features.json
└── ...
具體拆分可依資料量調整,但必須滿足:
若 canonical source 已是英文,en presentation 可以由 canonical field直接提供或經 overlay 正規化;但對 runtime caller 必須呈現一致的 localized resolver contract,不得讓 component 猜「這個 pack 的英文是不是自己讀 canonical name」。
Resolver至少能支援:
nameshort_name / equivalent display labeldesc是否 required 仍由 localizable field policy 決定。
建立單一 localization resolver / presentation service,不讓各 feature 自己拼語言邏輯。
概念責任:
StableKey + field + locale
→ canonical entry
→ localizable field policy
→ localized overlay / canonical en
→ localized presentation
resolver 應能提供至少:
缺 translation 的處理:
可保留 defensive fallback 避免程式 crash,但 fallback 發生必須可被測試與診斷偵測,不能讓 completeness gate 通過。
目前 Builder / Sheet 流程存在 server-generated name / label / message。M02 必須清理「server 先把英文 presentation 固化,再交給 frontend」的路徑。
允許兩種模式之一,實作時選一套並保持一致:
request 帶明確 presentation locale,server 依 locale resolve name / label / description。
要求:
server DTO 優先提供 StableKey / machine identity,frontend 透過已載入 localization data render。
要求:
M02 不要求所有 DTO 完全移除 display text,但任何 user-visible rules label 必須有足夠 identity 可正確切換語言。
Builder validation / domain errors 優先依:
code
severity
path
related_refs
作為穩定 identity。
不能把英文 message 當唯一 error identity。
Frontend 顯示時以 error code / structured metadata取得目前 locale 文案。
若 server 仍需回傳 message:
錯誤訊息含數值、名稱、level、choice 等動態值時,使用 structured interpolation;其中 rules entity 名稱亦需走 localized resolver。
這是 M02 必須修正的既有 localization debt。
系統提供的 Background roleplay suggestion 不應只靠 raw English sentence 當 identity。
應提供穩定 suggestion identity,例如 conceptually:
<background-stable-key>:roleplay:<field>:<suggestion-id>
或等價 deterministic id。
系統 suggestion:
identity
→ locale-specific presentation
使用者自己輸入的文字:
raw user text
→ 永遠原樣保存
若使用者「採用系統 suggestion」後希望能隨 locale 切換,持久化模型必須保留足夠 identity,不得只能留下 translated/raw display string。
既有已保存且只剩 raw text 的資料不做猜測式 migration;視為 user-authored / legacy text 保留原樣。
搜尋結果只顯示目前 locale 的 presentation;繁中模式不要為了搜尋 alias 額外並排英文名稱。
允許目前 locale 的搜尋 index 同時接受另一正式 locale 名稱作 alias。
例如:
locale = zh-TW
query = fireball
→ result displays 火球術
需要依名稱排序的 UI,應依目前 locale display name 進行 locale-aware sort;不得用 StableKey / index 假裝 alphabetical presentation sort。
搜尋命中不改變 persisted selection;最終保存仍是 StableKey。
建立正式 D&D 5e 2014 terminology glossary / translation contract。
用途:
不得把 glossary 做成 runtime regex replace engine。
至少涵蓋:
docs/暫用規則資訊/ 的繁中譯名是 glossary 的 priority reference input,而不是 runtime source。
M02-C glossary 至少保存:
English term / canonical name
chosen zh-TW
legacy/reference zh-TW(有差異時)
reference source
optional decision note
若決定不採用既有 reference 譯名,必須有可追溯 decision note;不需要為每個 reference Markdown occurrence 建立第二套人工同步表。
M02 closeout 後 glossary 是正式 terminology SSOT;reference Markdown 保持 maintainer/reference 性質。
M02-D / E / F 有大量翻譯工作,不能只定 schema 與 CI,必須定義產出與 review 流程。
允許使用外部 AI session 批次產生 translation draft,因為本專案本來就允許開發/維護時使用外部 AI 工具。
但:
可人工翻譯、AI-assisted、或兩者混用;最後都必須經相同 lint / review / evidence gate。
大量資料依 category / coherent dataset 分批 author、review、commit,例如:
spells
features
conditions
equipment
backgrounds
...
每批 commit 應保持 dataset schema-valid,並盡量讓該 batch 的 required fields 完整。
分批 commit 不代表可以分批關閉 Subphase。
M02-D complete scope all green → 才能 close D
M02-E complete scope all green → 才能 close E
M02-F complete scope all green → 才能 close F
不得翻一半 D 就宣告 D closeout 並跳 F,之後再回來補。
每批至少跑:
自動 lint 不取代人工規則語意 review。
Glossary / canonical terminology:新增或變更的正式 glossary entry 必須 100% review。
Long-form translation batch:每個 category 至少人工抽審:
max(10 entries, 10% of that batch)
若 batch 小於等於 10 筆則全審。
抽審優先包含玩法理解敏感內容:
若抽審發現系統性翻譯問題,不能只修抽到的幾筆;必須擴大 review / 修正同類 batch。
每批至少留下可追溯 evidence:
category / pack
entry count
required field count
translation source/method(human / AI-assisted / mixed)
human-reviewed entry count
glossary lint result
schema/completeness result
known exceptions(若有,且不能是 required missing translation)
Evidence 可以放在 commit / closeout artifact / machine-readable report;不要求每批建立新永久 Markdown 文件,但 M02-H 必須能彙整證據。
M02 建立可機器驗證的 translation coverage contract。
completeness 集合:
enabled content packs
× M02-C required localizable fields
× supported locales
M02 closeout enabled packs:
srd5.1
phb2014
scag
gos
對於 canonical content 中目前沒有 product surface 的 field,不為了數字 100% 強行翻譯;但是否 required 必須由 localizable field policy 決定,不可人工隨意忽略。
缺失報告至少列出:
另外必須檢查:
SRD 5.1 的 zh-TW translation 是對 CC BY 4.0 material 的修改/改作。
M02-H closeout 時必須更新 data/srd5.1/NOTICE.md,明確說明本專案提供 SRD 5.1 實際被翻譯之 user-visible presentation text 的繁體中文翻譯,並標示該內容已被修改/翻譯。
NOTICE wording 必須與實際 scope 一致;若 M02 只翻目前 user-visible fields,不得寫成「完整翻譯整份 SRD 5.1」。
三份 M02 文件固定:
M02-A — Locale Foundation & Runtime Switch
M02-B — Full UI Copy Localization
M02-C — Localized Content Model & Terminology Contract
M02-D — SRD 5.1 Names & Structured Text
M02-E — SRD 5.1 User-Visible Descriptions
M02-F — PHB / SCAG / GoS Localization
M02-G — Localized Search, Errors & Completeness Gates
M02-H — Full M02 Integration & Closeout
zh-TW / en typed locale contract。zh-TW。html lang 同步更新。將目前既有 product surface 的 static UI copy 移到 localization resources:
UI component 不再新增直接 user-visible hardcoded English / Chinese 文案,必要 exceptions 必須是 product name / technical token。
Translation resource key 應以語意/功能命名,不依完整英文句子本身當 key。
docs/暫用規則資訊/ 為 priority reference input,定稿 D&D glossary。C closeout 時不要求 SRD 全資料已翻完,但 foundation 必須用 fixture 證明同一 StableKey / field 可正確呈現兩語,並能判定 required vs not-yet-user-visible field。
依 M02-C policy 完成 SRD 5.1 目前 user-visible 的 names / labels / structured short text zh-TW / en coverage。
典型包含:
這是範例,不是另一份 scope SSOT;實際 required field 永遠以 policy 為準。
不得改 StableKey 或 canonical mechanics refs。
依 M02-C policy 完成目前 product surface 已顯示的 SRD 5.1 long-form / explanatory text 雙語 coverage。
不得因 canonical dataset 有 description 就自動把所有 description 列為 M02 required;例如尚未被任何畫面顯示的 magic item full description 可延後到首次 expose 的 Subphase。
翻譯需維持規則語意、數值、骰式、條件與限制,不得因翻譯改變 rules meaning。
長文可以使用 paragraph / list 等結構化 presentation,但 canonical mechanics 不依翻譯文字解析。
M02 closeout 前已正式 runtime 化的 non-SRD packs:
phb2014
scag
gos
依 M02-C policy 完成所有目前 user-visible content 的 zh-TW / en presentation coverage。
docs/暫用規則資訊/ 對應 PHB / SCAG / GoS 文件作 zh-TW draft / terminology priority input;正式 runtime presentation 仍進 localization resources,不 runtime parse Markdown。
至少覆蓋目前可見的:
Roleplay suggestion reuse 必須 reuse identity / source relationship,而不是把另一語言 raw sentence 當 mechanics inheritance。
此 Subphase 後,新增/修改/首次 expose 正式 user-visible content 若缺任一 supported locale,測試應能失敗。
進行完整 integration hardening:
Documentation closeout 必須同步:
AGENTS.mdPROJECT_BRIEF.md規格企劃.md(產品層語言行為需要同步時)data/srd5.1/NOTICE.mdM02 closeout 後新增全專案永久要求:
任何後續 Subphase 新增、修改,或因新畫面而首次 expose user-visible system / rules content,都必須同步維護所有正式 supported locales;缺任一語言即視為該 Subphase 未完成。
M02 closeout 後:
Resume M01-D — VGM Race Expansion
M01-D~M01-I 的新增 content / UI 必須在各自 Subphase 同步交付 zh-TW / en presentation。