貢獻指南
感謝你願意幫忙維護 rd2-wiki(Random Dice 2 骰子樹非官方玩家攻略站)!
這份文件同時是 repo 的貢獻指南,也是網站 關於頁 的內容來源 ——正本只有這一份,不會有第二份「網站上寫的」版本跟這裡不一致。
如果你不確定用詞,全站與所有資料一律使用「渾沌」這個寫法(遊戲原始資料的正式用字就是如此), 不要用發音相近但不同的另一種寫法。
1. 資料正本在哪裡
你能改、也只需要改這三個地方:
data/nodes.json——所有文字:名稱、節點下方顯示的標籤、類型、解鎖花費、等級上限、 效果說明、骰子覺醒、管理 ID。以節點 id 為鍵,一個節點一個區塊、一個欄位一行。 改錯字、修數值、補說明都在這裡,改一句就是一行 diff。data/dice-tree.svg——整棵骰子樹的幾何,共 239 個節點。每個節點是一個<g class="node">,只帶data-id、位置、形狀與外框色、圖示引用。 一個字都沒有——要移動節點、加減連線、換圖示才需要動它。data/icons/——238 張骰子/符文/被動/支援的圖示 PNG,檔名是內容的 sha256 前 12 碼。
⚠️ 兩份正本的節點 id 必須完全對得起來:SVG 裡的每個 data-id 在 nodes.json 都要有
一筆,反之亦然,多一筆少一筆都會被 CI 擋下(規則 19)。新增節點=兩邊都要加。
💡 想知道哪個 id 是哪顆節點,跑 npm run preview:它會用 data/nodes.json 的標籤產出
一份 data/dice-tree.preview.svg,每個節點都標上名字與 id,用瀏覽器打開就看得懂整張圖。
那個檔是產生物、不進版控,改它不會有任何效果。
(2026-08-22 之前文字是寫在 SVG 的 data-* 屬性與 <title> 裡的。那份 <title> 是名稱與
說明的第二份副本,改一個字要同時改兩處,而且整個節點擠在一行 500 字元的標籤裡沒辦法 review。)
其他東西(src/generated/tree.json、public/assets/)都是 npm run build:data 從上面
自動產生出來的建置產物,不要手動編輯、也不會被提交進 repo(在 .gitignore 裡)。你改了
正本之後,本機跑 npm run build:data 或 npm run dev 就會重新產生。
2. 可以用 Inkscape 等 GUI 工具編輯,但送 PR 前一定要先跑一次正規化
data/dice-tree.svg 用 Inkscape、Illustrator 之類的 GUI 向量編輯器直接開來改是可以的,改節點位置、
連線都沒問題。但它只有幾何、沒有任何文字,直接打開就是 239 個無名圖示。
建議的動線是改預覽檔、存回正本:
npm run preview # 產出 data/dice-tree.preview.svg(有名字、有 id)
# 用 Inkscape 打開預覽檔,移動節點/加減連線
cp data/dice-tree.preview.svg data/dice-tree.svg # 存回正本
npm run normalize # 把標籤與 GUI 留下的東西清掉,還原成乾淨的正本
npm run normalize 會把注回去的標籤刪掉——那些字的正本是 data/nodes.json,SVG 裡留一份
就會變成兩份會漂掉的文案。
⚠️ 如果你在 GUI 裡動到了某個標籤的文字(或不小心解散了某個節點的群組、把標籤拖了出來),
normalize 會逐筆列出對不上的地方、一個位元組都不寫、然後失敗。你的檔案原封不動,
照它的指示改完 data/nodes.json 的 label 再跑一次就好。
但這類工具在存檔時,習慣會把檔案「重寫」成它們自己偏好的形式,包括:
- 把單純的位移
translate(x,y)改寫成更泛用的matrix(...) - 把連線的絕對座標指令(
M x y L x y)改成相對座標指令(m dx dy l dx dy) - 在節點外面多包一層看不出差異、但結構上多一層的
<g>圖層群組
這些改變肉眼看起來畫面完全一樣,但會讓 CI 判讀失敗(見下一節規則 0),因為我們的解析器只認 「絕對座標、單一位移、沒有多餘巢狀圖層」這種乾淨形式。
所以編輯完、送出 PR 之前,一定要在專案根目錄執行:
npm run normalize
這支腳本會把 GUI 工具重寫出來的形式,攤平回乾淨的正規形式(matrix 還原成 translate、相對座標
指令還原成絕對座標、多餘的巢狀圖層拿掉、座標統一取到小數點後兩位)。跑完後再用 git diff 檢查
一下改動是否符合預期,才進行提交。
3. 新增圖示:用 npm run add-icon <path>,不要自己命名檔案
data/icons/ 裡每張圖的檔名,規則是「內容 sha256 雜湊值的前 12 碼 + .png」,例如
a1b2c3d4e5f6.png。這是為了:同一張圖不管被幾個節點共用都只存一份、換圖時檔名一定會跟著變
(不會有「內容換了但檔名沒換,瀏覽器快取吃到舊圖」的問題)。
因此新增或替換圖示時,不要自己手動存檔命名,改用:
npm run add-icon <你的圖片路徑>
它會自動計算雜湊、用正確檔名複製進 data/icons/,並印出這個檔名,你只要把
data/dice-tree.svg 對應節點的 <image href="icons/..."> 指到這個檔名即可。圖片必須是有效
PNG,且最長邊至少 96px(太小會被 CI 擋下,見規則 7)。
骰盤編輯器(/board)用的是另一批圖——不含底板的「純骰子圖」,放在 data/board-icons/,
而且哪顆骰子用哪張圖記在 data/board-icons.json。要新增或替換它,多帶一個 --board 與節點 id:
npm run add-icon -- --board <節點 id> <你的圖片路徑>
這樣圖檔與對應表會在同一次指令裡一起更新——只做其中一邊,CI 的規則 21 就會紅(見下一節)。
骰子圖鑑(/dice)的卡片又是第三批——遊戲的 3D 立體骰子圖,放在 data/dice3-icons/,
對應表是 data/dice3-icons.json,形狀與規矩跟 --board 完全一樣:
npm run add-icon -- --dice3 <節點 id> <你的圖片路徑>
⚠️ 同一顆骰子在站上有三張長得不一樣的圖(節點圖有底板、/board 是扁平卡片視角、圖鑑是 3D
立體),三條路徑彼此獨立,不要互相借用——接錯了畫面上只是「圖變成另一種樣子」,看起來
完全正常,規則 30 就是為了擋這件事(見下一節)。
戰術(/tactic)與 Boss(/boss)也各有自己一批圖,放在 data/tactic-icons/ 與
data/boss-icons/,而雜湊直接寫在 data/tactics.json/data/boss.json 那一筆的 icon 欄裡
(不像 /board 另有一份對應表——這兩份資料本來就是站台自己的,不必對到 SVG 裡的節點 id):
npm run add-icon -- --tactic <戰術編號> <你的圖片路徑>
npm run add-icon -- --boss <Boss 編號> <你的圖片路徑>
⚠️ 這兩個只會更新既有那一筆的 icon,不會新增紀錄。要加一條全新的戰術,得先把名稱、
階段、適用模式、效果全文與內部ID 補進 data/tactics.json——那些只有看著官方資料表的人知道,
工具猜不出來。找不到那個編號時它會直接失敗,而且圖還沒被寫進目錄。
4. 送 PR 前建議自己先跑一遍
npm run normalize # 把 GUI 工具的重寫攤平回正規形式(跑完 git diff 要是乾淨的,見下一節)
npm run preview # 產出帶名字與 id 的 data/dice-tree.preview.svg,用來肉眼確認版面
npm run validate # 檢查資料本身正確不正確(規則 0–10、13–30,見下一節)
npm run build # 或 npm run build:data;順便檢查組裝後的體積有沒有超出效能預算(規則 12)
npm run typecheck # 型別檢查(tsc --noEmit);動到 src/ 或 tools/ 一定要跑
npm run test # 純函式與解析器的單元測試
npm run validate 和 npm run build 檢查的不是同一件事:validate 只讀
data/dice-tree.svg 與 data/nodes.json 本身,檢查資料正確不正確;build(或單獨跑 build:data)會先把
資料組裝成正式產出的 tree.json,再檢查組裝後的檔案體積有沒有超標。兩個都要跑——
只跑 validate 不會抓到體積超標的問題,等 CI 才發現就白跑一趟。
如果你動到的是 src/ 底下的前端程式碼(畫布渲染、互動邏輯、版面⋯),而不只是
data/nodes.json、data/dice-tree.svg 或 data/icons/,送 PR 前也建議跑一次 npm run e2e(它會自動先建置一次)
(第一次跑 E2E 前要先執行一次 npx playwright install --with-deps chromium 裝瀏覽器)——
CI 會用獨立的 job 跑同一套 E2E 測試,本機先跑過能提早抓到問題。
5. CI 會擋什麼(白話版)
PR 送出後,CI 會用 npm run validate 檢查兩份正本本身的正確性(座標與結構一律
用瀏覽器同款的 SVG 解析方式判讀,不是用簡單的文字比對,所以看起來「差不多」不代表過得了)。
以下任何一條沒過,PR 就會被擋下:
-
SVG 檔案結構必須是我們認得的乾淨形式:連線只能是「一條直線、絕對座標、附箭頭」;節點只能 是「單純位移、沒有多餘圖層」。—— 這條幾乎都是忘記跑
npm run normalize才會中,錯誤訊息會提醒你。 另外節點裡不可以有<text>或<title>——名稱、標籤與說明一律寫在data/nodes.json, 留在 SVG 就會變成第二份會漂掉的副本。npm run normalize會自動清掉它們。 -
data/nodes.json的每一筆都要結構完整:name/label/type/gameId/cost/maxLevel/description都要填、都不能是空的,長度不超過 500 字(label是 20 字), 也不能多出我們不認得的欄位。 選用的category與awakening不用時要整個省略那個鍵,不要留""。 -
每個節點的編號(id)不能重複,而且要符合命名規則(開頭數字代表屬性分支、第二碼代表類型)。
-
節點外框顏色要跟它的屬性分支對得上:例如粉紫色外框只能用在支援類節點,不能拿去畫骰子。
-
解鎖成本的寫法要合乎格式:
cost只寫核心與金幣的數字,格式固定、不能換行——等級上限 寫在maxLevel欄位,不要寫回cost裡。 -
連線兩端要準確接在節點正中央,而且要有箭頭:連線畫歪、沒接到節點中心點,或忘記加箭頭樣式, 都會被擋下(座標容許誤差很小,肉眼看起來「差不多對齊」通常不夠)。
-
整棵樹不能有循環、也不能有孤立節點:不可以出現「A 的前置是 B、B 的前置又繞回 A」這種環, 而且除了五個屬性的起手骰之外,每個節點都要能沿著連線往回追到某個起手骰,不能憑空飄在樹外接不到任何東西。
-
圖示要對得上:節點指到的圖示檔案要存在;圖示檔名(sha256 前 12 碼)要跟檔案實際內容算出來 的雜湊一致(也就是前面說的,新增圖示要用
npm run add-icon,不要自己改檔名);檔案要是合法的 PNG,而且最長邊至少 96px。 -
效果說明裡的
#關鍵字(例如#僵硬)必須是白名單裡已經有的詞,白名單在data/keywords.json。要用新關鍵字,先把詞加進這個檔案——而且一併寫上解釋,因為那份檔案 同時就是站上顯示給玩家看的詞彙表(詳情面板會把節點用到的每個關鍵字連同解釋一起列出來):"冰凍": { "code": "FROZEN", "color": "#9B6BFF", "desc": "移動速度減少" }code:遊戲資源包裡的代碼,只給貢獻者比對原始資料用,站台不顯示、也不進tree.json。color:遊戲內這個標記的底色,#RRGGBB格式;同色代表同一類機制,站上照用。desc:解釋文字。裡面可以再引用別的#關鍵字,但同樣要是白名單裡有的詞。
三個欄位缺一個、色碼寫成
藍色、或解釋裡引用到不存在的詞,都會被規則 8(b) 擋下。遇到同一個效果在遊戲裡有兩個名字時(例如詞彙表寫
#果實、花骰子的覺醒文案寫#播種), 不要抄第二份解釋,用別名指回本尊:"播種": { "aliasOf": "果實" }。別名不准再指向別名。 -
成長數值的單位前後要一致:像「每級 +2%(最高 +20%)」這種寫法,括號內外的單位要一樣, 不能一邊寫
%一邊寫「秒」。 -
中央樞紐要接得上:畫面正中央那個「骰子樹」圖示(正本裡的
<g class="tree-center">) 不是節點、沒有 id,但它有五條放射線接到五顆起手骰。這條會檢查:圖檔(data/tree-center.png) 存在、是合法 PNG、而且解析度至少是顯示尺寸的兩倍;data-links列的 id 都真的存在;每一條 放射線的終點確實落在對應節點的中心(順序也要跟data-links一致)。 連線集合若跟五顆起手骰對不起來,只會警告、不會擋。編輯這一組時記得先跑
npm run normalize:它必須是<svg>的直屬子元素、不能帶transform(跟節點同一條規矩),圖也必須以樞紐中心對齊,否則npm run validate會直接擋下來。
規則 13:畫布與座標
(編號接在 12 後面,是為了不動已經寫在別處的規則 11=差異摘要留言、規則 12=效能預算。)
- 畫布
viewBox必須是0 0 2000 1700。要改畫布尺寸請先開 issue 討論——整站的縮放推算與 端對端測試的幾何斷言都綁著這組數字。 - 每個節點的中心、每條邊的兩端都必須落在畫布範圍內。
- 任兩顆節點的中心至少要相距 5。兩顆疊在一起時,連到那個位置的邊要算給誰,只取決於它們在 檔案裡的先後順序——把其中一顆往上挪一行就能換掉整條前置鏈,而 diff 上只有兩行位置對調。
另外幾條散在既有規則裡的補強,都是同一個道理(畫面上看不出來、資料卻變了):
data-wip="1"的節點完全不能接線(規則 6(d))。這個標記的用途是「先佔位、之後再接線」, 所以它可以不接到任何前置——但也因此不准接線。- 邊必須直接放在
<svg>底下,不可以藏在<defs>或圖層裡;節點與邊都不可以帶display、visibility、style或opacity="0"(規則 0)。 marker-end必須指向正本定義過的箭頭,而且不可以加marker-start(規則 0)。nodes.json的每個文字欄位都有長度上限(500 字,規則 1);cost只寫錢、不可換行—— 等級上限一律寫在maxLevel欄位(規則 4)。
規則 14–16:覺醒、升級花費表、管理 ID
(2026-08-20 依遊戲原始資料表補齊資料時新增的三條。編號同樣接在既有的後面,不動舊的。)
- 規則 14|每顆骰子都要有
awakening(7 骰點時自動啟用的覺醒效果),其他類型的 節點則一個都不能有。覺醒不是骰子樹上的節點——不花核心也不花金幣、沒有前置——所以它是骰子 節點身上的一個屬性。裡面的#關鍵字跟效果說明適用同一份白名單。 - 規則 15|改
data/upgrade-cost.json要連appliesTo一起想:那張表只適用骰子符文 (玩家被動的等級上限與單價都不一樣)。表格第 1 級的金幣與核心必須等於 50 級符文在正本裡 寫的解鎖成本,對不起來會被擋下——那是這兩份資料唯一對得起來的地方。 - 規則 16|每個節點都要有
gameId(遊戲資料表的管理 ID:骰子D000、 骰子技能D0000、共通節點S0200),格式跟著節點類型走、而且全檔不能重複——那是這份 資料與遊戲原始資料表唯一對得起來的鍵,之後拿新版資源包來核對就靠它。 70 個玩家被動另外要有category,五選一:系別屬性/全骰屬性/系別技能/玩家被動/支援強化;其他類型的節點不能有。
⚠️ 規則 14 與 16 說的「不能有」是指整個省略那個鍵,不是寫成 "awakening": ""。
空字串會被規則 1 擋下來——它看起來像「有這個欄位、只是還沒填」,語意不一樣。
規則 17–19:官方滿級值、解鎖例外、兩份正本同步
- 規則 17|
data/maxlevel-official.json反向驗算成長值。站台的「50 級 X」是從效果說明 裡的(+每級增量)現推的,而說明抄錯不會有任何其他規則說話。這份夾具存的是官方資料表 標註的滿級值,兩邊對不起來就擋。等級上限大於 1 的骰子符文每一顆都要在夾具裡——漏一項 就等於單獨關掉那顆節點的檢查。 - 規則 18|
data/unlock-exceptions.json的 key 必須是真的節點 id,unlockVia三選一 (quest/default/achievement),note是會直接印在面板上的取得條件原文。 - 規則 19|
data/dice-tree.svg的 id 集合必須等於data/nodes.json的鍵集合, 多一筆少一筆都會被列出來。這是「兩份正本已經不同步」唯一會說話的地方。
規則 20–21:更新日誌、/board 的純骰子圖
-
規則 20|
data/changelog.json要跟著資料一起更新。首頁那幾筆更新日誌是全站唯一沒有 自動來源的內容,而「忘了寫」在畫面上跟「這次沒更新」長得一模一樣。這條檢查日誌本身的結構, 以及最新一筆資料條目的版本欄位跟正本一致——它擋的不是「日誌寫錯」,是**「資料改了、日誌沒改」**。 -
規則 21|
/board的純骰子圖。骰盤編輯器用的骰子圖跟骰子樹上的節點圖示是兩批不同的圖: 它是不含底板的「純骰子圖」,不在正本 SVG 裡,所以規則 7 完全看不到它,由這一條單獨守。每一顆骰子(不含符文、玩家被動、支援)都要在
data/board-icons.json有一筆"節點 id": "圖示雜湊",而那個雜湊要對得上data/board-icons/底下的一個檔案。新增或替換 時不要自己算雜湊、也不要自己改 JSON,用上面第 3 節說的npm run add-icon -- --board, 它會把兩邊一起更新。圖檔的要求跟節點圖示同一組:有效 PNG、最長邊至少 96px。這條會擋下:骰子在對應表漏了一筆、對應表指向的圖不存在、對應表的值不是 12 碼雜湊、檔名跟 內容雜湊對不上、檔案不是有效 PNG 或解析度太低、兩顆骰子指到同一張圖(複製上一筆忘了換成 新加的圖,畫面上就是兩顆一模一樣的骰子)、以及對應表裡留著一筆早就不是骰子的 id。
-
規則 30|
/dice圖鑑的 3D 骰子圖。圖鑑卡片用的是遊戲的 3D 立體骰子圖,跟上面那兩批 又是不同的一批——同一顆骰子在站上有三張圖:骰子樹的節點圖(有底板)、/board的純骰子圖 (扁平的卡片視角)、圖鑑的 3D 立體圖。規矩跟規則 21 一模一樣(同一支實作),只是換成
data/dice3-icons.json+data/dice3-icons/, 指令是npm run add-icon -- --dice3 <節點 id> <圖片路徑>。會擋下的東西也一樣,外加一條: 兩份對應表不准有任何一顆骰子指向同一個雜湊——那代表圖鑑被接回了/board的圖。
規則 24–25:戰術與 Boss
- 規則 24|
data/tactics.json。站上只收遊戲已開放的戰術;官方資料表裡標示「未啟用」的 那一批刻意不落地(維護者裁決)。把未啟用的貼回來時,錯誤訊息會直接告訴你「整筆移除,不要改成 別的模式」。這條還守幾件從畫面上完全看不出來的事:mode是「對戰」就不能有coop,是「對戰/合作」就一定要有——漏了的話那條戰術在合作模式下 會整條消失,而那跟「它本來就只有對戰」長得一模一樣。- 子選項(編號帶
-,例如69-1)的stage必須是「選項」,而且母條目要在。改成別的階段的話 它會跟母條目分家,被排到其他階段裡去,畫面上只是「多一條前期戰術」。 - 欄位名打錯(
coop寫成co-op)會被「未知欄位」擋下——必填檢查對選填欄位是沉默的。
- 規則 25|
data/boss.json。跟規則 24 是同一組檢查,欄位少一些。 - 兩條共通的還有:編號重複、
icon不是 12 碼雜湊、指向的圖不存在、兩筆指到同一張圖、 檔名跟內容雜湊對不上、不是有效 PNG 或解析度太低,以及效果文字裡的#關鍵字要查得到 (比不到白名單時,畫面上會出現一個裸的#,看起來就像上游漏填的佔位符)。
規則 26:前置節點的等級條件
-
規則 26|
data/prereq-ranks.json。骰子樹的邊只表達得出「那顆要先解開」,表達不出 「而且要練到 Lv.50」——太陽骰子(1501)的解鎖條件除了兩條入邊,還要求1201子彈傷害%增加 練滿 50 級。那個門檻沒有地方放,所以另立這一份檔案({"被擋住的節點": {"祖先": 等級}})。 只收需要等級 ≥ 2 的條目:等級 1 就是「解鎖」,邊已經說過了。這條會擋下:外層或內層的 id 不是節點(那個條件會安靜地從來不成立或永遠不成立)、內層 id 不是外層節點的祖先(玩家被要求去練一顆跟這條鏈無關的節點)、等級不是 ≥2 的整數、 等級超過那顆前置節點的
maxLevel(條件永遠達不到,而畫面上跟「前置還沒解完」一模一樣)、 以及把自己列成自己的前置。
以上規則 0–10 與 13–30 都是 npm run validate 實際會檢查的內容,本機先跑過一次就能提早抓到,不用等 CI。
另外兩道 CI 檢查:正規化定點、型別檢查
這兩條不在上面的規則編號裡,但一樣會讓 PR 被擋下:
- 正規化定點檢查:CI 會自己跑一次
npm run normalize,然後要求data/dice-tree.svg一個字都不能變。也就是說「跑過 normalize」還不夠,要跑到再跑一次也不會有差異。 ⚠️ 這跟規則 0 不一樣:規則 0 擋的是解析器讀不懂的結構,定點檢查擋的是格式漂移—— 座標寫成x="897"而正規形式是x="897.00"這種,validate是綠的,定點檢查才會紅。 修法就是在本機跑npm run normalize然後把它產生的改動一起 commit。 - 型別檢查:CI 會跑
npm run typecheck(tsc --noEmit,含noUnusedLocals, 會抓沒用到的 import)。只改data/通常碰不到;動到src/或tools/就一定要先在本機跑過。
規則 12:效能預算(npm run validate 不會查,npm run build 才會查)
這條不是由 npm run validate 檢查,是 npm run build(或單獨執行 npm run build:data)
把資料組裝成正式的 tree.json 與 sprite.webp 之後,順便檢查兩者的體積有沒有超過上限(目前
門檻:tree.json 壓縮後不超過 20 KB、sprite.webp 不超過 400 KB)。這個指令執行時會直接印出
目前實際用量與距離門檻還剩多少餘裕,例如:
tree.json gzip 15.7 KB / 20 KB,餘裕 4.3 KB
sprite.webp 132.3 KB / 400 KB,餘裕 267.7 KB
這個餘裕平常看起來很寬鬆,但 tree.json 那條其實很緊(目前只剩不到 3 KB,換算大約是
再加 40~50 個節點就會超標)——遊戲改版一次加一整個新分支很容易就吃光。所以就算你只是新增
幾個節點、沒有動到既有資料,送 PR 前也建議看一眼這行輸出,餘裕快見底了及早跟其他貢獻者提一下,
不要等真的超標變成紅燈才發現。
超過門檻的話,npm run build(或 build:data)本身就會印出 ❌ 錯誤訊息並以非 0 狀態結束,
CI 的建置步驟也會因此失敗——效果上一樣會擋下 PR,只是踩線的時間點跟 validate 不同。單獨跑
npm run validate 過了,不代表這條也過,送 PR 前記得也跑一次 npm run build(見上一節)。
CI 也會另外跑一次端對端測試(E2E)
除了上面這些資料層級的檢查,CI 還有一個獨立的 job 會把整站建置起來、用真的瀏覽器(Chromium)
跑一遍互動流程(點選節點、搜尋篩選、鍵盤操作、手機版面⋯)。這個 job 因為要另外安裝瀏覽器,
通常比資料驗證那個 job 慢一些,兩者會平行跑、不互相等待——資料本身有沒有問題,通常很快就能
看到結果,不用等瀏覽器裝完。E2E 測試失敗一樣會讓 PR 的 CI 檢查顯示不通過。一般貢獻者如果只是
改 data/dice-tree.svg 或 data/icons/,通常不會影響到這個 job;只有動到 src/ 底下前端
程式碼時才比較需要留意。
這兩個 job 綠了才能合併
verify(資料驗證與建置)與 e2e(端對端測試)在 GitHub 上被設成 main 的必要檢查:只要
其中一個沒通過,PR 的 Merge 按鈕就會被鎖住。main 也不接受直接推送,維護者自己的變更同樣
要走 PR。換句話說,這份文件裡寫的每一條規則,都是真的擋得下來的,不是「建議照做」。
6. 這些情況只會警告、不會擋 PR
以下這幾種情況,npm run validate 只會印出警告(本機執行時終端機就看得到;CI 上則是在 PR 的
Checks 分頁裡展開「資料驗證」那個步驟的記錄檔才看得到),不會讓 PR 被擋下,也不會
另外觸發 PR 留言——只有下一段的規則 11 才會自動貼留言:
- 節點加了
data-wip="1"(代表「先佔位、之後再接線」),這種節點可以先不接到任何前置節點。 - 效果說明裡含有
{n}這種佔位符(代表遊戲原始資料本身還沒填完整數值,不是你的錯,只是提醒)。 - 新增了圖示、但目前沒有任何節點在用它(可能是準備給下一批節點用的,先警告,不擋)。
data/icons/、data/board-icons/與data/dice3-icons/都適用——換圖時留下來的舊檔就屬於 這種,確認沒有別的節點在用就可以直接刪掉。 - 這些圖示目錄裡出現不是小寫
.png的檔案(something.PNG、.DS_Store⋯):站台不會用到 它,但也不會安靜地當作不存在。
另外還有一項提醒不太一樣——它會自動貼在 PR 底下(不只是記錄檔裡才看得到):
- 既有節點的 id 若消失或改變:CI 會在 PR 底下自動貼一則「資料差異摘要」留言(規則 11),
列出新增/刪除/修改的節點數與全樹解鎖成本的變化,id 若消失還會用
⚠️特別標出來,提醒審核者 「分享網址會失效」(骰子樹的分享連結是用 id 組出來的,id 一旦消失,舊的分享連結就打不開了)。 這不會擋 PR,只是顯眼地提醒審核者確認這是不是刻意變更;貢獻者若刻意重新編號某個節點, 建議在 PR 說明裡順手註明原因,方便審核者判斷。這則留言即使是 fork PR 送出的也一樣會出現, 詳見下一節。
關於這則留言的三個細節:
- 一個 PR 只會有一則:同一個 PR 再推 commit 時,機器人會就地更新原本那則,不會愈積愈多。
- 資料完全沒變動就不貼:只改了
src/底下的程式碼或文件的 PR,不會收到這則留言 (如果先前貼過,那則會被改成「沒有變更資料正本的內容」,不會留著過期的警告)。 - 端對端測試紅燈時照樣會貼:差異摘要是資料驗證與建置那個 job 算出來的, 只要那個 job 過了就有摘要。反過來說,如果連資料驗證都沒過,就不會有這則留言—— 那時候 PR 頁面上的紅叉本身已經是更直接的提醒了。
7. 關於 fork PR 的重要提醒
如果你是從自己 fork 出來的 repo 送 PR(而不是直接推到這個 repo 的分支),Cloudflare Pages 不會自動幫你的 PR 建立 preview 網址(這是 Cloudflare Pages 對 fork PR 的預設限制),所以你在 PR 底下不會自動看到「這個改動實際長怎樣」的預覽連結。
這種情況下:
- ⚠️ CI 不會馬上開始跑,要等維護者按一下核准。這是 GitHub 對外部貢獻者的預設保護(送 PR 就等於讓別人的程式在維護者的 CI 額度上執行),本 repo 設定成每一個外部 PR 都要核准。 你看到 checks 卡在「waiting for approval」不是壞掉,等一下就好。
- 核准之後,
npm run validate、正規化定點檢查、型別檢查、單元測試、建置、效能預算、E2E 這些 檢查都會正常跑在你的 PR 上,不受影響——GitHub 對 fork PR 只限制「寫入」類的操作(例如自動 貼留言),不影響「讀取+執行檢查」這類操作。 - 規則 11 的「資料差異摘要」留言也一樣會正常出現:技術上這是靠另一支獨立的 workflow(在本 repo 的情境下執行,而非你 fork 出去那份)讀取檢查結果、貼上留言,繞開了 fork PR 唯讀 token 的限制, 所以你不需要做任何額外的事,正常送 PR 即可。
- 唯一受影響的是 Cloudflare Pages 的視覺預覽:想要看視覺上的預覽,需要請維護者把你的分支拉進
本 repo 觸發部署,或是你自己在本機跑
npm run dev看效果、或截圖貼在 PR 說明裡。
不確定的話,直接在 PR 留言請維護者幫忙看一下即可。
8. 不要上傳遊戲原始資源包本體
data/dice-tree.svg 與 data/icons/ 是我們整理過、拆解出來的必要素材(骰子樹結構、圖示),
請不要把遊戲客戶端解包出來的完整資源包、聲音檔、模型檔等其他素材放進 PR。這個 repo 只收錄
網站呈現骰子樹所需要的最小資料集。
9. 授權說明
- 這個 repo 的程式碼(Astro 站台、工具腳本、測試等,
data/目錄以外的所有內容)採 MIT License(repo 根目錄的LICENSE檔案)。你送出的程式碼變更、以及對data/dice-tree.svg/data/icons/資料本身的修正貢獻(例如修正錯字、補齊缺漏欄位、 更新版本後的數值),都視為對 MIT 授權部分的貢獻,代表你同意以相同條款提供給這個專案使用。 data/目錄內的骰子圖示與遊戲效果文字,其著作權屬於原遊戲開發商 111%(111 Percent Inc.), 詳見data/NOTICE.md。這個 repo 只是把官方已公開呈現的遊戲內容, 整理成方便查閱的資料結構,不主張這些素材本身的著作權。
再次感謝你願意花時間幫忙維護這份資料,讓其他玩家能更清楚地規劃自己的骰子樹!