From 6618674ff7b53685af7944e08aafd68b6c34661f Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 09:11:58 +0800 Subject: [PATCH 01/14] =?UTF-8?q?chore(starpuff):=20T7-C=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20SSOT=20=E6=94=B6=E6=96=82=E9=96=8B=E5=B7=A5?= =?UTF-8?q?=E6=B4=BB=E6=80=A7=E9=8C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 建立 docs/starpuff-t7c-split 分支與隔離 worktree - 後續處理 GAME_DESIGN.md 拆分與 issue #871 文件漂移 測試:無(空 commit 活性錨,不含程式碼變更) Co-authored-by: Cursor From 80b6ec8871a49c2329a91d4cf06b2efd64a71f83 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 09:21:36 +0800 Subject: [PATCH 02/14] =?UTF-8?q?docs(starpuff):=20=E4=BF=AE=E6=AD=A3=20GA?= =?UTF-8?q?ME=5FDESIGN=20=E8=88=87=20T7-A=20=E5=AF=A6=E4=BD=9C=E6=BC=82?= =?UTF-8?q?=E7=A7=BB=EF=BC=88#871=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - §62 慈悲補血改確定性 pity 參數表:受傷/低血雙門檻+魔王 bossPityHurts=2,移除 35%/60% 擲骰 - 新增 §118 記載 sp-settings 單鍵 SSOT、統一設定頁、存檔備援 checksum 與 PWA 更新套用閘 - §9/§34/§35/§36/§38/§63.1/§70/§87/§89/§95/§101 舊敘述加註取代標記 - 三個 legacy 散鍵全檔不再作為現行規格敘述,僅保留為 migration 來源 - docs/dev/002 新增 reward 條目並更新記分行 測試:先讀 mercyHeal.ts/settings.ts/save.ts/pwaUpdateGate.ts 實作核對,prettier 3.8.1 格式通過;純文件變更未跑 vitest Co-authored-by: Cursor --- apps/starpuff/docs/GAME_DESIGN.md | 140 ++++++++++++++---- .../dev/002_development_reward_penalty_log.md | 5 + 2 files changed, 117 insertions(+), 28 deletions(-) diff --git a/apps/starpuff/docs/GAME_DESIGN.md b/apps/starpuff/docs/GAME_DESIGN.md index fb4653dca..746b988ba 100644 --- a/apps/starpuff/docs/GAME_DESIGN.md +++ b/apps/starpuff/docs/GAME_DESIGN.md @@ -62,7 +62,7 @@ hit-stop 60ms、震屏 4px、受擊白閃、squash & stretch(跳躍/落地/吸 ## 9. 音效(zzfx,零音檔資產) -jump、flap、inhale(迴圈)、swallow、shoot、hit、hurt、metal(皇冠落地)、pop(puffy 爆裂)、chomp(咬咬花咬合)、boss-roar、boss-slam、win、lose;BGM 用 zzfx 合成短循環(手刻序列混音,零依賴)。首次觸控後 resume AudioContext(iOS 必須)。靜音偏好存 localStorage(sp-muted)。 +jump、flap、inhale(迴圈)、swallow、shoot、hit、hurt、metal(皇冠落地)、pop(puffy 爆裂)、chomp(咬咬花咬合)、boss-roar、boss-slam、win、lose;BGM 用 zzfx 合成短循環(手刻序列混音,零依賴)。首次觸控後 resume AudioContext(iOS 必須)。靜音偏好存 localStorage(sp-muted)(v19 已由 §118.1 取代:收斂為 `sp-settings.audioMuted`,`sp-muted` 僅作一次性 migration 來源,落盤後刪除)。 ## 10. 美術資產規格(codex imagegen 專用;除此之外嚴禁動用 codex) @@ -322,7 +322,7 @@ Arcade Physics 相容優先(斜坡不做——Arcade 無原生支援,違反 - 人體工學定案(§33 條目 7):雙手橫持時拇指錨於下側角、食指自然落在裝置上緣——A 跳躍維持右下(拇指連打),B 吸/射移至右側偏上(食指按壓;與 A 垂直遠離杜絕誤觸);方向搖桿維持左半屏。 - 布局 SSOT:`core/layout.ts`——按鍵中心以 keys-layer 安全區內比例(cx/cy 0-1)表示,直橫持共用;`DEFAULT_LAYOUT`:A (0.92, 0.78)、B (0.92, 0.34)。(v16 已由 §95 取代「預設」的直持適用性:預設依殼旋轉態分流 `defaultLayoutFor`,直持採右下拇指帶錨點;自訂布局仍直橫持共用。) - `#keys-layer`:安全區內鋪滿的定位容器(四向 `max()` 地板+portrait 換軸表),按鍵以 `left/top %` + `translate(-50%,-50%)` 定位。 -- 按鈕自訂(KISS:拖曳+儲存+重置,不做進階編輯器):Title「按鈕配置」→ `systems/keyConfig.ts` DOM 覆層——直接拖曳真實 A/B 鍵即時預覽,「儲存並返回」寫入 localStorage `sp-key-layout`(schema `{version:1, a:{cx,cy}, b:{cx,cy}}`;版本不符/損毀回退預設),「恢復預設」一鍵還原。拖曳座標經 `pointerToLocal` 換軸,夾限 `KEY_CLAMP` 保證按鍵完整在畫面內。(v14 已由 §88/§89 取代操作列結構與 schema:schema 升 v2 增全域縮放、操作列直欄化並增持向切換與縮放列。) +- 按鈕自訂(KISS:拖曳+儲存+重置,不做進階編輯器)(v19 已由 §118.1/§118.2 取代入口與儲存位置:入口自 Title 直鈕改為設定頁轉入,布局改存 `sp-settings.keyLayout`,`sp-key-layout` 僅作 migration 來源):Title「按鈕配置」→ `systems/keyConfig.ts` DOM 覆層——直接拖曳真實 A/B 鍵即時預覽,「儲存並返回」寫入 localStorage `sp-key-layout`(schema `{version:1, a:{cx,cy}, b:{cx,cy}}`;版本不符/損毀回退預設),「恢復預設」一鍵還原。拖曳座標經 `pointerToLocal` 換軸,夾限 `KEY_CLAMP` 保證按鍵完整在畫面內。(v14 已由 §88/§89 取代操作列結構與 schema:schema 升 v2 增全域縮放、操作列直欄化並增持向切換與縮放列。) ## 35. v5 暫停系統與離頁自動暫停 @@ -331,12 +331,12 @@ Arcade Physics 相容優先(斜坡不做——Arcade 無原生支援,違反 - 全停語義:`scene.pause(Game)`(物理/計時/tween/輸入輪詢全停)+ `AudioContext.suspend()`(BGM 與 SFX 全停)。 - 重新開始=重置當前關卡全狀態(血量/彈藥/擊殺數/計時/實體經 scene.restart 重生),保留已完成關卡累計用時與本輪死亡數。 - 離頁自動暫停:`visibilitychange`(hidden)與 `pagehide`(同走 hidden 檢查防雙觸發)即開暫停選單;回前景停在選單、玩家點「繼續」才接續(取代 §26 的自動恢復,杜絕回前景瞬間被偷襲)。音訊恢復一律走手勢堆疊內 `resume()`(§33 條目 6),刻意暫停期間全域復聲保險不生效。 -- 與 PWA 週期更新 hooks(main.ts `import './pwa'`)共存:兩者互不依賴,同檔並列。已知邊界:回前景恰逢新版部署時,autoUpdate 完成後的 reload 會重新載入頁面蓋過暫停選單,屬可接受權衡,不特別攔截。 +- 與 PWA 週期更新 hooks(main.ts `import './pwa'`)共存:兩者互不依賴,同檔並列。已知邊界:回前景恰逢新版部署時,autoUpdate 完成後的 reload 會重新載入頁面蓋過暫停選單,屬可接受權衡,不特別攔截。(v19 已由 §118.4 取代此已知邊界:更新套用改經殼層安靜閘,遊戲進行中與暫停選單期間絕不 reload。) ## 36. v5 開場主選單與圖鑑/技能介紹 - Title 開場動畫:主標縮放彈出(Back.easeOut)、副標延遲淡入、主角自天而降 Bounce 落定+光暈淡入;維持既有美術風格與 zzfx 音效(選單按壓 pop)。 -- 主選單:開始遊戲(主鈕)+次選單列 圖鑑/技能介紹/按鈕配置(DOM 鈕承接命中,data-menu 標識)。 +- 主選單:開始遊戲(主鈕)+次選單列 圖鑑/技能介紹/按鈕配置(DOM 鈕承接命中,data-menu 標識)。(v6 §39 增「世界地圖」;v19 已由 §118.2 取代次選單構成:世界地圖/圖鑑/技能介紹/設定四鈕,按鈕配置移入設定頁轉入口;桌機另增常駐「操作說明」,見 §87.4。) - 圖鑑/技能介紹(`CodexScene` 單場景雙分頁,資料 SSOT `core/codex.ts`,立繪一律取既有 sprite 資產、禁止新美術): - 圖鑑分頁:全 8 角色(jelly/floaty/spiky/puffy/chompy/shelly/zappy/boss)4×2 網格——立繪+名稱+行為一句話+可吸/不可吸圓點標記。(v7 擴 5×2 十格;v8 擴 7×2 十四格;v9 已由 §59 取代:8×2 十六格。) - 技能分頁:吸入/星彈三系(含來源怪物對應)(v6 已由 §40 擴充為五系+殼盾/雷鏈條目;v7 §44/§46 移除空中疾衝、增混合星彈與七系敘述)/強化星/星暴/下衝擊/漂浮,雙欄列表(名稱+操作+效果)。 @@ -356,12 +356,12 @@ Arcade Physics 相容優先(斜坡不做——Arcade 無原生支援,違反 ## 38. 存檔系統(core/save.ts 為 SSOT,pure TS 可測) -- localStorage `sp-save` schema v1:`{ schemaVersion, highestClearedLevel, levels: { [id]: { cleared, bestTimeMs, eggsFound: string[] } }, lastPlayedAt }`。 +- localStorage `sp-save` schema v1:`{ schemaVersion, highestClearedLevel, levels: { [id]: { cleared, bestTimeMs, eggsFound: string[] } }, lastPlayedAt }`。(v15 已由 §94.2 升 v2 增 `achievements`;v19 已由 §118.3 補訂 checksum 欄與 `sp-save-backup` 備援。) - 寫入時機:通關(星星門吸入當下即寫,演出中斷不掉進度)、魔王擊破、彩蛋觸發(`trigger` 型別字串為關內唯一 id)。 -- 容錯(沿用 §34 sp-key-layout parse/fallback 模式):schema 版本不符、形狀損毀、隱私模式拋錯——一律回退預設值;`highestClearedLevel` 由關卡條目重新推導,不信任持久化值。 +- 容錯(沿用 §34 鍵位布局 parse/fallback 模式):schema 版本不符、形狀損毀、隱私模式拋錯——一律回退預設值;`highestClearedLevel` 由關卡條目重新推導,不信任持久化值。 - `bestTimeMs`=該關單次成功嘗試的最短用時(死亡重試重計);`eggsFound` 去重持久化,跨局累計。 -- 重置進度:世界地圖左下「重置進度」兩步確認(武裝態 3s 未確認自動退回),僅清 `sp-save`(按鍵布局 `sp-key-layout`、靜音 `sp-muted` 不動)。全新存檔不顯示入口。 -- 偏離備註:任務原文「設定頁加重置進度」——本遊戲無設定頁(按鈕配置為鍵位編輯器,語義不符),重置入口落於世界地圖(進度顯示與進度管理同場景,KISS)。 +- 重置進度:世界地圖左下「重置進度」兩步確認(武裝態 3s 未確認自動退回),僅清存檔(偏好不動)。全新存檔不顯示入口。(v19 已由 §118.3 補訂清除範圍:同時清 `sp-save` 與備援 `sp-save-backup`;偏好鍵自 `sp-key-layout`/`sp-muted` 收斂為 `sp-settings`。) +- 偏離備註:任務原文「設定頁加重置進度」——v6 當時本遊戲無設定頁(按鈕配置為鍵位編輯器,語義不符),重置入口落於世界地圖(進度顯示與進度管理同場景,KISS)。(v19 已由 §118.2 取代前提:Title 已有「設定」入口,但重置進度**維持在世界地圖**——進度顯示與進度管理同場景的 KISS 裁決不變。) ## 39. 迷霧世界地圖(MapScene,data-driven 自 LEVELS) @@ -817,17 +817,26 @@ epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 ## 62. v9 慈悲補血愛心(logic/mercyHeal.ts 純決策,保底機制非資源農場) -- 機制參數表(`MERCY_HEAL`,RNG 與時鐘由呼叫端注入供測試): - -| 參數 | 值 | 說明 | -| -------- | --------------- | ------------------------------------------ | -| 評估間隔 | 5000ms | 每 5s 評估一次(未過門檻僅重置計時不擲骰) | -| 血量門檻 | HP ≤ 總血量 1/3 | 5 血制即 HP ≤1 | -| 久戰門檻 | ≥60s | 本關(本命)經過時間 | -| 生成冷卻 | ≥45s | 距上次愛心生成 | -| 觸發機率 | 35% | 全門檻通過後擲骰 | -| 每命上限 | 2 次 | 死亡重試/重開關卡即重置 | -| 回復量 | +1 HP | 走既有回復管線 | +- 機制參數表(`MERCY_HEAL`,**確定性 pity 決策**;時鐘由呼叫端注入供測試,RNG 僅決定 + 生成位置不參與生成與否——v19 #819 卡 9 去 RNG,取代原 35%/60% 擲骰): + +| 參數 | 一般關 | 魔王房(含 EX)override | 說明 | +| ------------- | --------------- | ----------------------- | ---------------------------------------------- | +| 評估間隔 | 5000ms | 同左 | 每 5s 評估一次(未過門檻僅重置評估計時) | +| 血量門檻 | HP ≤ 總血量 1/3 | HP ≤ 2(絕對值) | 5 血制一般關即 HP ≤1 | +| 久戰門檻 | ≥60s | ≥12s | 本關(本命)經過時間;boss 戰典型 20–60s | +| 生成冷卻 | ≥45s | ≥18s | 距上次愛心生成 | +| pity 受傷門檻 | ≥2 次 | ≥2 次 | `pityHurts`/`bossPityHurts`,自上次生成起累計 | +| pity 低血門檻 | ≥30s | ≥15s | `pityLowHpMs`/`bossPityLowHpMs`,低血累計時間 | +| 每命上限 | 2 次 | 2 次(EX 1 次) | `exMaxPerLife=1`;死亡重試/重開關卡即重置 | +| 回復量 | +1 HP | 同左 | 走既有回復管線 | + +- pity 決策語意(`advanceMercyHeal`):**首顆固定生成**(`spawned === 0`);第二顆起需 + 自上次生成後累積「受傷次數 ≥ pity 受傷門檻」**或**「低血狀態累計 ≥ pity 低血門檻」 + 任一成立才保底放行。受傷偵測=HP 較上一 tick 下降即計 1(單次多傷計 1,回血僅更新 + 基準);低血累計僅於存活且過血量門檻時推進。生成當下 pity 計量歸零。 +- 計量與評估分離:pity 計量逐幀累積,評估間隔到期才做生成決策;任一門檻不過只重置 + 評估計時,**保底計量不消耗**(低血久撐不會白費)。 - 生成呈現(重用共用愛心拾取管線 systems/pickups.ts,勿新造 pickup 系統):隨機擇一 ——空中緩降型(y=150 起以 26px/s 緩慢飄落至地面錨點,降落中可接住)或地面定點型 @@ -868,7 +877,7 @@ epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 | levels L7 | 補給構成 | jelly/floaty/gusty | **jelly/floaty/zappy** | 移除俯衝型騷擾;保雷化斷召素材 | | waves.ts | 補給入場側 | 左右交替 | **玩家遠側** | 走向玩家的路程=拾取節奏 | | homing.ts | `BOSS_AIM_ASSIST` | 無 | **range 560 / 0.0012 rad/ms** | 一般星彈對魔王微導向:地面平射自然上彎入盤旋帶(追蹤彈 1/5 轉率、須大致對向;追電/迴旋星不疊加) | -| mercyHeal | 魔王房 override | 無 | **HP≤2、12s、18s CD、60%** | boss 戰長度下保底真正可觸發 | +| mercyHeal | 魔王房 override | 無 | **HP≤2、12s、18s CD、60%** | boss 戰長度下保底真正可觸發(v19 已由 §62 取代 60% 擲骰:改 pity 受傷 2 次/低血 15s 保底) | ### 63.2 驗收證據(噗頭對噗頭 bot 實測,序列執行;`scripts/noctra-bot-audit.mjs`) @@ -1026,8 +1035,9 @@ epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 - 新觸發器 `twin-finish`(eggs.ts 第五型):時窗真值由 prismixFsm 持有(單一真值), GameScene 收到 twinFinish 事件餵入觸發器——鎖存、gold-star 獎勵+全屏稜光演出; `vent-hit-count` 已於 v11 落地(§75)、`survive-collect` 隨 v12(主計畫 §7.3)。 -- 慈悲補血:L12 沿用 §62 魔王房 override(HP≤2、12s 起評、18s 冷卻、60%、上限 2)—— - `bossRoom` 判定隨 `level.boss` 泛化,零新碼。 +- 慈悲補血:L12 沿用 §62 魔王房 override(HP≤2、12s 起評、18s 冷卻、上限 2;v19 已由 + §62 取代 60% 擲骰:改 pity 受傷 2 次/低血 15s 保底)——`bossRoom` 判定隨 `level.boss` + 泛化,零新碼。 - anti-softlock 不變式(測試守門):warp 四不變式(§66);checkpoint 落點房界外(§67); L12 補生全可吸且恆可吸佔比 ≥0.6;碎晶盾可全數擊破(星彈屏障非無敵殼);前室單向門 重試自前室起、arena 無門鎖擊破制(§10.2-10);增益永不必需(§69)。 @@ -1487,10 +1497,14 @@ epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 bottom→殼左;cw 維持 v4 原表。 - 偏好持久化:localStorage `sp-rotation`('cw'|'ccw',缺省=ccw 新預設; 不進 save schema);讀取走記憶體快取(pointer 熱路徑不重複讀 storage)。 + (v19 已由 §118.1 取代儲存位置:收斂為 `sp-settings.shellRotation`, + `null`=從未選擇;`sp-rotation` 僅作一次性 migration 來源,落盤後刪除。 + 記憶體快取語意不變。) ### 87.2 回訪玩家保護(肌肉記憶) -- 既有玩家(sp-save 有進度且未曾設定 sp-rotation)首次進站於 Title 顯示一次性 +- 既有玩家(存檔有進度且未曾設定持向偏好——v19 §118.1 即 + `sp-settings.shellRotation === null`)首次進站於 Title 顯示一次性 方向告知卡(§92 殼層卡片):說明新方向並提供「切回舊方向」一鍵; 已示記憶 localStorage `sp-rotation-notice`。全新玩家無感知不打擾。 - 持向切換入口常駐「按鈕配置」操作列(§88),納入草稿語意:切換即時預覽、 @@ -1499,7 +1513,7 @@ epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 ### 87.3 驗證 - 座標矩陣單測(rotation.test.ts 九案):三態四角/中心/滑動向量映射斷言。 -- portrait e2e 雙案:ccw 新預設(上滑=往右)+ sp-rotation=cw 舊方向回歸 +- portrait e2e 雙案:ccw 新預設(上滑=往右)+持向偏好設為 cw 的舊方向回歸 (下滑=往右、殼 matrix 斷言)。畫布覆蓋率 99.98% 不變。 ### 87.4 方向解鎖引導+桌機正置(#817,T2) @@ -1529,6 +1543,8 @@ epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 - schema v1→v2 versioned migration:v1 舊存檔鍵位保留、`scale` 補預設 1; 未知版本回退預設。v2:`{version:2, a, b, scale}`,scale 夾限 0.8–1.3。 + (v19 已由 §118.1 取代儲存位置:**schema 形狀不變**,改存於 + `sp-settings.keyLayout` 子樹;`sp-key-layout` 僅作一次性 migration 來源。) - 縮放經 CSS 變數 `--sp-key-scale` 單點驅動鍵體與鍵帽(clip-path 圖形同步), 觸控熱區隨元素幾何自然同步;`KEY_BASE_PX`(A76/B72)與 style.css 以單測 跨檔守門防雙寫漂移。 @@ -1643,14 +1659,15 @@ epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 (A fx 0.82/fy 0.86、B fx 0.80/fy 0.68——右下拇指帶、B 沿拇指弧在 A 上方), `defaultLayoutFor(rotation)` 依殼向反算層比例:ccw cx=1−fy、cy=fx; cw cx=fy、cy=1−fx(§87 軸向映射逆向);橫持沿用 v14 定案。 -- schema 不動(sp-key-layout v2 零遷移):合法自訂資料在任何持向原樣適用; +- schema 不動(鍵位布局 v2 零遷移,§89):合法自訂資料在任何持向原樣適用; 只有「無自訂/損毀回退」與「恢復預設」走旋轉感知預設。 - 直持下 A/B 幾何上與 joy-zone 重疊(裝置下半即遊戲左半):keys-layer 為後繪 兄弟層,按鍵天然承接命中;誤觸空白處僅錨定浮動搖桿(點按零位移,無害)。 ### 95.2 儲存語意(配置頁) -- 預設態不落盤:從未自訂或按過「恢復預設」後儲存=清除 sp-key-layout, +- 預設態不落盤:從未自訂或按過「恢復預設」後儲存=清除布局(v19 §118.1: + `sp-settings.keyLayout` 置 null,v14–v18 為清除 `sp-key-layout` 鍵,語意等價), 直橫持各自動態解析預設;拖曳/縮放屬自訂,儲存持久化具體布局(維持 v14 單一共用布局語意)。 - 「恢復預設」依當前草稿持向給對的錨點;持向切換(cw/ccw)時預設態即時重映射, @@ -1742,8 +1759,9 @@ epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 canvas 圖示保留純視覺、移除 interactive(沿 recon-v4 A.3 單一命中路徑); `pause.ts addButton` 補 aria-label。 - 命中尺寸:邏輯 44×44 經 §98 短邊 48px 保底,直橫持皆達標。 -- 驗證:v16 e2e(暫停開選單真凍結→繼續、靜音 aria-pressed 與 sp-muted 同步 - 翻轉);portrait e2e 真觸控點暫停即凍結、pause/mute AABB 短邊 ≥48。 +- 驗證:v16 e2e(暫停開選單真凍結→繼續、靜音 aria-pressed 與靜音偏好同步 + 翻轉——v19 §118.1 後偏好真值為 `sp-settings.audioMuted`);portrait e2e + 真觸控點暫停即凍結、pause/mute AABB 短邊 ≥48。 ## 102. v16 配置模式遮罩加深(F-04,補充 §34) @@ -2440,3 +2458,69 @@ W3 合議收斂:補齊 §8.2 表前二王真 P4(stub 落地)+Syrona 暴 - 行為錨:visualScale.test 鎖住「動畫期間物理讀取窗 scale 恆為基準」契約與 池重用重錨、shutdown 清理語意;行為零改變由全量 vitest+e2e 全套+ level-audit L1/L14/L16 EX 對比 base 佐證。 + +## 118. 使用者設定 SSOT、存檔備援與 PWA 更新閘(#819;T7-A 列車) + +現行偏好與持久化 SSOT。取代散落 localStorage 鍵敘述:§9 靜音鍵、§34/§89/§95.2 鍵位 +布局鍵、§87.1 旋轉方向鍵,以及 §38 的「本遊戲無設定頁」偏離備註與重置範圍描述。 + +### 118.1 UserSettings 單鍵 SSOT(core/settings.ts) + +- 儲存鍵 `sp-settings`(`SETTINGS_SCHEMA_VERSION = 1`)為**唯一偏好真相**,欄位: + `audioMuted`/`hapticsEnabled`/`wakeLockEnabled`/`reducedMotion`/`screenShake` + (`off|low|full`)/`shellRotation`(`cw|ccw|null`,null=從未選擇供 §87.2 一次性 + 告知判定)/`keyLayout`(§89 v2 子樹,null=預設態不落盤,§95.2 語意不變)。 +- `reducedMotion` 預設尊重系統 `prefers-reduced-motion`(WCAG 2.3.3);非瀏覽器環境 false。 +- **一次性 migration**:首次讀取時吸收 legacy 散鍵 `sp-muted`/`sp-rotation`/ + `sp-key-layout` 為初始值(值損毀逐項回預設),**落盤成功即刪除三個 legacy 鍵** + (單真相;PWA 部署單向前進,回滾非支援路徑,殘留舊值會在主鍵遺失時被吸回過期偏好)。 + 例外語意:`persist` 失敗(隱私模式/配額滿)**保留 legacy 作下次開機來源**。 +- 主鍵損毀(JSON 壞損/版本不符/形狀損毀):回退 legacy 吸收並回寫修復,不以預設 + 靜默覆蓋;置 `wasSettingsRecoveredFromCorruption` 旗標,main.ts 於 Title 安靜時刻 + 以殼卡(§92)明確告知。 +- 一次性記憶鍵(`sp-rotation-notice`/`sp-install-dismissed`/`sp-desktop-keys`/ + `sp-orientation-hint` 等)非偏好,**不入本 schema**。 +- 已知限制:偏好經記憶體快取、無 storage event 跨分頁同步——多分頁併發寫入為 + last-writer-wins(單分頁互動情境,接受此限制)。 + +### 118.2 統一設定頁(systems/settingsPage.ts,取代 §38「無設定頁」備註) + +- Title 次選單第四鈕「設定」(`data-menu="settings"`)開啟純 DOM overlay(沿 + keyConfig/shellCards 慣例,不進 Phaser Scene);容器沿用 `.install-overlay` + class,`isShellBusy` 天然視為忙碌(與 PWA 套用/殼卡排隊互斥)。 +- 內容:音效/震動回饋/遊戲中螢幕常亮/減少動態效果四開關+震屏強度三段 + (關/弱/全)+「按鈕配置(鍵位與持向)」轉入口(§34 keyConfig 專頁由此轉入, + 不再是 Title 獨立鈕)+「完成」。ESC 關閉。 +- **即改即存**,無草稿語意(草稿/取消回滾僅存在於按鈕配置頁,§87.2/§95.2 不變); + 音效切換同步 mute 系統,震動開啟時輕震一次即時回饋。 +- 震屏/閃光偏好落地(`systems/cameraFxGate.ts`):一次性包裝 main camera 的 + `shake`/`flash`,全部 boss/fx 呼叫端零改動即受管——`reducedMotion` 或 + `screenShake:'off'` 時震屏強度 ×0(直接不震)、`low` ×0.5、`full` ×1; + `reducedMotion` 另將 flash 時長 ×0.3(未帶參呼叫以 Phaser 預設 250ms 為基準)。 + 偏好每次呼叫重讀,設定頁改動即時生效。 + +### 118.3 存檔備援與 checksum(core/save.ts,補訂 §38) + +- schema 現值 v2(§94.2 已升版;§38 的 v1 敘述為 v6 歷史值)。寫入時附 + `checksum` 欄;解析時 checksum 不符/JSON 壞損/未知版本一律判**損毀**。 + legacy 存檔(無 checksum 欄)視為合法,不誤殺舊玩家。 +- 備援鍵 `sp-save-backup`:每次寫入前把**上一份合法主檔**輪替至備援(損毀資料不 + 污染備援);主檔損毀時自備援恢復並回寫自癒,備援亦不可用才回退預設——兩路徑 + 皆 `console.warn` 留痕,不再默默歸零。備援輪替失敗(配額不足/隱私模式)不得 + 阻斷主檔寫入。 +- **重置進度範圍修正**(取代 §38 的「僅清 `sp-save`」):`resetSave` 同時清除 + `sp-save` 與 `sp-save-backup`(否則重置後會自備援恢復出舊進度);偏好 + (`sp-settings`:靜音/鍵位/持向等)不動。入口與兩步確認語意沿 §38 不變。 + +### 118.4 PWA 更新套用時機閘(pwaUpdateGate.ts) + +- 新版 SW ready 只標記 pending,**遊戲進行中絕不 reload**;僅在殼層安靜 + (非 GameScene/非配置中/無殼卡=Title/Map/Result 選單面,忙碌訊號沿 + `shellCards.isShellBusy` 單一 SSOT)才自動套用。 +- 套用寬限 1500ms:條件成立後再等寬限期並重驗,期間殼層轉忙(再入遊戲)即放棄 + 本次套用交還重試管線——避免場景切換瞬間 reload 吃掉使用者正要按下的點擊 + (Result「下一關」CTA 競態,§100)。 +- 邊界事件漏接保險:pending 期間每 5s 低頻重試;`#controls` class 變化 + (MutationObserver)=遊戲進出場邊界,離開 GameScene 當下即嘗試套用。 +- 取代 §35 的已知邊界敘述「autoUpdate 完成後的 reload 會蓋過暫停選單」——該競態 + 已由本閘根治(暫停選單期間 `#controls.is-active` 仍為真=殼層忙碌,不會套用)。 diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index db5f5610a..e779f48f5 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:reward-starpuff-t7c-871-doc-drift-settings-mercy +- 原因:T7-A(#864)改了慈悲補血判定與偏好儲存架構卻零文件同步,GAME_DESIGN 仍記 35%/60% RNG 擲骰與 sp-muted/sp-rotation/sp-key-layout 三散鍵,且宣告「本遊戲無設定頁」(issue #871,P1 SSOT drift) +- 解法:先讀 mercyHeal.ts/settings.ts/save.ts/pwaUpdateGate.ts 實作反寫文件——§62 改確定性 pity 參數表(含 bossPityHurts=2 與首顆固定生成語意)、新增 §118 記載 sp-settings 單鍵 SSOT/migration 刪 legacy 與 persist 失敗例外/設定頁/存檔備援 checksum/PWA 更新閘,並對 §9/§34/§35/§36/§38/§63.1/§70/§87/§89/§95/§101 舊敘述加取代標註 + - 日期:2026-07-26 - ID:reward-starpuff-release-verifiability-doc-accuracy - 原因:兩席複審殘留扣分皆為敘述精確性——002 本身兩處與實作不符(宣稱 shell 與 JS 用「同一條」regex,實則 JS 另帶 `i` 並正規化小寫而 shell 大小寫敏感;`__resetSaveUnavailableForTests` 標為 dev-only,實則執行期無 env 閘只是命名慣例),save.ts 例外註解以「提示會反覆洗版」為由但 `notifySaveUnavailable` 早有 session 級單次守衛,且「備援回寫本身失敗」的貫穿場景無直接回歸鎖 From b285b54930d05bf4095281aa3efdba60d8729172 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 09:45:16 +0800 Subject: [PATCH 03/14] =?UTF-8?q?docs(starpuff):=20=E4=BE=9D=E4=B8=BB?= =?UTF-8?q?=E9=A1=8C=E6=8B=86=E5=88=86=E8=A8=AD=E8=A8=88=20SPEC=20?= =?UTF-8?q?=E4=B8=A6=E5=BB=BA=E7=AB=8B=E5=8F=96=E4=BB=A3=E5=B0=8D=E7=85=A7?= =?UTF-8?q?=20SSOT=EF=BC=88T7-C=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 2436 行單檔按 §NN 邊界機械拆為 design/00-08 九個主題檔,各檔開頭聲明職責範圍與邊界 - 新增 design/99-superseded.md:取代對照表(權威索引)+版本列車沿革+已失效內容搬遷區 - GAME_DESIGN.md 改為索引入口——章號對照表、主題檔一覽、硬不變式;路徑不變故外部引用不斷 - 章號 §N 不重新編號(src 註解直接引用),索引表負責章號到檔案的解析 - §15 v2 直向配置表、§43 v6 攻略表、§30 空中疾衝規格三塊全失效內容移入歷史檔並留指路句 測試:逐章比對驗證 118 章零遺失(115 章逐字元相同、3 章為刻意搬遷且規格行全數落在歷史檔), prettier 3.8.1 通過,全 repo grep 確認零錨點引用 Co-authored-by: Cursor --- apps/starpuff/docs/GAME_DESIGN.md | 2689 +---------------- apps/starpuff/docs/design/00-foundations.md | 132 + .../starpuff/docs/design/01-controls-input.md | 373 +++ apps/starpuff/docs/design/02-combat-star.md | 167 + .../starpuff/docs/design/03-enemies-bosses.md | 764 +++++ apps/starpuff/docs/design/04-levels-world.md | 467 +++ apps/starpuff/docs/design/05-save-settings.md | 136 + apps/starpuff/docs/design/06-ui-shell-pwa.md | 163 + apps/starpuff/docs/design/07-art-audio-fx.md | 118 + apps/starpuff/docs/design/08-safety-nets.md | 235 ++ apps/starpuff/docs/design/99-superseded.md | 146 + .../dev/002_development_reward_penalty_log.md | 5 + 12 files changed, 2871 insertions(+), 2524 deletions(-) create mode 100644 apps/starpuff/docs/design/00-foundations.md create mode 100644 apps/starpuff/docs/design/01-controls-input.md create mode 100644 apps/starpuff/docs/design/02-combat-star.md create mode 100644 apps/starpuff/docs/design/03-enemies-bosses.md create mode 100644 apps/starpuff/docs/design/04-levels-world.md create mode 100644 apps/starpuff/docs/design/05-save-settings.md create mode 100644 apps/starpuff/docs/design/06-ui-shell-pwa.md create mode 100644 apps/starpuff/docs/design/07-art-audio-fx.md create mode 100644 apps/starpuff/docs/design/08-safety-nets.md create mode 100644 apps/starpuff/docs/design/99-superseded.md diff --git a/apps/starpuff/docs/GAME_DESIGN.md b/apps/starpuff/docs/GAME_DESIGN.md index 746b988ba..a8745a95b 100644 --- a/apps/starpuff/docs/GAME_DESIGN.md +++ b/apps/starpuff/docs/GAME_DESIGN.md @@ -1,2526 +1,167 @@ -# 星噗噗 StarPuff — 遊戲設計 SPEC(SSOT) +# 星噗噗 StarPuff — 遊戲設計 SPEC(索引) > 手機優先 PWA 動作小遊戲。穿越層層果凍關卡、吸入果凍怪、化為星彈、擊敗果凍魔王。 -> 版本:v20(PM 派工;T4 變身 2.0 §110——三形態攻/防/機動三語彙加深(雷放電反擊·磁免疫/風落地滾翻·滑翔/殼滾殼衝撞·受身入殼)+MechanicProgressionMatrix 落 levels.ts(teaches/bossApplies 圖遍歷守門)+L3 變身教學位點(drillSpawns 同系供給+SP 首現浮字)+變身優勢情境模板(TRANSFORM_ADVANTAGE,Jellord/Noctra 先行)與 level-audit --transform TTK 對照 hook(#816)、T3 星暴 2.0 輸入層 SSOT §109——彈匣 5 槽滿匣自動結晶/SP 情境鍵(引爆·變身·解除天然互斥,鍵盤 C)/B 鍵收斂三語意(點按發射·按住吸入·殼盾星舉盾),B 長按 0.8s 星暴與地面長按 0.6s 變身全數退場(#815,修 #812 輸入面)、v18 修復列車 §107——全 20 關實測回饋三修:走動關飢荒救援律(#804,STARVATION_RESCUE_MS 4s 強制補生可吸怪)/L5 供給節奏調參(#805,gusty·spora -5pt 讓渡 jelly·floaty)/L14 滿潮死亡螺旋雙修(#806,浸水甦醒無敵 +1000ms+滿潮生成降載 floodHold)、v17 債務列車 §106——行為零改變維護性收斂:GameScene strangler 拆解(2121→1196 行,bossFactory/starCombat/starSteering/overlaps/eggTracker/toasts 六模組)/GameEvents 契約測試/ESLint max-lines 守門、v16 產品缺陷修復列車 §95-§105——三席批評收斂:直持預設鍵位重錨右下拇指帶(cw/ccw 雙向+預設態不落盤儲存語意)/圖鑑分頁有界網格(y≤470 守門)/區關命名層級標示/選單 DOM 鈕命中短邊 48 保底/版本頁腳 SHA 來源修正/勝利結算「下一關」主 CTA/HUD 暫停靜音 DOM 化+aria/配置遮罩加深/標題字形品牌化/怪物圖鑑分頁化(每頁 12 格)/教學關死亡配額結轉與精英門明示提示、v15 成就系統列車 §94——21 條成就 SSOT 純呈現層聚合(進度/魔王/EX/收集/速通/隱藏)/save schema v2 versioned migration 與舊玩家開機補發/圖鑑成就分頁與解鎖 toast 佇列/Result 解鎖名單、v14 UX/PWA 列車 §87-§93——直持預設方向翻轉 ccw(含回訪告知與偏好切換)/按鈕配置直欄化與標籤單行/虛擬鍵縮放(sp-key-layout v2)/PWA 安裝偵測與分平台指引/觸覺回饋與螢幕常亮/殼層卡片基建/殼局部 safe-area 量測、v13 EX 全魔王與星核制霸 §86——五王 EX 徽鈕開放收尾/EX 慈悲上限/EX 再戰保留/L4·L7 前室 retrofit/星核制霸全制霸獎勵、v12.1 P0 熱修 §85——真實觸控下滑判定重修(扇區+幅度+drop-intent 緩衝窗+蹲下鉗水平)、v12 五區終章 §78-§84——分區分頁世界地圖/流星雨/Twinkla·Cometa/低重力/L17-L20 二十關完結/最終魔王蝕星魔核 Voidra(生存段·星核共鳴·段起點重試)/星光復甦謝幕與圖鑑補完、v11.1 P0 熱修 §77——站台下跳穿落根修/蹲姿與跳鍵下跳指示/吸入接觸豁免/大嘴吸入影格、v11 四區完結 §71-§76——糖漿潮汐/熱泉噴口/Bubbla·Splatta/L13-L16 十六關/第四魔王 Syrona 場控型(噴泉洗牌·皇冠弱點·窯風三連)、v10 三區完結 §65-§70——星門折躍/L10-L12 十二關/卡點 checkpoint/第三魔王稜晶雙子 Prismix/魔王關特殊體系(前室·增益·專屬彩蛋)、v9.1 P0 熱修 §64——Noctra 返空連續飛行/星暴 5s 無敵窗、v9 星化與挑戰 §57-§63、v8 世界擴張 §50-§56、v7 手感與深度 §44-§49、v6 存檔/世界地圖/新技能/手感 §38-§43、v5 控制自訂/暫停/圖鑑/開場 §33-§37、v4 免轉向與元素包 §28-§32、v3 橫式轉向 §21-§27)|路由:`https://app.haotool.org/starpuff/`|24h 衝刺交付 - -## 1. 產品定位 - -- 橫式(landscape)四關側向卷軸動作遊戲:三關走動探索 + 魔王關(Boss Rush 收尾),單局 2–4 分鐘,可無限重玩。(v8 已由 §50 取代:七關雙魔王;v9 已由 §60 取代:九關——七關走動探索+兩座魔王關+雙 EX 變體。) -- 原創 IP:主角與怪物皆為原創設計(果凍星球世界觀),嚴禁使用任天堂卡比之名稱、造型、配色構圖。 -- 目標體驗:Q 彈、可愛、爽快——大量擠壓拉伸、粒子、震屏、音效回饋。 - -## 2. 核心循環 - -移動/跳躍/漂浮 → 長按吸入小怪 → 吞下獲得星彈(上限 5,v19 §109)→ 點按發射星彈打魔王 → 閃避彈幕與衝撞 → 擊破勝利。 - -## 3. 場景流程 - -`BootScene`(載入+進度條)→ `TitleScene`(標題、開始按鈕、音效提示)→ `MapScene`(v6 世界地圖 hub,§39)→ `GameScene`(四關制)(v8 已由 §50 取代:七關流程;v9 已由 §60 取代:九關流程)→ `ResultScene`(勝/敗)。 - -四關制流程(v8 已由 §50 取代:七關流程——L1-L3 → L4 果凍王 → L5-L6 → L7 暗月蝠王):Title → Stage 1-3 側向卷軸(擊殺配額達成 → 星星門開啟 → 走入過關)→ Stage 4 魔王戰(入場動畫 → Boss 戰,期間補生可吸小怪供彈藥)→ 勝利星爆 / 敗北。死亡處理:Stage 1-3 重試當前關;魔王關進敗北結算。關卡資料驅動細節見 §15。(v6 已由 §39 取代直達下一關的轉場卡:過關寫入存檔後自動進世界地圖,自地圖節點進下一關或重玩。) - -## 4. 操作(行動裝置優先) - -- 左半屏:浮動搖桿(觸點即中心、半徑 60px、死區 12px;水平移動 + 下向偵測供下衝擊,規格見 §21)。 -- 右側:A/B 圖形圓鍵(斜排布局 v5 已由 §34 取代:B 移右側偏上食指區、位置可自訂)——A 跳躍(空中連按=拍翅漂浮,最多 3 次,落地重置);B 吸/射(無彈藥=按住吸入;有彈藥=點按發射,長按仍可吸)。 -- 鍵盤(桌機備援):←→ / Z 跳 / X 吸射。 -- 全域:`touch-action: none`、禁雙擊縮放、首次觸控解鎖 AudioContext。 - -## 5. 角色設定(全部原創) - -| 角色 | 名稱 | 外型 | 行為 | 數值 | -| ---- | -------------- | -------------------------------------- | ------------------ | -------------------------------------- | -| 主角 | 噗噗 Puffpo | 薄荷奶油色圓球、頭頂星星呆毛、桃色腮紅 | 移動/跳/漂浮/吸/射 | HP 5、受擊無敵 1.5s | -| 小怪 | 果凍丁 Jelly | 草莓粉果凍方塊、瞇瞇眼 | 定期彈跳朝玩家 | HP 1、觸碰傷害 1、可吸 | -| 小怪 | 飄飄 Floaty | 薰衣草紫圓鳥、小翅膀 | 正弦飄移 | HP 1、觸碰傷害 1、可吸 | -| 小怪 | 刺刺瓜 Spiky | 萊姆綠刺球、壞笑 | 地面滾動衝刺 | HP 1、觸碰傷害 1、不可吸(吸會被彈開) | -| 魔王 | 果凍王 Jellord | 巨大葡萄紫果凍、金皇冠、跋扈眉 | 見 §6 | HP 60、身體傷害 1 | - -## 6. 魔王 AI(有限狀態機,pure TS 可測) - -(v21 已由 §111 取代:P1/P2 固定循環改 `JELLORD_MOVES` 加權表選招,招池與 telegraph 數值不變。) - -- P1(HP > 50%)循環:`idle(1.2s) → jellyRain(5 顆拋物線彈) → idle → slam(跳起落地雙向地面震波) → idle → …` -- P2(HP ≤ 50%):變紅憤怒、速度 ×1.3,新增 `dash`(白閃三拍前搖 0.6s → 水平衝刺,牆邊回彈; - #809 前搖 0.3s→0.6s 對齊 ≥600ms 衝撞可讀性紅線);jellyRain 升為 7 顆。 -- 前室反制提示(#809):一次性浮字「被逼到角落?連按跳鍵拍翅可飛越魔王」——拍翅淨高 - 211px > 全王本體需求(跳越可行性矩陣 §108),貼牆「必中」體感為知識缺口非物理問題; - 入 arena 即記憶(localStorage)不重複打擾。 -- 受擊:白閃 + 抖動 + 傷害數字;每損 10 HP 補生小怪。 -- 死亡:慢動作 0.5s → 星爆粒子 → 勝利。 - -## 7. 戰鬥數值 - -- 玩家:移速 220px/s、跳躍初速 -420、漂浮升力 -260、重力 900。 -- 吸入:長按 ≥150ms 啟動、錐形範圍 140px、拉力漸增;吞下 +1 彈藥(上限 5,v19 §109)。 -- 星彈:傷害 5、速度 520、穿透 1 隻小怪、命中魔王消失。 -- 邏輯畫布:854×480(橫式,Scale.FIT;v4 改 NO_CENTER 由旋轉殼定位,見 §28);解析度採 Scale.FIT 自適應,不做 DPR cap(欄位已於修復包 B 移除)。 - -## 8. Juice 清單(品質關鍵,全數必做) - -hit-stop 60ms、震屏 4px、受擊白閃、squash & stretch(跳躍/落地/吸入鼓脹)、吸入漩渦粒子、星彈拖尾、傷害數字浮動、魔王死亡星爆、HP 心心受擊跳動、按鈕按壓回饋、入場/退場 tween。 - -## 9. 音效(zzfx,零音檔資產) - -jump、flap、inhale(迴圈)、swallow、shoot、hit、hurt、metal(皇冠落地)、pop(puffy 爆裂)、chomp(咬咬花咬合)、boss-roar、boss-slam、win、lose;BGM 用 zzfx 合成短循環(手刻序列混音,零依賴)。首次觸控後 resume AudioContext(iOS 必須)。靜音偏好存 localStorage(sp-muted)(v19 已由 §118.1 取代:收斂為 `sp-settings.audioMuted`,`sp-muted` 僅作一次性 migration 來源,落盤後刪除)。 - -## 10. 美術資產規格(codex imagegen 專用;除此之外嚴禁動用 codex) - -統一風格關鍵詞(每次生成必附): -`kawaii chibi jelly creature, soft pastel palette, thick rounded soft outline, glossy jelly highlight, flat cel shading, clean high-quality mobile game sprite, centered, full body` - -透明需求資產以 flat #00ff00 背景生成後去背。生成尺寸 2048×2048(bg 為 1024×1536),交付至 `apps/starpuff/src/assets/sprites/`。表列 `.png` 為生成源檔名;實際入庫交付為同名 `.webp`(q82 壓縮,透明保留)。 - -| 檔名 | 內容 | 備註 | -| ----------------- | ------------------------------------------- | ---------------------------------------------------- | -| hero-idle.png | 噗噗待機:圓潤微笑、星星呆毛 | 薄荷奶油 #BFF3E0、腮紅 #FFB7A0 | -| hero-inhale.png | 噗噗張大嘴吸入 | 嘴佔臉 40% | -| hero-puffed.png | 噗噗雙頰鼓滿 | 含住星星微光 | -| hero-hurt.png | 噗噗受傷 >\_< | 淚珠 | -| minion-jelly.png | 果凍丁 | 草莓粉 #FFB3C7 | -| minion-floaty.png | 飄飄鳥 | 薰衣草 #CBB7F0、小翅 | -| minion-spiky.png | 刺刺瓜 | 萊姆 #D9F29B、短刺 | -| boss-idle.png | 果凍王+金皇冠 | 葡萄紫 #9B7BD8、跋扈眉 | -| boss-enraged.png | 果凍王憤怒紅化 | 紅暈 #FF6B6B、怒目 | -| fx-star.png | 五角星彈+光暈 | 金黃 #FFD966 | -| bg-arena.png | 直向粉彩天空果凍島戰場(1024×1536,不去背) | 底部 1/3 乾淨平台區、上 2/3 雲朵漸層 #FDEFF6→#D6ECFF | - -走路/跳躍動畫一律用程式 tween(squash/stretch/bob/rotate)實現,不生成逐幀序列。PWA icon 由 hero-idle 裁切導出。 - -## 11. 技術架構 - -- Vanilla TypeScript + Vite + Phaser(最新穩定版)+ vite-plugin-pwa + zzfx。**不用 React**(遊戲 canvas 無需,KISS)。 -- Arcade Physics、object pool(彈幕/粒子)、`base: '/starpuff/'`。 -- 目錄契約(並行開發邊界,各 stream 只改自己的檔): - -``` -src/game/core/ config.ts events.ts types.ts ← scaffold 定義,凍結 -src/game/scenes/ Boot/Title/Game/Result ← 整合 stream 專屬 -src/game/systems/ player controls enemies waves boss fx hud -src/game/audio/ sfx.ts bgm.ts -src/game/logic/ combat.ts bossFsm.ts levels.ts ← pure TS,vitest 對象 -``` - -- 事件契約(`events.ts`,跨系統唯一溝通管道;v3 增列 `player:healed` 與 `skill:*` 技能結算事件;v4 增列 `boss:quake` P3 全場震落事件): - `player:damaged, player:healed, player:died, ammo:changed, enemy:inhaled, enemy:killed, star:fired, skill:starstorm, skill:slam-landed, boss:spawned, boss:damaged, boss:phase, boss:quake, boss:defeated, level:changed, level:quota, level:gate-opened, game:won, game:lost` - -## 12. 品質門檻 - -- 效能:60fps(中階機)、JS gzip < 1.6MB、首屏 < 3s(4G)。 -- PWA:可安裝、離線可玩、manifest 完整、無 console error。 -- 測試:logic/ 模組 vitest 全綠;playwright 手機視窗 smoke(載入→開始→canvas 運行→無錯誤)。 -- 每 commit 過 repo hooks(lint-staged、typecheck、format、commitlint)。 - -## 13. 安全與合規 - -純前端、無資料收集、無 API、無 secrets;原創角色(§5);依賴僅 phaser/zzfx(MIT);CSP 相容(無 eval)。 - -## 14. 效能與範圍紀律 - -能 10 行不寫 50 行;能用套件不手刻;嚴禁提前抽象與過度工程;註解預設不寫,僅必要處簡短正式繁體中文。 - ---- - -# v2 擴充:層層關卡(PM 親撰) - -## 15. 關卡系統(levels.ts 為 SSOT,pure TS 可測) - -流程改為:Title → Stage 1 → 2 → 3 → 4(魔王)→ Result。死亡重試當前關;通關進下一關(轉場卡全屏 1.2s:關卡編號+名稱+緩動)(v6 已由 §39 取代:通關 → 世界地圖揭霧 → 自節點進下一關,轉場卡廢除)。 - -下表世界寬為 v2 直向值,v3 已由 §21 橫式世界尺寸取代(S1 2700 / S2 3100 / S3 3500 / S4 854 單屏): - -| # | 關卡 | 場景(bg key) | 世界寬 | 擊殺配額 | 生成間隔 | 怪物組合 | 難度設計 | -| --- | -------- | -------------- | ------------------- | -------- | ----------------------- | -------------------------------- | -------------------------------------------- | -| 1 | 果凍草原 | bg-meadow | 1680px | 6 | 2600ms | jelly 60%、floaty 40% | 教學關:平台低差、無地形威脅、幾乎不死 | -| 2 | 雲朵高台 | bg-heights | 1920px | 9 | 1800ms | floaty 40%、spiky 35%、puffy 25% | 垂直平台跳躍、spiky 巡邏走道、puffy 空中封位 | -| 3 | 星空回廊 | bg-arena | 2160px | 10 | 1300ms | 五種混編、可吸怪佔比 50% | 密度高壓、chompy 卡口、彈藥管理壓力 | -| 4 | 魔王城 | bg-throne | 480px(單屏 arena) | — | 補生 3500ms(僅可吸怪) | Jellord + jelly/floaty 補給 | §6 + §17 強化演出 | - -- 走動:關卡 1-3 為側向卷軸(v3 定案:`camera.startFollow(player, false, 1, 1)` 剛性跟隨 + `roundPixels: false` + `setBounds(0,0,worldW,480)`;world 物理邊界同步;緣由見 §25 抖動修復定案)。 -- 通關條件:擊殺配額達成後右端出現「星星門」(fx-star 放大 + 光暈脈動 + 浮動 tween,graphics 組合,不新增美術),走入即過關。 -- 關卡資料契約(levels.ts):`{ id, nameZh, bgKey, worldWidth, killQuota, spawnIntervalMs, maxOnScreen, safeZoneTailPx, enemyMix: {kind,weight}[], platforms: {x,y,w}[] }`——GameScene 依資料驅動,禁止每關寫死邏輯分支。 -- 尾端 release:每關末 `safeZoneTailPx: 480` 禁 spawn(星星門前喘息區,鋸齒 tension-release)。`maxOnScreen`:S1 3、S2 4、S3 5。 -- HUD 增列:左上 `STAGE N 關卡名` + 配額 `⭐ n/quota`。 - -### 15.1 觸控寬容度硬規則(調研回寫,全關卡生效) - -- Coyote time 150ms、jump buffer 160ms(離台仍可跳、提前按跳落地即跳)。 -- 玩家 hurtbox = 視覺 75% 寬 × 80% 高;敵人 contact hitbox = 視覺 90%(spiky 85%)。 -- 受擊 i-frame 1.5s + 擊退期控制鎖 250ms;死亡重開載入 ≤400ms。 - -## 16. 新怪物 ×2(多樣性;全原創) - -| 怪物 | 名稱 | 外型 | 行為 | 數值 | -| ------ | ------ | -------------------------- | ------------------------------------------------------------------- | -------------------------------------------------- | -| 氣球魨 | Puffy | 珊瑚粉圓河豚、短刺、驚訝眼 | 高空緩慢下飄,落地或受擊「啵」爆成 4 向短刺彈(220px/s、0.6s 消散) | HP 1、可吸(吸入得彈藥且不爆)、爆刺傷害 1 | -| 咬咬花 | Chompy | 鵝黃果凍花、花瓣嘴、瞇眼 | 定點紮根,玩家進 120px 前搖 0.4s 後咬合(嘴部 hitbox 0.3s) | HP 2(吃兩發星彈)、不可吸(紮根彈開)、咬合傷害 1 | - -行為實作沿用 enemies.ts 既有模式(pool + kind 分支 + wobble tween);EnemyKind 契約擴充 'puffy' | 'chompy'。 - -## 17. 魔王關演出強化(動畫品質關鍵) - -- 入場運鏡:黑幕淡入 → 相機從王座緩推近(pan+zoom 1.2s)→ Jellord 三段彈跳落座(每段落地震屏+塵埃圈)→ 吼叫(畫面漣漪 + boss-roar)→ 戰鬥開始。 -- P2 轉換震撼:時停 0.4s → 全屏紫色 vignette 脈動常駐 → 果凍地震(相機持續微震 2s)→ 皇冠迸出星火粒子 → 背景色調轉暗(tint 疊層)。 -- 擊破多段演出:時緩 0.3× → 連環小爆 ×6(隨機體表位置、間隔 150ms)→ 全屏白閃 → 大星爆 → 皇冠拋物線落地彈兩下(金屬音)→ 勝利。 -- 粒子預算:單一發射器 maxAliveParticles ≤120(勝利彩帶峰值例外),單次 burst ≤40;以實機 60fps 實測為準(QA 實測 avg 100fps);vignette 用單一半透明 rect 疊層。 - -## 18. 動畫流暢度打磨清單(全實體) - -走路彈跳(玩家移動時 y 微幅 bob + 輕微傾斜)、落地塵埃圈(著地速度 >300 觸發)、所有敵人生成 popIn(scale 0→1 back.out)、死亡 squash 消失、星星門吸入過關演出(玩家縮小旋轉飛入)、轉場卡緩動(slide+fade)、鏡頭剛性跟隨 lerp(1,1)(v3 定案;lerp×roundPixels 逐幀往返跳動的根因修復見 §25 抖動修復定案)。 - -## 19. v2 美術資產增補(codex 專用;生成尺寸同 §10 規範) - -| 檔名 | 內容 | 備註 | -| ----------------- | ------------------------------------------------------------------------ | ---------------------------------- | -| bg-meadow.png | 直向果凍草原:粉綠草丘、果凍花、奶油雲(1024×1536 不透明) | 底 1/3 乾淨地面 | -| bg-heights.png | 直向雲朵高台:高空粉藍雲海、遠景漂浮果凍島(1024×1536 不透明) | 底 1/3 乾淨、中段留平台視覺空間 | -| bg-throne.png | 直向魔王城王座廳:葡萄紫果凍城、金冠紋飾、戲劇但可愛(1024×1536 不透明) | 底 1/3 乾淨、頂部王座剪影 | -| minion-puffy.png | 氣球魨(2048 透明) | 珊瑚粉 #FFA8A0、短圓刺、驚訝圓眼 | -| minion-chompy.png | 咬咬花(2048 透明) | 鵝黃 #F5E6A8、花瓣嘴微張、莖葉底座 | - -## 20. 技能系統:吞噬賦星(v2.1,PM 親撰) - -吞下的怪決定星彈屬性(最後吞下者覆蓋既有彈藥屬性),表驅動實作(config 一張表,禁止散落分支)(v6 已由 §40 擴充為五系:shelly 殼盾星、zappy 雷鏈星,取代 v4 的標準星/疾風星代位): - -| 吞下 | 星彈屬性 | 效果 | 視覺 | -| ------ | -------- | ----------------------------------- | ------------------------------- | -| jelly | 標準星 | 傷害 5、速度 520、穿透 1 | 金黃 #FFD966 | -| floaty | 疾風星 | 傷害 5、速度 650、穿透 2 | 藍紫 tint #A78BFA、拖尾加長 | -| puffy | 爆裂星 | 命中爆 60px AoE(主目標 5、波及 2) | 珊瑚 tint #FF8A80、命中小爆粒子 | - -- HUD 彈藥星星依屬性上色;發射音效 pitch 依屬性微調(標準 1.0/疾風 1.15/爆裂 0.85)。 -- 實作契約:`swallow(kind)` 記錄 flavor → `fireStar(flavor)` → `STAR_FLAVORS` 常數表(core/config.ts)。 -- KISS 底線:不做技能樹、不做冷卻、不做 UI 選單——吞什麼射什麼,一眼可懂。 - -## 21. v3 橫式轉向(PM 親撰) - -- 邏輯畫布 854×480(橫式),Scale.FIT + CENTER_BOTH;manifest orientation 改 landscape(v4 已由 §28 免轉向旋轉殼取代:manifest 不鎖 orientation);直向持機時顯示「請轉橫」遮罩(v4 已由 §28 免轉向旋轉殼取代:遮罩廢除)。 -- 世界尺寸:高 480;寬放大至 S1 2700 / S2 3100 / S3 3500(視野變寬 1.78 倍,維持等效走動時長);平台改雙層以內(天花板變低),高度差以跳躍 -420 可達為準。 -- HUD 重排:頂列橫排——HP 心心左上、STAGE 標示中上、配額右上;Boss 條頂中置。全部 HUD 圖示改 graphics 繪製(星形/心形程序化),全遊戲禁用 emoji 與文字字元鍵帽。 -- 虛擬手柄(參考實體手柄配置):左側浮動搖桿(觸點即中心、半徑 60px、死區 12px、水平為主 + 下向偵測供下衝擊);右側 A(跳,右下)/ B(吸/射,A 左上 45 度)雙鍵 64px+ 斜排、間距 16px+(v5 已由 §34 取代:B 移右側偏上食指區、支援拖曳自訂布局);橫持 iPhone safe-area 側邊 inset 必須套用。按鍵一律 canvas/CSS 繪製圖形(無文字節點)。 - -## 22. iOS 觸控直通(研究回寫後定稿) - -- 已知基線:控制層與 canvas 套 `-webkit-touch-callout: none`、`-webkit-user-select: none`、`user-select: none`、`touch-action: none`、`-webkit-tap-highlight-color: transparent`;pointerdown/contextmenu preventDefault;按鍵不含可選取文字(無障礙走 aria-label)。 -- 長按放大鏡(iOS 17+ text loupe)根除:按鍵去文字化 + callout/select 全關 + 必要時 touchstart passive:false preventDefault——以調研結論為準補齊。 -- 研究項:Safari gesturestart 縮放攔截、standalone PWA 與瀏覽器內差異、audio unlock 於橫式的相容性。 - -## 23. 技能組合 v3:吞噬連鎖(表驅動,logic/skills.ts) - -- 三屬性沿用 §20;新增連鎖規則: - - 同種連吞 ×2:該槽升級為強化星(傷害 ×1.6、尺寸 ×1.4、pitch -15%、金邊 tint)。 - - 彈匣全滿長按 B 0.8s:星暴大招——清場全部小怪 + 魔王 12 傷,震屏 + 白閃 + 星雨粒子,清空彈匣。(v9.1 已由 §64.2 補訂:發動附 5s 無敵窗,與受擊 i-frame 取較大值不疊加。)(v19 已由 §109 取代:滿匣自動結晶+SP 鍵手動引爆,B 長按星暴路徑退場。) - - 空中搖桿下 + B:下衝擊(v7 已由 §44 取代:改為空中搖桿下+跳躍鍵,B 鍵回歸純吸/射語意)。 -- 彈匣槽各自帶 flavor 與強化態,後進先出發射;HUD 槽位顯示屬性色 + 強化金邊。 - -## 24. 關卡彩蛋(data-driven:levels.ts easterEggs[]) - -| 關 | 觸發 | 獎勵 | 演出 | -| --- | --------------------------- | ----------------------------------------------- | ------------------------------- | -| 1 | 開局反向走到世界最左緣 | 彩虹果凍 +1 HP | 金光 popIn + 專屬 jingle + 浮字 | -| 2 | 最高雲朵平台連續站上 3 次 | 星星雨(瞬間滿彈匣;v19 §109 無蓄能星時即結晶) | 星雨粒子 + jingle | -| 3 | 依序連吞 jelly→floaty→puffy | 金星彈一發(傷害 20) | 金彈入匣特寫 + jingle | -| 4 | 開場 5 秒內命中皇冠 | +1 HP | 皇冠火花 + jingle | - -- 觸發器型別化:`'reach-x' | 'stand-count' | 'eat-sequence' | 'crown-early-hit'`;每關至多觸發一次;純邏輯可測。 - -## 25. 背景連續感與視覺升級 - -- 每關背景改「橫向無縫平鋪」新資產(§27),tileSprite 雙層視差:遠景 scrollFactor 0.25、近景 0.6;接縫若可見改鏡像平鋪。 -- 共用漂浮雲層(透明平鋪帶)恆速漂移;每關主題 ambience 粒子(草原花瓣/高台雲絮/回廊星塵/王座金塵,密度低於 8 顆同屏)。 -- 色彩分級:每關極輕 tint overlay(alpha 0.06)統一色調。 -- 動作抖動修復定案(US-022 調查結論):根因為 camera lerp 次像素捲動 × roundPixels 量化的逐幀往返跳動——修法為剛性跟隨 `lerp(1,1)` + `roundPixels: false`(非 pixel-art 美術);walk bob 改 PRE/POST_UPDATE 視覺偏移掛鉤不污染物理;全實體動作平滑化(tween ease 統一 Sine 系)。 - -## 26. 反卡死保證(softlock 防護,全部 MUST) - -- Spawner 保證律:玩家彈藥 0 且場上無可吸怪時,下一隻生成強制可吸(覆蓋權重);boss 期同律且立即補生(不等間隔)。 -- 星星門必達:配額達成即於可達地面生成,overlap 高度涵蓋跳躍弧線。 -- 場景無坑洞設計維持(無墜落死);世界邊界實牆。 -- visibilitychange:切背景暫停物理與計時(v5 已由 §35 取代:回前景停在暫停選單、點繼續才接續,不自動恢復)。 -- 深度探索 QA 劇本:邊緣紮營 5 分鐘、只殺不可吸怪、彈藥歸零僵持、暫停/恢復循環、快速連死——全數不得卡關。 - -## 27. v3 美術資產(codex 專用;橫向平鋪) - -| 檔名 | 內容 | 規格 | -| ---------------- | ------------ | --------------------------------------- | -| bg-meadow-l.png | 果凍草原橫景 | 1536×512、水平無縫平鋪、底 1/4 乾淨地帶 | -| bg-heights-l.png | 雲朵高台橫景 | 同上、中段留平台空間 | -| bg-arena-l.png | 星空回廊橫景 | 同上、星塵粉紫調 | -| bg-throne-l.png | 魔王城橫景 | 同上、紫金王座廳 | -| fx-clouds.png | 共用漂浮雲層 | 1024×256、透明、水平無縫平鋪 | - -## 28. v4 免轉向橫式與響應寬幅(PM 親撰) - -- 免轉向:偵測 portrait viewport 時,以 CSS 旋轉容器方案將整個遊戲容器(canvas + DOM 控制層)旋轉 90 度呈現橫式——使用者直持手機即玩,不再顯示轉橫遮罩(遮罩廢除)。技術定案依調研回寫(Phaser 4 相容性、pointer 座標映射、safe-area 換軸)。(v14 已由 §87 取代預設旋轉方向:預設 ccw(rotate -90deg、鏡頭朝右),cw 舊方向降為可切換偏好。) -- 響應寬幅:邏輯高固定 480,寬依裝置比例擴展(下限 854、上限 1200);Scale 模式依調研定案(EXPAND/RESIZE 擇一)。HUD 錨定鏡頭邊緣自適應;世界生成邊距、星星門偵測、boss 單屏佈局以動態視寬計算,禁止硬編 854。 -- 驗收基準機型:390×844(iPhone 13 直持)、430×932(Pro Max 直持)、844×390(橫持)三態皆可玩。 - -## 29. v4 平台玩法元素包(調研回寫後定案數值) - -Arcade Physics 相容優先(斜坡不做——Arcade 無原生支援,違反 KISS): - -| 元素 | 行為 | 關卡配置 | -| -------- | -------------------------------------------------------------------------------------------- | ---------------- | -| 單向平台 | 下方可穿上方可站(checkCollision.down only);搖桿下+跳可下落穿透(§71.1:地形粉紅平台同權) | S1 起每關 2-4 個 | -| 移動平台 | 水平/垂直往返(tween 驅動 + 玩家載運) | S2 起 1-2 個 | -| 彈簧墊 | 踩上彈跳 -640(超級跳)、squash 動畫 + 專屬音 | S2 起 1-2 個 | -| 可破壞磚 | 星彈或下衝擊破壞、碎裂粒子、內藏獎勵(彈藥/HP 小回復) | S3 起 2-3 個 | - -- 全部元素 data-driven 進 levels.ts platforms/elements 資料;純邏輯可測。 -- 反卡死約束:元素佈局不得製造不可達區域;可破壞磚不得阻擋唯一路徑(破壞前繞行可過)。 - -## 30. v4 內容擴充:新技能、新怪物、魔王 P3(PM 親撰) - -- 新技能「空中疾衝 Air Dash」(v7 已於 §44 整體移除:雙擊 A 誤觸率高且與拍翅語意衝突,輸入預算讓給下衝擊改制):空中雙擊 A 朝面向水平疾衝 180px、0.18s、無敵幀、CD 2s。 -- 新怪物 ×2(全原創): - - 殼殼 Shelly:藍綠硬殼龜果凍。第一發星彈 → 縮殼旋轉衝刺 1.5s(期間無敵、傷害 1)→ 停下暈眩 1.6s(可吸/可擊殺)。HP 2 段。不可直接吸(縮殼後暈眩時可吸)。 - #811 吞食體感修復:暈眩窗 1.0s→1.6s、暈眩期吸入引力 ×1.5+判定半徑 +20%+貼身 - ≤60px 錐形豁免(停位貼腳死角);暈眩視覺=頭頂眩星公轉+殼體閃白脈動(與可吸窗 - 同生共滅);L2 首遇浮字教學。工具實測正確時機吞食 37%→73%(門檻 ≥60%)、 - 衝刺期 0% 不變(技巧性保留)。 - - 雷雷 Zappy:薰衣草黃電氣水母。緩慢懸浮追蹤,每 3s 放電環(半徑 70px、傷害 1、前搖 0.5s 閃爍預警)。可吸(吸入得疾風星)(v6 已由 §40 取代:吸入得雷鏈星)。HP 1。 -- 魔王 P3(HP ≤ 25%):狂暴皇冠——rain 改追蹤彈 ×5(緩速跟蹤 2s 後直線)、slam 觸發全場單向平台震落效果(站立玩家強制彈起)、體色金紫閃爍;P3 進場演出:皇冠射出星環衝擊波 + 時停 0.3s。 -- 關卡怪物組合更新:S2 加 shelly 15%、S3 加 zappy 15%(權重重配,可吸佔比維持 ≥50%)。 - -## 31. v4 美術資產(codex 專用) - -| 檔名 | 內容 | 規格 | -| ----------------- | ------------------------------------------------ | ------------- | -| minion-shelly.png | 殼殼:藍綠 #7FD8C8 硬殼龜果凍、圓殼紋、憨笑 | 2048 透明 | -| minion-zappy.png | 雷雷:薰衣草黃 #E8D88A 電氣水母、火花觸鬚、瞇眼 | 2048 透明 | -| props-meadow.png | 草原道具條:果凍蘑菇/花叢/小石/木牌 4 件橫排等距 | 2048×512 透明 | -| props-heights.png | 高台道具條:氣球/雲絮/風向旗/星星燈 4 件 | 2048×512 透明 | -| props-arena.png | 回廊道具條:水晶簇/星柱/光苔/浮石 4 件 | 2048×512 透明 | -| props-throne.png | 王座道具條:旗幟/燭台/王冠雕像/寶箱 4 件 | 2048×512 透明 | - -道具條以固定 4 等分切割(512×512/件),佈景密度規範見 §32。表列 `.png` 為生成源檔名(§10 慣例);實際入庫交付為切割後之 `prop-{meadow,heights,arena,throne}-1..4.webp` 與 `minion-*.webp`(q82、透明保留),資產鍵與檔名對齊 `core/assets.ts` 註冊表。 - -## 32. 場景裝飾密度規範 - -- 每關地面帶每 400-600px 佈置 1-2 件主題道具(levels.ts decor 資料驅動、隨機微縮放 0.9-1.1 與 y 抖動);深度在玩家後、平台前。 -- 道具純裝飾無碰撞(KISS);可破壞磚除外(§29)。 -- 同屏道具上限 6 件防雜訊;與 ambience 粒子總量合併預算(同屏繪製物 ≤14)。 - -## 33. v5 iOS PWA UX 調研回寫(2026-07-15 定稿) - -調研結論與對應實作(出處:MDN `BaseAudioContext.state`、MDN CSS env()、Polypane safe-area 指南、iOS PWA 安全區實測筆記 gist/fozzedout、Steven Hoober thumb-zone 研究、Smashing Magazine 拇指觸控統計): - -| # | 結論 | 實作 | -| --- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -| 1 | `viewport-fit=cover` 缺失時 `env(safe-area-inset-*)` 全為 0,Safari 以黑邊 letterbox | 既有 meta 已含 cover(複查通過,未重工) | -| 2 | standalone 邊到邊需 `apple-mobile-web-app-status-bar-style: black-translucent` | v5 補上該 meta | -| 3 | 橫持瀏海機頂緣存在 phantom 觸控死區(inset 回報 0 仍吃事件),建議頂緣 ≥20px 緩衝 | `#keys-layer` top 取 `max(20px, env(top))`;joy-zone 既有 20px 緩衝維持 | -| 4 | `env()` 值冷啟動/轉向可能為 0 或 stale,須設 `max(Npx, env(...))` 地板 | keys-layer 四向皆 `max()` 地板(20/12px) | -| 5 | iOS standalone 冷啟動 `100dvh` 不可靠 | 維持 v4 `100vh` 決策(複查,未重工) | -| 6 | iOS 切 app/背景後 AudioContext 進非標準 `interrupted` 態,`resume()` 須於手勢堆疊內呼叫 | sfx.ts `resumeAudio()`(`state !== 'running'` 即 resume)+全域 pointerdown 復聲保險+暫停選單「繼續」手勢內恢復 | -| 7 | 觸控目標 ≥44pt(Apple HIG);拇指自然熱區在底部/下側緣,食指可達區在裝置上緣(雙手橫持) | 全按鍵 ≥44px(A 76 / B 72 / 暫停與靜音 hit 48 / 選單鈕 ≥52);布局見 §34 | -| 8 | 長按 loupe/選字/callout/雙擊縮放攔截 | v3/v4 已滅(touch-callout/user-select/touch-action/gesturestart 全鏈,複查通過,未重工) | -| 9 | `position: fixed` 根元素於 iOS 26 鍵盤場景會裁切 app shell | 本遊戲無文字輸入,維持 fixed 殼;記錄為已知邊界 | - -## 34. v5 控制布局重設計與按鈕自訂 - -- 人體工學定案(§33 條目 7):雙手橫持時拇指錨於下側角、食指自然落在裝置上緣——A 跳躍維持右下(拇指連打),B 吸/射移至右側偏上(食指按壓;與 A 垂直遠離杜絕誤觸);方向搖桿維持左半屏。 -- 布局 SSOT:`core/layout.ts`——按鍵中心以 keys-layer 安全區內比例(cx/cy 0-1)表示,直橫持共用;`DEFAULT_LAYOUT`:A (0.92, 0.78)、B (0.92, 0.34)。(v16 已由 §95 取代「預設」的直持適用性:預設依殼旋轉態分流 `defaultLayoutFor`,直持採右下拇指帶錨點;自訂布局仍直橫持共用。) -- `#keys-layer`:安全區內鋪滿的定位容器(四向 `max()` 地板+portrait 換軸表),按鍵以 `left/top %` + `translate(-50%,-50%)` 定位。 -- 按鈕自訂(KISS:拖曳+儲存+重置,不做進階編輯器)(v19 已由 §118.1/§118.2 取代入口與儲存位置:入口自 Title 直鈕改為設定頁轉入,布局改存 `sp-settings.keyLayout`,`sp-key-layout` 僅作 migration 來源):Title「按鈕配置」→ `systems/keyConfig.ts` DOM 覆層——直接拖曳真實 A/B 鍵即時預覽,「儲存並返回」寫入 localStorage `sp-key-layout`(schema `{version:1, a:{cx,cy}, b:{cx,cy}}`;版本不符/損毀回退預設),「恢復預設」一鍵還原。拖曳座標經 `pointerToLocal` 換軸,夾限 `KEY_CLAMP` 保證按鍵完整在畫面內。(v14 已由 §88/§89 取代操作列結構與 schema:schema 升 v2 增全域縮放、操作列直欄化並增持向切換與縮放列。) - -## 35. v5 暫停系統與離頁自動暫停 - -- HUD 暫停鍵:頂列右上(靜音鈕左側 48px,top-right 硬熱區遠離戰鬥區),雙豎條圖形紋理、48px 觸控目標;配額顯示左移讓位。桌機備援:ESC / P。 -- 暫停選單(`systems/pause.ts`,DOM 覆層——旋轉殼下 hit-test 天然正確、覆蓋虛擬鍵防誤觸):繼續/重新開始/回主選單。 -- 全停語義:`scene.pause(Game)`(物理/計時/tween/輸入輪詢全停)+ `AudioContext.suspend()`(BGM 與 SFX 全停)。 -- 重新開始=重置當前關卡全狀態(血量/彈藥/擊殺數/計時/實體經 scene.restart 重生),保留已完成關卡累計用時與本輪死亡數。 -- 離頁自動暫停:`visibilitychange`(hidden)與 `pagehide`(同走 hidden 檢查防雙觸發)即開暫停選單;回前景停在選單、玩家點「繼續」才接續(取代 §26 的自動恢復,杜絕回前景瞬間被偷襲)。音訊恢復一律走手勢堆疊內 `resume()`(§33 條目 6),刻意暫停期間全域復聲保險不生效。 -- 與 PWA 週期更新 hooks(main.ts `import './pwa'`)共存:兩者互不依賴,同檔並列。已知邊界:回前景恰逢新版部署時,autoUpdate 完成後的 reload 會重新載入頁面蓋過暫停選單,屬可接受權衡,不特別攔截。(v19 已由 §118.4 取代此已知邊界:更新套用改經殼層安靜閘,遊戲進行中與暫停選單期間絕不 reload。) - -## 36. v5 開場主選單與圖鑑/技能介紹 - -- Title 開場動畫:主標縮放彈出(Back.easeOut)、副標延遲淡入、主角自天而降 Bounce 落定+光暈淡入;維持既有美術風格與 zzfx 音效(選單按壓 pop)。 -- 主選單:開始遊戲(主鈕)+次選單列 圖鑑/技能介紹/按鈕配置(DOM 鈕承接命中,data-menu 標識)。(v6 §39 增「世界地圖」;v19 已由 §118.2 取代次選單構成:世界地圖/圖鑑/技能介紹/設定四鈕,按鈕配置移入設定頁轉入口;桌機另增常駐「操作說明」,見 §87.4。) -- 圖鑑/技能介紹(`CodexScene` 單場景雙分頁,資料 SSOT `core/codex.ts`,立繪一律取既有 sprite 資產、禁止新美術): - - 圖鑑分頁:全 8 角色(jelly/floaty/spiky/puffy/chompy/shelly/zappy/boss)4×2 網格——立繪+名稱+行為一句話+可吸/不可吸圓點標記。(v7 擴 5×2 十格;v8 擴 7×2 十四格;v9 已由 §59 取代:8×2 十六格。) - - 技能分頁:吸入/星彈三系(含來源怪物對應)(v6 已由 §40 擴充為五系+殼盾/雷鏈條目;v7 §44/§46 移除空中疾衝、增混合星彈與七系敘述)/強化星/星暴/下衝擊/漂浮,雙欄列表(名稱+操作+效果)。 - - 分頁切換以 scene.restart 重建(選單輕量無局內狀態);ESC 或返回鈕回 Title。 - -## 37. v5 全元素位置稽核 - -- 稽核腳本:`scripts/capture-audit.mjs`——Title/Game/Boss/Result(+v5 新頁)於 390×844(直握旋轉殼)與 926×428(寬幅橫持)截圖至 `screenshots/starpuff-v5-audit/{before,after}/`。 -- 檢查項:HUD(血條/彈藥/擊殺進度/計時/boss 條)、虛擬鍵、彩蛋提示、教學文字——重疊/出界/safe-area 裁切/離熱區過遠。 -- v5 修正:暫停鍵擠入頂列後配額右錨左移(width-112/126)避免熱區重疊;B 鍵離開 A 鍵斜上緊鄰位,垂直間距 ≥80px。 -- Boss 條頂中置於兩檔寬皆不與左上心心、右上配額/暫停/靜音重疊(854 與 1200 邏輯寬實測)。 -- v6 增列:版本號頁腳(§42)置於 Title 底緣中央(height-6、12px 小字),不與次選單列(height×0.85)重疊。 - ---- - -# v6 擴充:存檔與世界地圖(PM 親撰) - -## 38. 存檔系統(core/save.ts 為 SSOT,pure TS 可測) - -- localStorage `sp-save` schema v1:`{ schemaVersion, highestClearedLevel, levels: { [id]: { cleared, bestTimeMs, eggsFound: string[] } }, lastPlayedAt }`。(v15 已由 §94.2 升 v2 增 `achievements`;v19 已由 §118.3 補訂 checksum 欄與 `sp-save-backup` 備援。) -- 寫入時機:通關(星星門吸入當下即寫,演出中斷不掉進度)、魔王擊破、彩蛋觸發(`trigger` 型別字串為關內唯一 id)。 -- 容錯(沿用 §34 鍵位布局 parse/fallback 模式):schema 版本不符、形狀損毀、隱私模式拋錯——一律回退預設值;`highestClearedLevel` 由關卡條目重新推導,不信任持久化值。 -- `bestTimeMs`=該關單次成功嘗試的最短用時(死亡重試重計);`eggsFound` 去重持久化,跨局累計。 -- 重置進度:世界地圖左下「重置進度」兩步確認(武裝態 3s 未確認自動退回),僅清存檔(偏好不動)。全新存檔不顯示入口。(v19 已由 §118.3 補訂清除範圍:同時清 `sp-save` 與備援 `sp-save-backup`;偏好鍵自 `sp-key-layout`/`sp-muted` 收斂為 `sp-settings`。) -- 偏離備註:任務原文「設定頁加重置進度」——v6 當時本遊戲無設定頁(按鈕配置為鍵位編輯器,語義不符),重置入口落於世界地圖(進度顯示與進度管理同場景,KISS)。(v19 已由 §118.2 取代前提:Title 已有「設定」入口,但重置進度**維持在世界地圖**——進度顯示與進度管理同場景的 KISS 裁決不變。) - -## 39. 迷霧世界地圖(MapScene,data-driven 自 LEVELS) - -- 入口:Title 主選單「世界地圖」+通關後自動進入(取代 §15 轉場卡直達下一關);Result 勝利鈕改「世界地圖」。Title「開始遊戲」=接續當前可挑戰關,全通關後改開地圖。 -- 橫向節點路徑:四節點(各關+魔王節點)沿虛線路徑排布,節點主題色鏡像關卡 bg 主色;禁自由漫遊式大地圖(KISS)。 -- 節點三態(解鎖規則:第 1 關恆開、第 N 關需第 N-1 關通關): - - locked:迷霧雲團遮罩+問號、關名降透明。 - - open(當前可挑戰):節點脈動 tween。 - - cleared:金星徽記+「最佳 N.Ns」;點擊重入該關(關卡選擇=重玩入口,重玩不回退解鎖態)。 -- 揭霧動畫:通關進場帶 `reveal` 節點——霧散(alpha/scale tween)+節點 Back.easeOut 彈出+zzfx reveal sting;視寬重排 restart 不重播。 -- 彩蛋計數:標題下方 `彩蛋 found/total`,total 由 LEVELS easterEggs 推導。 -- 命中一律 DOM 鈕(`data-menu="node-N"`,旋轉殼 hit-test 天然正確);鎖定節點無入口。鍵盤備援:ENTER 進當前挑戰關、ESC 回 Title。 -- 計時語義變更:hub 模型下各關獨立計時入存檔 bestTime;Result 顯示該關用時(v5 四關累計總時語義廢除)。 - -## 40. v6 新技能:殼盾與雷鏈(PM 原創,補防禦與群戰原型) - -沿用 ammo/flavor 表驅動管線(§20/§23),不加新 HUD 元件;星彈三系擴為五系: - -| 吞下 | 星彈屬性 | 效果 | 視覺 | -| ------ | -------- | ----------------------------------------------------------------------- | --------------------------- | -| shelly | 殼盾星 | 直射傷害 5、速度 480、穿透 0;頂槽時長按=舉盾(見下) | 青綠 tint #7FD8C8 | -| zappy | 雷鏈星 | 直射傷害 5、速度 585、穿透 0;命中後跳電至 160px 內最近 2 敵、各 3 電傷 | 電黃 tint #FFE28A、折線閃電 | - -- 殼盾(防禦原型):頂槽殼盾星且未滿匣時,長按 B ≥150ms 舉正面護盾(取代吸入語意;滿匣長按維持星暴優先,肌肉記憶不變)。格擋彈幕/接觸一次:不掉血不擊退、消耗頂槽、觸發反擊星爆(盾前 90px 傷害 3)+短無敵 0.8s,冷卻 4s。正面判定=傷害來源位於面向側(同 x 視為正面)。點按仍為發射。(v19 已由 §109 補訂:長按星暴退場,頂槽殼盾星即成立殼盾情境——滿匣不再讓位。) -- 雷鏈(群戰清場原型):命中主目標後由近至遠跳電(主目標排除、折線閃電演出+burstSmall);命中魔王同樣跳電波及補給小怪(v4 多平台混戰場景受益)。 -- 純邏輯 SSOT:`logic/skills.ts`(`advanceShield`/`resolveShieldBlock`/`isFrontalHit`/`pickChainTargets`)+ `STAR_FLAVORS` chain 欄位(core/config.ts),vitest 全蓋。 -- 事件契約增列:`skill:shield-block`(player 發出,GameScene 結算反擊星爆)。 -- 平衡註記:殼盾 CD 4s 防無限格擋;雷鏈單跳 3 傷不足以秒 chompy(10 HP),保持坦怪定位;§24 連吞彩蛋序列不含新屬性(zappy 現記為 zappy,不再以 floaty 代位計序)。 - -## 41. v6 移動手感打磨(logic/movement.ts,pure TS 可測) - -- 加減速曲線取代瞬時 setVelocity:加速 1400px/s²(約 0.16s 達全速 220)、減速 2000px/s²(約 0.11s 停定)、反向轉身加+減速疊加率(即刻有力);殘速 <8 吸附歸零防微速漂移。 -- 超速殘速(擊退 234 等)先夾回常速帶再逼近,無殘速滑行(v7 §44 移除疾衝後僅餘擊退來源)。 -- 手感事件(邊緣觸發,`detectMoveFx`):起跑塵埃(靜止起步)、急停塵埃(高速鬆手 ≥160)、轉身塵埃+小幅擠壓(高速反向 ≥120,遮蓋翻面瞬間)。塵埃 ≤4 顆/次、tween 自毀,60fps 安全。 -- 既有落地 squash(§18)、走路 bob(§18/§25 PRE/POST_UPDATE 視覺偏移)維持不動;嚴禁重新引入抖動——相機 lerp(1,1)/roundPixels:false 現值不動,改後必跑既有抖動與 portrait e2e(本版已全綠)。 - -## 42. 版本號顯示 - -- SSOT:package.json `version` + short git SHA,經 vite `define __APP_VERSION__` 嵌入(`v0.X.Y+abcdef`;無 git 環境標記 nogit)。 -- 呈現:Title 頁腳小字(12px、violet、alpha 0.75);`window.__sp.version()` production 也掛載供現場排障(其餘 \_\_sp 除錯鉤子維持 DEV/test 限定)。 - -## 43. 每關攻略 PoC 與反卡關驗證 - -(本節怪物權重與招式為 v6 定案值;L2/L3 波次已由 §47 取代——glowy/drilly 入編後之現值以 -`levels.ts` 與 §47/§49 為準,下表保留 v6 歷史攻略脈絡。) - -設計意圖 → 最佳打法 → 無技能保底打法(僅移動+吸入+星彈必可通關,§26 保證律背書)逐關表: - -| 關 | 設計意圖 | 最佳打法 | 無技能保底打法 | 難度曲線(quota/interval/構成) | -| --- | ------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------- | --------------------------------------------------------------------------- | -| 1 | 教學:移動/吸/射閉環,幾乎不死 | 開局反向拿 +1 HP 彩蛋,連吞 jelly×2 強化星速殺 | 站樁吸 jelly/floaty、點按發射,達 6 殺走右入門 | 6 / 2600ms / jelly 60%+floaty 40%(全可吸) | -| 2 | 垂直閱讀:平台跳躍+不可吸威脅初登場 | 吞 shelly(暈眩窗)備殼盾格擋 spiky 滾撞;雲台連站 3 次拿滿匣彩蛋 | 遠距吸 floaty/puffy 補彈、地面點射 spiky/shelly,貼牆等暈眩窗再殺 | 9 / 1800ms / floaty 35%+spiky 30%+puffy 20%+shelly 15%(可吸 ≥55%) | -| 3 | 高壓混編:彈藥管理+群戰清場 | 吞 zappy 得雷鏈星一發清簇;連吞 jelly→floaty→puffy 拿金星彈轟 chompy | 保持距離逐隻吸射;chompy 兩發標準星;彈盡靠 §26 飢荒強制補可吸怪 | 10 / 1300ms / 六種混編(jelly15+floaty10+puffy15+spiky25+chompy20+zappy15) | -| 4 | Boss Rush:彈幕閱讀+補給循環 | 開場 5s 內命中皇冠拿彩蛋;補生小怪吞成滿匣憋星暴(12 傷);P3 靠拍翅躲全場震落 | 吸補生小怪(飢荒立即補生)→ 點射果凍王,僅跳躍閃 slam/dash 即可磨死 | 0(HP 60 擊破制)/ 補生 3500ms / jelly+floaty(全可吸) | - -- 反卡關驗證(e2e 沿用 `__sp` 鉤子):L1「全程僅用基礎動作通關」全流程案;L2/L3 `gotoLevel` 走查——飢荒必補可吸怪斷言+地面路徑(含磚前繞跳)必達星星門;存檔重載、地圖解鎖、關卡重玩、殼盾格擋、雷鏈跳電各自獨立案。 -- 靜態 overlap 必達背擋(§26 擴充,歸因定稿):實測 Phaser 4.2.1 Arcade overlap 存在間歇漏檢(v5 基準亦可重現:彈簧 walk-over 6 次 3 失敗、星星門走入間歇不觸發),修復分兩軌、因果不可混淆—— - - `useTree: false`(main.ts):只服務 sprite vs **Group** 配對(吸入區/星彈/觸碰 vs enemies group 走 `collideSpriteVsGroup` 的動態 RTree broadphase),關閉後改直接枚舉,根治該類漏檢; - - 門/彈簧為 **direct pair**(`collideSpriteVsSprite` 直呼 `separate`、從不查 RTree)——`useTree:false` 對它們無效,真正有效且必要的是幾何掃掠背擋:星星門 `crossedGate`(跨門心/站門心右側/AABB 交疊三重判定,含 spawnGate 時已越門直判)與彈簧 `springSweepHit`(前後幀掃掠 x 區間,補高速穿越),純函式落 `logic/stageModel.ts` 供 vitest 守門,與原 overlap 共用單一觸發出口(transitioning/lockedUntil 閘去重)。**明文禁止未來把掃掠背擋當冗餘刪除。** - -## 44. v7 下衝擊觸發改制與跳躍鍵輸入矩陣(PM 親撰,取代 §23 下+B 觸發) - -- 下衝擊改為「空中搖桿下+跳躍鍵(A)」觸發:B 鍵回歸純吸/射/技能語意,空中吞含 - (puffed,腹中有怪)狀態不影響觸發——矩陣不讀彈匣。數值不變(下墜 700、落地 60px - 衝擊波傷害 2、CD 1.2s、零彈藥消耗、可破磚)。 -- 空中疾衝(§30 Air Dash)整體移除:雙擊 A 與拍翅節奏衝突且誤觸率高;相關輸入、 - 純邏輯、殘影 fx、音效、圖鑑條目與測試全數清除(movement 夾速鏈保留供擊退殘速)。 -- 跳躍鍵輸入矩陣(`logic/skills.ts` `resolveJumpPress`,pure TS 可測): - -(v10.1 已由 §71.1 補訂:「空中」判定收斂為真空中——coyote 窗內視同在地不觸發下砸; -地面主地面下+跳自 §71.2 起帶蹲姿視覺,跳躍裁決不變。) - -| 情境 | 下 | 跳 | 裁決 | -| -------------- | --- | --- | --------------------------------------------------------------------------------- | -| 空中(CD 完) | ✓ | ✓ | 下衝擊(吞含狀態同樣觸發;§71.1:coyote 歸零的真空中才成立) | -| 空中(CD 中) | ✓ | ✓ | 回落一般跳躍鏈(拍翅/buffer),不吞輸入 | -| 空中 | ✗ | ✓ | 拍翅(≤3 次)/ jump buffer | -| 地面站單向平台 | ✓ | ✓ | 下落穿透(§29 `shouldDropThrough` 於 stage 層裁決,覆蓋跳躍脈衝——既有優先序不變) | -| 地面主地面 | ✓ | ✓ | 一般跳躍(無蹲下語意,無衝突) | -| 地面 | ✗ | ✓ | 一般跳躍(coyote/buffer 寬容不變) | - -## 45. v7 走動手感根修與抖動歸因(logic/walkFeel.ts,pure TS 可測) - -- 根因結論(依序排查證據,`sp-jitter-probe` 逐幀取樣): - 1. 物理 velocity 震盪:無(approachVelocity 曲線平滑)。 - 2. render rounding:無(roundPixels:false 現值正確,維持不動)。 - 3. camera 耦合:剛性跟隨段 screen-space 幀間位移恆 0(角色與捲軸完全同步);非跟隨段 - (相機貼世界邊緣)幀間位移呈 0/3.667/7.333px 三值跳動——根因為 Arcade fixedStep - 60Hz 與渲染幀率錯拍(單一渲染幀吞 0/1/2 個物理步)。實測 `fixedStep:false` 可消除 - 該錯拍但在低幀率下重力穿地(8 連測 1-2 次沉地 ~80px、彈簧判定帶失效)——**裁決維持 - fixedStep:true(確定性物理),禁止以 variable step 或全域取整掩蓋**。 - 4. sprite anchor / CSS 旋轉殼:無異常(座標鏈 §28/§34 現值正確)。 - 5. 動畫姿態層:v5「走動不像走動」主因——貼圖平移滑行,僅低頻 bob,無步頻/姿態/音畫拍點。 -- 速度驅動步頻系統(零新素材,程序化): - - 相位累積 ∝ |vx|/moveSpeed,全速步頻 3.2Hz;停走相位歸零凍結。 - - y 軸 bob:|sin| 雙頻小彈跳(峰值 3.2px,速度比縮放),沿用 PRE/POST_UPDATE 視覺 - 偏移通道(不污染物理)。 - - 前傾 lean 0.06rad + 步頻搖擺 sway 0.045rad(面向鏡像);空中依 vy 前後傾 - (上升後仰 -0.1、下墜前傾 +0.14 夾限)。 - - 落腳拍點(|sin| 每半週期回零):池化腳塵 emitter explode ×2+低量 footstep zzfx。 - - idle 呼吸:週期 2.4s、scaleY ±1.8%(squash tween 進行中讓位)。 - - 既有起跳 stretch / 落地 squash / 起跑急停轉身塵埃(§41)維持不動。 - - 主角輪廓對比(三席審查補修):深紫剪影背襯(本體 1.1 倍 FILL tint image,POST_UPDATE - 鏡像貼圖/翻面/縮放/bob),草原亮底對比 1.81:1 提升至實測 10.23:1(≥3:1 門檻); - 不用 Glow filter——SwiftShader/低階 GPU 逐幀模糊採樣致幀率崩跌。 -- 幀證據:`screenshots/starpuff-v6/before/`(v6 基準連拍)與 `screenshots/starpuff-v6/after/` - (v7 步頻連拍+idle 呼吸);e2e 行為斷言走 `__sp.walk()`(rotation 振盪、bob>0、停走歸零)。 - -## 46. v7 雙味混合星彈(config STAR_MIXES 為 SSOT,表驅動) - -- 規則(KISS 裁決,`swallowIntoMagazine` 單一入口): - - 依序吞兩隻**不同**怪且頂槽為素槽(未強化/非金/非混)且配方存在 → 頂槽合成混合星 - (佔 1 槽);HUD 星芯顯示配方色、外圈顯示第二味屬性色(雙色可讀)。 - - 同怪疊加 = 強化單味(§23 不變);無配方對照 → 推新槽(§23 不變)。 - - 取消/覆蓋規則:混合槽為**終態**——不可再強化、不可再混(再吞任何怪推新槽); - 滿匣改吞維持覆蓋頂槽(§20),混合槽在頂被覆蓋即取消;滿匣且頂槽配方成立時優先合成。 - - **anti-softlock 硬規則:混合星永不為破關必需——基礎星彈恆可通關**(配方僅為威力加成, - 關卡配額/魔王皆可純標準星磨死;§26 飢荒保證律不變)。 - - 首遇情境提示(三席審查補修):本 session 首次取得某味/首次合成某配方時,頂部 toast - 一行文案(名稱+一句效果,SSOT `core/codex.ts` FLAVOR_HINTS/MIX_HINTS);seen 集合 - 僅存 session 記憶體,不動 save schema。 -- 混合表(六式;效果自 穿透/追蹤/散射/爆炸/凍結場/連鎖電 擇優組合): - -| 配方 | 成分 | 效果 | tint | pitch | -| ------ | --------------- | ------------------------------------------------------------------------- | ------- | ----- | -| 疾光星 | jelly + floaty | 穿透 3、彈速 780(穿透) | #FFF1C4 | 1.35 | -| 巨爆星 | jelly + puffy | 直傷 6、AoE 110px/4 傷(爆炸) | #FF9D7A | 0.70 | -| 追電星 | floaty + zappy | 飛行中追蹤最近敵(轉向 0.006rad/ms、鎖敵 320px)+雷鏈 ×2(追蹤+連鎖電) | #C9B8FF | 1.30 | -| 雷爆星 | puffy + zappy | AoE 70px/3 傷+雷鏈 ×3(爆炸+連鎖電) | #FFD24D | 0.90 | -| 碎鑽星 | shelly + drilly | 發射分裂 3 發扇形(±90vy)、各傷 6、穿透 1(散射+穿透) | #9ADFD2 | 0.80 | -| 凝光星 | drilly + glowy | 命中生成 100px 凍結光域 1.5s,域內小怪停擺冰藍(凍結場) | #FFF7D6 | 1.15 | - -## 47. v7 新怪物 ×2(全原創;素材 codex imagegen 僅此 2 張,風格與既有嚴格一致) - -- 鑽鑽鼴 Drilly(sandy-brown 鑽頭鼴鼠果凍,`minion-drilly`): - - FSM(`logic/enemyFsm.ts`):潛地 burrow 2.2s(僅露鰭——壓扁貼地 0.55×/0.3× 半透明, - 朝玩家 x 潛行 90px/s;**不可吸、不可傷、觸碰無害、吸力不彈開**)→ 前搖 windup 0.5s - (定點鰭抖動+落點預警 telegraph)→ 破土 surfaced 1.4s(躍出 -360 攻擊;**可吸可傷**)→ 回潛。 - - 吞下得**重鑽星**:傷害 7、彈速 430、穿透 2(低速高傷)。條件可吸(破土窗), - spawner 保證律保守值不計入可吸佔比。 -- 提燈水母 Glowy(warm-cream 提燈水母果凍,`minion-glowy`): - - FSM:緩慢漂近 26px/s+正弦浮動 → 週期 4s 末段 0.9s 預警圈先行(由小到滿半徑擴張 - +明暗閃爍)→ 釋放範圍脈衝(半徑 80、傷害 1,走 hazards 管線)。恆可吸。 - - 吞下得**流光星**:傷害 5、彈速 540、命中 90px 光域 AoE 2 傷。 -- 入編:L2 glowy 10%(可吸佔比 60%);L3 八種混編 drilly/glowy 各 10%(可吸佔比 55%, - drilly 保守不計)。圖鑑 5×2 網格收錄十隻;混合表(§46)與技能頁同步。 - -## 48. v7 中魔王精英系統(levels.ts elite 為 SSOT,零新美術) - -- 每走動關中段一隻精英變體(既有怪 tint+scale+血量池+FSM 參數強化): - -| 關 | 精英 | 基底 | HP | scale | 強化(speedMul) | 掉落稀有味 | -| --- | -------------- | ------ | --- | ----- | --------------------------- | ---------- | -| 1 | 粉紅暴走果凍丁 | jelly | 10 | 1.6 | 跳頻/衝量 ×1.5 | glowy | -| 2 | 鋼青重殼殼 | shelly | 14 | 1.55 | 走速 ×1.4(血量池制不縮殼) | drilly | -| 3 | 暗紫狂咬花 | chompy | 20 | 1.5 | 前搖/冷卻縮時 ×1.6 | glowy | - -- 精英房流程:玩家接近(臂距 480px)且星星門未開 → 武裝——生成精英+軟鎖門 - (半透明果凍門柱,可退不可進)+頭頂血條;擊敗 → 開門+稀有味小怪(走正式 spawn - 管線,吞下即得稀有星味)+回復食物(心形拾取 +2 HP,15s 未拾自動淡逝)。 -- 反卡關雙保險:60s 逾時自動開門(精英留場可略過);星星門已開(配額達成)後不再 - 武裝——關卡已進尾端 release 節奏,既有走查路徑不受影響。精英不可吸、擊殺計入配額; - 白閃後回套變體 tint 維持精英識別。 -- 房界箝制(三席審查補修):精英越房界(左界鏡像門距、右界門前內縮 48px)即回夾並朝 - 房內反向(`stageModel.clampEliteX` 純函式),不出房追殺,60s 開門保險恆有效。 - -## 49. v7 每關攻略 PoC 與節奏補訂(引入→練習→考驗→獎勵) - -| 關 | 引入(0-25%) | 練習(25-45%) | 考驗(45-65% 精英房) | 獎勵(65-100%) | 怪物密度(interval/maxOnScreen) | -| --- | ---------------------- | -------------------- | --------------------------- | -------------------------------- | -------------------------------- | -| 1 | 教學浮字+jelly/floaty | 單向平台+反向彩蛋 | 粉紅暴走果凍丁(跳頻 1.5×) | glowy 稀有味+回復→混合初體驗→門 | 2600ms / 3(低壓) | -| 2 | spiky/殼殼威脅初登場 | 移動平台+彈簧+雲台 | 鋼青重殼殼(血量池 14) | drilly 稀有味→碎鑽星可解鎖→門 | 1800ms / 4(中壓) | -| 3 | 八種混編暖場 | 破磚支線+吞序彩蛋 | 暗紫狂咬花(攻速 1.6×) | glowy 稀有味+雷爆/凝光清場→門 | 1300ms / 5(高壓) | -| 4 | 魔王入場運鏡 | P1 讀招(rain/slam) | P2 dash+P3 狂暴皇冠 | 皇冠彩蛋+星暴終結 | 補生 3500ms / 2 | - -- 攻略 PoC(v7 增補,§43 表仍有效): - - L1 最佳線:反向拿 +1 HP → 中段殺精英拿 glowy+回復 → 吞 jelly+floaty 合成疾光星速清尾段。 - - L2 最佳線:雲台三連站拿滿匣 → 精英房前吞 shelly 備殼盾 → 擊敗重殼殼拿 drilly → - shelly+drilly 碎鑽星掃平台群怪。 - - L3 最佳線:吞 zappy+puffy 合成雷爆星清簇 → 精英房 drilly+glowy 凝光星凍場安全輸出 - → 金星彈留給 chompy。 - - 主線恆不依賴精英/混合星(§46 anti-softlock);精英房 60s 逾時門自動開。 -- e2e 通關 bot(`__sp` hooks 驅動):L1 精英線全程通關案、L3 開門走查案(八種混編在場)、 - 精英軟鎖門阻擋/開門案、混合星彈案、drilly 免傷窗案、走動 bob 行為斷言案(v7.spec.ts)。 - ---- - -# v8 擴充:世界擴張(PM 親撰) - -## 50. v8 關卡 4→7 與雙魔王總覽(levels.ts 資料驅動擴充) - -流程擴為:L1-L3 → L4 果凍王 → L5-L6 → L7 暗月蝠王(第二魔王收尾)(v9 已由 §60 擴為 -九關;v10 已由 §65 取代:十二關三魔王)。解鎖鏈沿 §39 -(第 N 關需 N-1 通關);世界地圖擴為七節點鋸齒路徑(節點半徑收斂 30),新節點沿用 -迷霧鎖定態。save schema v1 不變——舊存檔(≤4 關條目)原樣載入,L5 依解鎖規則自然 -開放、L6/L7 鎖定(相容契約見 save.test「v8 存檔相容」與 e2e「舊存檔相容」案)。 - -| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | -| --- | -------- | ---------- | ------ | ---- | ------ | ------------------------------ | ---------------- | -| 5 | 翔風峽谷 | bg-canyon | 3300 | 10 | 1500ms | 上升氣流柱(§51)、Gusty 主場 | 狂風飄鳥 ×1 | -| 6 | 迴聲石廊 | bg-gallery | 3600 | 12 | 1200ms | Boomy 迴旋彈道、複合陣、全混編 | 雙精英(§52) | -| 7 | 蝕月王座 | bg-eclipse | 854 | — | 3200ms | 第二魔王 Noctra(§54) | —(Boss 即高潮) | - -- LevelSpec 契約變更:`elite: EliteSpec | null` → `elites: readonly EliteSpec[]`(L6 雙精英); - `boss: boolean` → `boss: 'jellord' | 'noctra' | null`(truthy 語意與舊 boolean 相容)。 -- L6 混編為全十二種怪高密度(interval 1200 / maxOnScreen 5),可吸佔比 0.72 - (shelly/drilly 條件可吸保守不計)。 -- bg 貼圖策略(§55):L5/L7 新 biome 各生成 1 張;L6 重用 `bg-arena-l`(TEXTURE_ALIAS) - +深紫 grade 與回聲光塵 ambience 辨識;三關道具條沿用既有主題(heights/arena/throne)。 - -## 51. v8 上升氣流機制(logic/updraft.ts,pure TS 可測) - -- zone 型非碰撞元素(`{ kind: 'updraft', x, topY, w }` 入 levels elements 表): - 柱域=柱寬內、柱頂 topY 與地面頂(400)之間。 -- 升力:柱域內逐幀向上加速 1600px/s²、升速夾限 -330(低於跳躍初速 420,柱內可控); - 柱頂以上不供力自然拋出(無「黏頂」)。 -- anti-softlock(§56):頭頂受阻(blocked.up)即不供力交還重力;柱頂距世界頂 ≥100px - (資料驅動測試守門);主線恆走地面雙層——208 高台為氣流專屬支線(彩蛋/探索), - 資料不變式:y < 272 的平台必須被氣流柱涵蓋(levels.test 守門)。 -- 呈現:柱體淡色矩形(alpha 0.12)+上飄粒子(池化、單柱同活 ≤10),854/1200 皆 60fps。 - -## 52. v8 新怪物 ×3 與雙精英(FSM-first;素材 §55) - -全部 FSM-first 進 `logic/enemyFsm.ts`(時序純函式),呈現接 `systems/enemyUpdates.ts` -per-kind: - -- 孢子菇 Spora(鼠尾草綠 `minion-spora`):定點紮根(更新迴圈每幀清速+一般地面 - 分離;非 Arcade immovable——該旗標會使動態體與靜態地面不分離而穿地,#841), - 週期 3.6s——末段 0.7s - 預警圈擴張 → 向上噴孢子雲(頭頂 -64、半徑 66、滯留 1.6s 區域拒止,走 hazards 管線, - 觸擊即散)。恆可吸 → **孢子星**(傷害 4、命中緩速 2.2s+每 0.7s 輕持續傷 1;緩速期 - 水平速度封頂 60px/s、孢綠著色,enemies.update 中央結算)。 -- 風飄鳥 Gusty(淡天藍 `minion-gusty`):四態 drift(水平漂移+正弦浮動)→(玩家於斜下 - 觸發域 200px)→ windup 0.5s(懸停抖動預警)→ dive 0.6s(鎖定前搖結束當下玩家位置 - 340px/s 撲擊,之後不修正可預判閃避)→ recover 回升(時滿 0.9s 且回抵航高 atBaseY - 才切 drift,#832 比照 cometa——深俯衝後不得自低空直接再漂移)。drift 期近域 - (130×90px)產生側風——推離方向 60px/s positional drift(不與速度控制器對抗), - 與 L5 氣流主題呼應。恆可吸 → 歸入既有**疾風味**(避免味數爆炸)。 -- 迴力殼 Boomy(暖陶土橘 `minion-boomy`):四態 walk 2.2s(緩速巡邏 55px/s、bounce 折返) - → windup 0.5s(定身舉殼抖動)→ throw(投擲迴旋殼刃:360px/s 去程勻減速、0.8s 折返、 - 回程同判定;壽命 2.0s 必回收——**回程彈不可穿門鎖死**(§56))→ cool 1.4s。恆可吸 → - **迴旋星**(§53)。 -- 雙精英(L6):重殼迴力守衛(boomy 基底,HP 16、×1.3,掉流光味)+暗雷水母(zappy - 基底,HP 18、×1.5 追速,掉重鑽味);房址 1300/2500(房距 1200 ≥ 2×門距不重疊), - 沿 §48 全套(軟鎖門/60s 逾時/房界箝制)。L5 精英狂風飄鳥(gusty 基底 ×1.4)掉 - **迴旋味**(L6 主場怪先行體驗,沿 v7 L1 掉 glowy 慣例)。 -- 圖鑑(§36 擴充):7×2 十四格(十二小怪+果凍王+暗月蝠王);立繪縮 50px、字級同步 - 收斂(v7 5×2 十格佈局由本節取代)。 - -## 53. v8 星彈九系與新混合三式(config 表驅動擴充) - -七系 → 九系(§20/§40/§47 擴充): - -| 吞下 | 星彈屬性 | 效果 | 視覺 | -| ----- | -------- | -------------------------------------------------------- | ----------------- | -| spora | 孢子星 | 傷害 4、命中緩速 2.2s(速度封頂 60)+輕持續傷(1/0.7s) | 孢綠 tint #A8D8A0 | -| boomy | 迴旋星 | 傷害 5、速度 520、穿透 1;去程 0.9s 勻減速折返、雙程判定 | 陶橘 tint #E8A878 | - -- StarFlavorSpec 擴欄:`slowMs`/`dotDamage`(緩速持續傷)與 `boomerang`(迴旋彈道); - 緩速/DoT 由 enemies.update 中央結算(單點),迴旋彈道由 `boomerangVelocity` 純函式 - 驅動(GameScene 逐幀轉向、壽命 2.2s 必回收)。 -- 混合三式(STAR_MIXES 六 → 九;§46 規則不變,混合彈永不為破關必需): - -| 配方 | 成分 | 效果 | tint | pitch | -| -------- | -------------- | --------------------------------------------------------- | ------- | ----- | -| 毒爆雲 | spora + puffy | AoE 90px/3 傷+波及未死者緩速 2.6s 持續傷(爆炸+緩速場) | #BCE8A0 | 0.75 | -| 電鋸迴旋 | boomy + zappy | 迴旋雙程判定+每次命中跳電 ×2(回程同樣鏈電) | #F5D878 | 1.28 | -| 迴風刃 | boomy + floaty | 速度 620、雙程各穿透 2 的長弧掃割(第三式 PM 手感裁量) | #C8DCF5 | 1.40 | - -- 「星彈七系」字樣全數改九系(codex 技能頁/README);FLAVOR_HINTS/MIX_HINTS 同步九味九式。 - -## 54. v8 第二魔王:暗月蝠王 Noctra(logic/noctraFsm.ts 表驅動,空中型) - -與果凍王(地面型 §6)區隔的空中型三階段;phase truth 全數收斂 noctraFsm,禁止散落 -scene。呈現層 `systems/noctra.ts` 與 boss.ts 共用 `BossHandle` 介面與 BOSS\_\* 事件契約 -(GameScene 依 `level.boss` 品種擇一建立,HUD/fx/結算零分支)。 - -- 數值:HP 70、身體傷害 1、P2 ≤60%、P3 ≤30%、狂暴節奏 ×1.25、每損 10 HP 掉補給小怪 - (§26 飢荒保證律不變——基礎星彈恆可通關)。(v9 已由 §63 難度根修取代:HP 52、 - 狂暴 ×1.15、每損 8 HP 補給;實測 0% 勝率歸因與全參數表見 §63。) -- 招式循環(表驅動 `noctraAttackCycle`;換階段循環游標重置)(v21 已由 §111 取代: - `noctraMoveTable` 加權表選招,循環游標敘述作廢;招池與 telegraph 數值不變): - - P1 `bomb(盤旋投彈 ×4,落點預警先行)→ dive(俯衝:telegraph+shake+變色前搖 -0.55s → 鎖定點撲擊 → 回升)` - - P2 `bomb ×5 → dive → dive(俯衝連擊)→ summon(召喚 floaty,場上上限 2——cap 由 -FSM 指令帶出、GameScene 依現量夾限走正式 spawn 管線)`(v9 已由 §63 取代:單 dive、 - bomb ×3) - - P3 `barrage(狂暴彈幕:全向放射彈環 ×10)→ sweep(全場俯掠:橫帶預警閃爍 0.6s 後 -貼 y=280 帶速掠全場,站立可躲)→ bomb` -- telegraph 全數必備:dive 落點標記、sweep 橫帶閃爍、bomb 落點標記、階段轉換體色循環 - (P2 白紅、P3 金紫)+白閃抖動;統一走 systems/fx 慣例。 -- 盤旋駕駛:常態沿視寬正弦盤旋(高度 168±14 呼吸浮動);dive/sweep tween 接管期間讓位 - (steering 互斥),死亡冪等(FSM defeated 單向鎖存,演出僅執行一次)。(v9.1 已由 §64 - 補訂:接管結束改速度上限逼近歸位,禁止相位座標直寫——修正返空瞬移。) -- 可達性:玩家跳躍+拍翅 ×3 可觸及盤旋帶;dive/sweep 主動進入地面帶提供輸出窗; - 補給小怪維持彈藥循環。擊破沿 §17 演出(皇冠戰利品:蝠「王」同為王權敘事)。 -- anti-softlock:入場運鏡 active 前傷害靜默忽略;退出/重整走 §35 暫停與 scene restart - 標準路徑(無門鎖、擊破制勝利);通關寫存檔沿 BOSS_DEFEATED 即記。 - -## 55. v8 美術資產(codex imagegen 專用;配額 6/6 用滿) - -| 檔名 | 內容 | 規格 | -| ---------------- | ------------------------------------------- | ------------------- | -| minion-spora.png | 孢子菇:鼠尾草綠 #A8D8A0 圓菇、奶油斑點 | 2048 透明 → 512webp | -| minion-gusty.png | 風飄鳥:淡天藍 #A8CBF0 圓鳥、後掠翼、風渦 | 2048 透明 → 512webp | -| minion-boomy.png | 迴力殼:暖陶土橘 #E8A878 犰狳、舉新月殼刃 | 2048 透明 → 512webp | -| boss-noctra.png | 暗月蝠王:暮光紫 #7A6FD8 蝙蝠、銀月冠、星翼 | 2048 透明 → 512webp | -| bg-canyon-l.png | 翔風峽谷橫景:暖杏糖霜峽谷、風痕絲帶 | 1536×512 無縫平鋪 | -| bg-eclipse-l.png | 蝕月王座橫景:薰衣草夜空、金月、紫塔剪影 | 1536×512 無縫平鋪 | - -重用評估結論:L6 迴聲石廊重用 `bg-arena-l`(同族星空回廊)+grade/ambience 變化;三關 -道具條全數重用既有主題(heights/arena/throne),不另生成。素材 ticket 與生成腳本存 -epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 - -## 56. v8 每關攻略 PoC 與 anti-softlock 不變式 - -| 關 | 引入(0-25%) | 練習(25-45%) | 考驗(45-70% 精英) | 獎勵(70-100%) | 密度 | -| --- | ---------------------- | ----------------------- | --------------------------- | ---------------------------- | ----------- | -| 5 | gusty/spora 亮相+首柱 | 氣流高台+彩蛋(×2 站) | 狂風飄鳥(俯衝 1.4×) | 迴旋味先行體驗→毒爆雲可解→門 | 1500ms / 5 | -| 6 | 全混編暖場+破磚支線 | 移動平台×2+彈簧×2 | 雙精英逐房(迴力守衛/暗雷) | 稀有味雙掉落+吞序彩蛋→門 | 1200ms / 5 | -| 7 | Noctra 入場運鏡 | P1 讀招(bomb/dive) | P2 俯衝連擊+召喚 | P3 彈幕俯掠+星暴終結 | 補生 3200ms | - -- 攻略 PoC: - - L5 最佳線:地面雙層推進 → 乘柱上 208 高台連站 ×2 拿 +1 HP → 精英房前吞 spora 備 - 緩速 → 擊敗狂風飄鳥拿 boomy → spora+puffy 毒爆雲清尾段 → 門。 - 保底線:全程地面層,吸 jelly/floaty/spora 點射,氣流柱可完全不碰(§26 保證律)。 - - L6 最佳線:破磚補彈 → 吞 boomy+zappy 電鋸迴旋清簇 → 第一房擊破拿 glowy → 移動平台 - 帶推進 → 第二房擊破拿 drilly → drilly+glowy 凝光星凍場安全輸出 → 吞序彩蛋金星彈 - 留給 chompy → 門。保底線:逐隻吸射、雙精英 60s 逾時門自動開,可全略過。 - - L7 最佳線:開場 5s 內命中拿彩蛋 → 補給小怪憋滿匣星暴(12 傷)→ P1/P2 於 dive 回升 - 窗跳打 → P3 貼地躲 sweep、拍翅穿彈幕縫。保底線:純標準星點射+跳閃 bomb 落點, - 飢荒立即補生保證彈藥(§26)。 -- anti-softlock 不變式(全部 MUST,測試守門): - - 氣流柱不可卡頂/卡牆:柱頂 ≥100(levels.test)+blocked.up 斷供(updraft.test); - 升力止於柱頂自然拋出。 - - Boomy 回程彈不可穿門鎖死:殼刃壽命 2.0s ≥ 2×折返時(enemyFsm.test),逾時必回收。 - - Noctra 退出/重整/離線恢復不鎖門:boss 關無門、擊破制;BOSS_DEFEATED 即寫存檔。 - - 精英沿 v7 §48 全規則(房間箝制+60s 逾時開門);L6 雙房房距 ≥600(levels.test)。 - - 混合星永不為破關必需(§46 硬規則不變);L5/L6 可吸佔比 ≥50%(levels.test)。 -- e2e 通關 bot(v8.spec.ts):舊存檔相容七節點案、L5 氣流升空案、L5 精英線通關案、 - L6 雙精英逐房通關案、Noctra 三階段擊破入結算案、新混合三式案、spora/boomy 行為案。 - ---- - -# v9 擴充:星化與挑戰(PM 親撰) - -## 57. v9 星化變身系統(logic/transform.ts 純狀態機,表驅動) - -- 觸發:彈匣內同系可變身星彈合計 ≥3 發(強化槽為連吞兩發合成、計 2 發;金星/混合槽 - 破壞資格)時 HUD 彈藥列脈動亮起變身提示;**地面**長按吸入鍵 0.6s 觸發(吸入拉怪 - 進行中與空中不可起手;不新增實體按鍵)。消耗全部彈匣進入形態,持續 10s(玩家頭頂 - 倒數環),到時自動解除;再長按 0.6s 提前解除(不返彈)。 - (v19 已由 §109 取代觸發面:改 SP 鍵點按立即變身/再按提前解除,0.6s 長按門檻 - 廢除;資格條件與形態語彙不變。) -- 語意讓位(輸入矩陣,`resolveActionPress`/`resolveTransformHold`):同系 ≥3 星情境 - 長按=星化(優先於星暴與殼盾);非同系滿匣長按維持星暴;頂槽殼盾星未滿匣維持舉盾; - 點按放開(<150ms)仍發射。變身期間吸入停用(B 鍵改役),星暴/殼盾不充能。 - (v19 已由 §109 取代:長按讓位矩陣退場,SP 天然互斥裁決見 `resolveSpPress`。) -- 三形態(各改變 移動+攻擊+防禦 至少兩項;zappy→雷化、floaty/gusty 味→風化、 - shelly→殼化)(v20 已由 §110 加深:每形態補齊 攻/防/機動 三語彙,下表為 v9 基線): - -| 形態 | 移動 | 攻擊 | 防禦 | -| -------------- | ----------------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | -| 雷化 Voltform | 移速 +15% | 身體帶電接觸傷害 2;B 點按短程鏈電束(170px 內最近敵 3 傷+跳電 2×2 傷,CD 0.9s) | — | -| 風化 Galeform | 拍翅無上限+升力 -330(近自由飛行) | B 點按穿透風刃(傷害 4、速度 640、無限穿透,CD 0.35s);落地 44px 衝擊 1 傷 | — | -| 殼化 Shellform | 移速 -20% | 下砸範圍加倍(120px) | 受傷減半(0.5 傷害池累積)+反彈魔王彈幕(§58) | - -- 呈現:變身爆發(星爆+擠壓)+形態專屬 aura 粒子(三 emitter 常駐池化、僅啟用當前 - 形態、maxAlive 14)+形態立繪(hero-volt/gale/shell,素材未載退回一般姿勢)。 -- anti-softlock 硬規則:**變身永不為破關必需**——全關卡純標準星保底線不變(§26/§46 - 同律);變身資格味(zappy/floaty/shelly)非全關卡保證供給,僅為威力加成路徑。 - -## 58. v9 魔王攻略多樣化與 EX 變體(表驅動擴充,禁止散落 scene) - -- 攻略路徑(每魔王 ≥3 條可行路徑,PoC 全數驗證): - - 果凍王 Jellord:① 標準線——吸補生小怪點射+跳閃 slam/dash 磨死;② 殼化反彈線—— - L4 補生加入 shelly(暈眩窗可吸),殼化後站定將果凍雨反彈回傷(reflect 3 傷/顆); - ③ 頭頂下砸線——下砸命中頭頂(上半身)觸發短暈 0.9s(`BOSS.slamStunMs`,表驅動 - hit window)輸出窗,命中回彈不吃體傷;④ 滿匣星暴 12 傷速攻。 - - 暗月蝠王 Noctra:① 標準線——補給點射+dive 回升窗跳打;② 雷化斷召線——L7 補生 - 加入 zappy,雷化鏈電命中召喚蓄勢中的 Noctra 立即中斷召喚(`interruptSummon`); - ③ 俯衝下砸線——俯衝落地瞬間 0.6s 窗內頭頂下砸觸發長暈 1.8s(`NOCTRA.diveStunMs`); - ④ 彈簧板線——boss 房雙彈簧板(x 190/664,過 stageModel 掃掠背擋)提供非風化到空 - 路徑貼打盤旋帶;⑤ 風化自由飛行貼身輸出。 -- EX 變體(已通關 L4/L7 節點顯示「EX 挑戰」第二入口;`EX_MODS` 兩魔王共用): - - 數值:HP ×1.5(果凍王 90/蝠王 78——蝠王基準沿 §63 難度根修後 52 再乘 EX 係數)、 - 全節奏 ×1.15;入場後緋紅呼吸循環變色演出。 - - 果凍王 EX 新 pattern:擊破時分裂 3 隻小果凍(`split` 事件表驅動、走正式 spawn 管線)。 - - Noctra EX 新 pattern:P3 循環追加「月蝕彈幕矩陣」(`eclipse`:9 列 ×2 波直落彈網、 - 每波隨機留 2 缺口通道、落點 telegraph 先行)。 - - 通關記錄 `exCleared`(save v1 additive 欄位:預設 false、僅信任明確 true、舊檔載入 - 不 crash——e2e 守門);EX 通關於地圖節點與圖鑑魔王條目掛紫星紀念章;L9 通關後地圖 - 提示 EX 入口解鎖。EX 通關不動一般 cleared/bestTime。 - -## 59. v9 新怪物 ×2(FSM-first 進 enemyFsm,均歸既有味系) - -- 磁極獸 Magno(鋼藍灰 `minion-magno`):緩行 idle 2.4s → 前搖 windup 0.7s(預警圈 - 擴張+閃爍)→ 磁場 field 1.9s(150px 磁域:**吸偏玩家飛行中星彈**(`magnetPull` - 逐幀彎折彈道)+磁殼星彈免傷(`resolveMagnoStarHit`)——鼓勵近戰/下砸/變身應對; - 下砸/波及/接觸傷害照常結算)→ 回 idle。恆可吸 → 歸**雷鏈味**(zappy)。 -- 鏡面蟲 Mirri(珍珠銀紫 `minion-mirri`):巡邏 roam 2.4s(末段 0.4s 亮銀預告閃爍 - telegraph)→ 鏡面 mirror 1.5s(定身亮銀高光:**反射玩家星彈**為朝玩家的傷害彈 - (反射彈 1 傷、壽命 1.4s 必回收),`resolveMirriStarHit`)→ 冷卻 cool 1.1s(黯淡 - 明確可打窗)→ roam。恆可吸 → 歸**迴旋味**(boomy)。 -- 圖鑑(§36/§52 擴充):8×2 十六格(十四小怪+雙魔王)。 - -## 60. v9 關卡 7→9 與世界地圖(levels.ts 資料驅動擴充)(v10 已由 §65 取代:十二關與十二節點) - -| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | -| --- | -------- | --------- | ------ | ---- | ------ | ----------------------------------- | ------------- | -| 8 | 磁極洞窟 | bg-cavern | 3400 | 11 | 1400ms | Magno 磁場干擾+drilly 地下突襲組合 | 磁暴磁極獸 ×1 | -| 9 | 鏡影迴廊 | bg-mirror | 3700 | 12 | 1150ms | Mirri 反射+移動平台複合陣 | 雙精英 | - -- 新組合情境:L8 磁場(彈道不可靠)×drilly(地下突襲)→ 近戰/下砸/星化應對; - L9 鏡面反射 × 雙移動平台/雙彈簧 → 反射窗躲位靠垂直機動;magno/mirri 雙新怪同場。 -- L8 開場 hint 浮字(LevelSpec.hint 資料驅動,沿教學浮字機制):首次星化教學 - 「同系星彈集滿 3 發,地面長按吸入鍵 0.6 秒星化變身」;起手區前 500px 無精英 - 無破磚(安全教學帶)。 -- L9 雙精英:銀鏡鏡面蟲(mirri 基底 HP 17 ×1.4,掉孢子味)+暗磁磁極獸(magno 基底 - HP 19 ×1.3,掉迴旋味);房址 1250/2550(房距 1300 ≥ 2×門距)。 -- 世界地圖九節點鋸齒路徑;解鎖鏈沿 §39;save schema v1 不變——v8 舊檔(≤7 關)載入 - L8 自然開放、L9 迷霧鎖定(save.test/e2e 守門)。 -- 背景重用(§55 慣例,不生成新背景):`bg-cavern`→`bg-eclipse` 貼圖(鋼藍 grade+ - 磁塵 ambience)、`bg-mirror`→`bg-arena` 貼圖(銀鏡 grade+鏡光塵 ambience); - 道具條沿用 arena 主題(晶洞/鏡晶質感)。 -- 攻略 PoC: - - L8 最佳線:起手吞 zappy×3 存雷化 → 磁場期近戰/下砸清 magno → 精英房前星化雷化 - 貼身鏈電 → 擊敗磁暴磁極獸拿 drilly → 破磚補彈 → 門。 - 保底線:全程等 field 週期空檔(idle/windup 5.1s 窗)純標準星點射,磁場可完全 - 不進域(§26 保證律,可吸佔比 0.74)。 - - L9 最佳線:吞 mirri/boomy 湊迴旋味彩蛋滿匣 → 鏡面 cool 窗集火 → 第一房銀鏡蟲 - 擊破拿 spora → 移動平台帶推進 → 第二房暗磁獸擊破拿 boomy → 門。 - 保底線:mirror 1.5s 定身期繞行或等 cool 窗(黯淡明確可打),雙精英 60s 逾時門 - 自動開,可全略過。 - - EX 果凍王最佳線:殼化反彈 P1/P2 彈幕回傷 → P3 頭頂下砸短暈接星暴;EX Noctra - 最佳線:雷化斷召+eclipse 走缺口通道、dive 窗下砸長暈輸出。 -- anti-softlock 不變式(測試守門):mirri 反射彈壽命 1.4s 必回收;magno 磁場僅影響 - 星彈(近戰路徑恆存);L8/L9 可吸佔比 ≥50%(levels.test);雙精英房距 ≥600; - EX 為選配挑戰(不阻主線、無新解鎖依賴)。 - -## 61. v9 美術資產(codex imagegen 專用;配額 5/5) - -| 檔名 | 內容 | 規格 | -| ---------------- | -------------------------------------------- | ------------------- | -| hero-volt.png | 噗噗雷化:電黃電弧環身、閃電呆毛、自信笑 | 2048 透明 → 512webp | -| hero-gale.png | 噗噗風化:風藍渦紋、氣流小翼、飄浮姿 | 2048 透明 → 512webp | -| hero-shell.png | 噗噗殼化:青綠圓甲殼片、殼紋高光、壯站姿 | 2048 透明 → 512webp | -| minion-magno.png | 磁極獸:鋼藍灰圓胖獸、馬蹄磁鐵角(紅藍極點) | 2048 透明 → 512webp | -| minion-mirri.png | 鏡面蟲:珍珠銀紫圓甲蟲、拋光鏡面背甲高光帶 | 2048 透明 → 512webp | - -背景不生成:L8/L9 重用既有橫景+grade/ambience 變化(§60)。素材 ticket 與生成腳本 -存 epic 資料夾(art-v9-ticket.md / run-art-v9.sh)。 - -## 62. v9 慈悲補血愛心(logic/mercyHeal.ts 純決策,保底機制非資源農場) - -- 機制參數表(`MERCY_HEAL`,**確定性 pity 決策**;時鐘由呼叫端注入供測試,RNG 僅決定 - 生成位置不參與生成與否——v19 #819 卡 9 去 RNG,取代原 35%/60% 擲骰): - -| 參數 | 一般關 | 魔王房(含 EX)override | 說明 | -| ------------- | --------------- | ----------------------- | ---------------------------------------------- | -| 評估間隔 | 5000ms | 同左 | 每 5s 評估一次(未過門檻僅重置評估計時) | -| 血量門檻 | HP ≤ 總血量 1/3 | HP ≤ 2(絕對值) | 5 血制一般關即 HP ≤1 | -| 久戰門檻 | ≥60s | ≥12s | 本關(本命)經過時間;boss 戰典型 20–60s | -| 生成冷卻 | ≥45s | ≥18s | 距上次愛心生成 | -| pity 受傷門檻 | ≥2 次 | ≥2 次 | `pityHurts`/`bossPityHurts`,自上次生成起累計 | -| pity 低血門檻 | ≥30s | ≥15s | `pityLowHpMs`/`bossPityLowHpMs`,低血累計時間 | -| 每命上限 | 2 次 | 2 次(EX 1 次) | `exMaxPerLife=1`;死亡重試/重開關卡即重置 | -| 回復量 | +1 HP | 同左 | 走既有回復管線 | - -- pity 決策語意(`advanceMercyHeal`):**首顆固定生成**(`spawned === 0`);第二顆起需 - 自上次生成後累積「受傷次數 ≥ pity 受傷門檻」**或**「低血狀態累計 ≥ pity 低血門檻」 - 任一成立才保底放行。受傷偵測=HP 較上一 tick 下降即計 1(單次多傷計 1,回血僅更新 - 基準);低血累計僅於存活且過血量門檻時推進。生成當下 pity 計量歸零。 -- 計量與評估分離:pity 計量逐幀累積,評估間隔到期才做生成決策;任一門檻不過只重置 - 評估計時,**保底計量不消耗**(低血久撐不會白費)。 - -- 生成呈現(重用共用愛心拾取管線 systems/pickups.ts,勿新造 pickup 系統):隨機擇一 - ——空中緩降型(y=150 起以 26px/s 緩慢飄落至地面錨點,降落中可接住)或地面定點型 - (地面錨點浮動);位置=玩家 ±120-240px、夾限世界內(下界 50 保玩家貼牆可達); - 生成時輕微閃光(burstSmall 粉)+zzfx reveal 提示音。 -- 適用範圍:一般關與魔王關(含 EX)皆啟用;HUD 無新元素。 -- 判定:拾取走逐幀 AABB+水平掃掠幾何判定(§43 direct pair 漏檢慣例修法), - 高速走過必中;15s 未拾取自動淡逝。 -- 平衡定位:上限與冷卻硬性,非資源農場;不影響 §26 反卡死保證律(彈藥飢荒補生 - 獨立運作)。 - -## 63. v9 Noctra 難度根修(實測席稽核回寫;bot 勝率門檻收斂定案) - -**根因**(v8 出貨值,雙水準 bot 對線上 0.6.0 實測普通/熟練勝率皆 0%、傷害進度近 0%): -`HOVER_Y=168` 盤旋帶與地面水平星彈幾何錯開——有效輸出窗僅剩俯衝貼地縫,P1 bomb/dive -約 15s 殺穿玩家;「基礎星彈恆可通關」保底線名存實亡。 - -### 63.1 調參前後值(基準表;EX 沿新基準 ×1.5/×1.15) - -| 位置 | 參數 | v8 出貨 | v9 根修 | 目的 | -| --------- | ------------------------------- | --------------------: | ----------------------------: | ------------------------------------------------------------------------------------------------ | -| noctra.ts | `HOVER_Y` | 168 | **246** | 體底降入單跳星彈可打帶(含 ±14 浮動恆可命中) | -| noctra.ts | `SIDE_MARGIN_X` | 130 | **190** | 收窄掃幅,牆側留玩家喘息帶(錨點打法成立) | -| noctra.ts | 盤旋掃速 | 0.0009 | **0.0007** | 峰值橫移降至玩家走速下,保距走位可行 | -| noctra.ts | `DIVE_TELEGRAPH_MS` | 550 | **720** | 普通反應(250-400ms)可讀可躲 | -| noctra.ts | `SWEEP_TELEGRAPH_MS` | 600 | **750** | 俯掠可讀 | -| noctraFsm | `diveHoldMs` | 無 | **300** | 俯衝落地滯留=地面明確輸出窗 | -| noctraFsm | `diveDurationMs` | 1500 | **2100** | 容納前搖+滯留(EX 最高速率下不與下招重疊) | -| noctraFsm | `diveStunWindowMs` | 600 | **900** | 頭頂下砸長暈窗涵蓋滯留段 | -| noctraFsm | `idleMs` | 1100 | **1600** | 表觀 hit window ≥55% | -| noctraFsm | `bombCountP1/P2` | 4/5 | **2/3** | P1/P2 落彈鏈為主要死因 | -| noctraFsm | `barrageCount` | 10 | **7** | P3 密度 | -| noctraFsm | P2 循環 | bomb,dive,dive,summon | **bomb,dive,summon** | 去連擊 | -| noctraFsm | `enrageSpeedMultiplier` | 1.25 | **1.15** | P2/P3 節奏回讀帶 | -| noctraFsm | `maxHp` | 70 | **52** | TTK 對齊補給經濟(普通保底線 ~40-60s 擊破) | -| noctraFsm | `minionSpawnHpStep` | 10 | **8** | 輸出愈多彈藥愈順(正回饋) | -| levels L7 | `spawnIntervalMs`/`maxOnScreen` | 3200/2 | **4500/1** | 供給定位是彈藥非第二傷害源 | -| levels L7 | 補給構成 | jelly/floaty/gusty | **jelly/floaty/zappy** | 移除俯衝型騷擾;保雷化斷召素材 | -| waves.ts | 補給入場側 | 左右交替 | **玩家遠側** | 走向玩家的路程=拾取節奏 | -| homing.ts | `BOSS_AIM_ASSIST` | 無 | **range 560 / 0.0012 rad/ms** | 一般星彈對魔王微導向:地面平射自然上彎入盤旋帶(追蹤彈 1/5 轉率、須大致對向;追電/迴旋星不疊加) | -| mercyHeal | 魔王房 override | 無 | **HP≤2、12s、18s CD、60%** | boss 戰長度下保底真正可觸發(v19 已由 §62 取代 60% 擲骰:改 pity 受傷 2 次/低血 15s 保底) | - -### 63.2 驗收證據(噗頭對噗頭 bot 實測,序列執行;`scripts/noctra-bot-audit.mjs`) - -| 水準 | 反應/走位 | v8 出貨勝率 | v9 根修勝率 | 均傷害進度 | 有效 hit window | -| ---- | --------------- | ---------------: | -----------: | ---------: | --------------: | -| 普通 | 250-400ms/0.65 | 0%(進度 ~0%) | **2/5=40%** | 84% | ~100% | -| 熟練 | 150ms/0.9 | 0%(進度 ~1.4%) | **4/5=80%** | 93% | ~100% | - -- bot 紀律=普通玩家可再現行為:牆側錨點站位、telegraph 讀招(盤旋凍結=俯衝前搖)、 - 落彈側移/低彈道跳越、原地吸入補給、慈悲愛心掃拾;純標準星保底 build(不用變身/混合)。 -- hit window 口徑:體底進入單跳星彈可打帶(≥270)之時間比;另含俯衝滯留地面窗。 -- L7/L4 跳幅:L4 果凍王大參數不動(實測可磨可通關);L7 全參數回落後 P 軸(命中幾何) - 自崩壞回歸常態,級距回落合理帶(≤~1.4×)。 -- 標準星保底線與 anti-softlock 不變式全數維持;變身/混合/EX 仍為加速與挑戰線非必需。 - -## 64. v9.1 熱修:Noctra 返空連續飛行與星暴無敵窗(P0) - -### 64.1 Noctra 返空瞬移根修(logic/noctraFlight.ts,取代 §54 盤旋駕駛敘述) - -**根因**:盤旋駕駛以「凍結相位的絕對座標」逐幀直寫 sprite——俯衝/俯掠/長暈 tween 接管 -期間相位凍結,接管結束當幀位置直接跳回相位點;俯衝落點追玩家(clamp 60..W-60),與 -凍結相位點距離可達數百 px,玩家所見即「返空瞬移」。一般與 EX 共用呈現層,兩型皆中。 - -**修法**(純邏輯層 `logic/noctraFlight.ts`,vitest 對象): - -- `hoverPatternPoint(hoverMs, viewWidth)`:相位 → 目標座標(航線 SSOT 自 noctra.ts 收斂)。 -- `approachPoint(current, target, maxSpeed, dt)`:速度上限逼近——單 tick 位移 ≤ - `maxSpeed×dt`、步長內貼合目標不過衝;`maxSpeedPxPerSec=340`(×speedFactor)嚴格高於 - 最寬幅盤旋峰值橫移(~287px/s),貼軌後恆跟上、接管交還必為連續飛行。 -- 涵蓋:不同落地位置、返空中受擊/相位轉換(cap 隨 speedFactor 縮放)、pause(dt=0 不動)、 - 超大 dt(位移仍受 `maxSpeed×dt` 夾制);e2e 以 rAF 逐幀取樣魔王座標守門單幀位移。 - -### 64.2 星暴無敵窗(§23 星暴補訂) - -- 星暴發動即開 **5s 無敵窗**(`STARSTORM.invulnMs=5000`,config SSOT):與受擊 i-frame - 為獨立計時,結算時 `effectiveInvulnMs = max(受擊, 星暴)` 生效——**取較大值不疊加**、 - 期間受擊零傷害且不重啟計時;到期即恢復正常受擊(受擊判定沿 `combat.resolveHit` - 單一出口)。 -- 視覺沿用受擊 i-frame 閃爍(alpha 節流),不新增散落 tween;受傷姿勢(hero-hurt)仍 - 僅綁受擊 i-frame,星暴無敵不觸發受傷表情。 -- 定位:星暴由「清場大招」升級為「攻防轉換窗」——發動後 5s 內可貼身輸出/穿彈幕走位; - anti-softlock 不變式不受影響(無敵為加成非必需)。 - ---- - -# v10 擴充:三區完結(PM 親撰;主計畫 SSOT=starpuff-20-levels-master-plan v1.2) - -## 65. v10 關卡 9→12 與世界地圖(levels.ts 資料驅動擴充)(v11 已由 §76 取代:十六關與十六節點) - -| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | -| --- | -------- | ----------- | ------------ | ---- | ------ | ------------------------------------------ | ------------- | -| 10 | 幽光晶湖 | bg-lumen | 3400 | 12 | 1150ms | 星門折躍首發(§66)×鏡蟲潛行混編 | 鏡光燈長老 ×1 | -| 11 | 磁晶險徑 | bg-magnetic | 3700 | 13 | 1100ms | 磁力域×折躍複合(卡點一,checkpoint §67) | 雙精英 | -| 12 | 稜晶王殿 | bg-prism | 854+前室400 | — | 3000ms | 第三魔王稜晶雙子(§68)+魔王關體系(§69) | — | - -- 世界地圖十二節點:佈局由關卡數推導(三階鋸齒、節點半徑 24、魔王節點恆最高階——EX - 徽鈕上方淨空恆成立);雙位數關號縮字級 20px。分區分頁延期(最遲 v12,主計畫 §2.2)。 -- save schema v1 不變:`LEVEL_IDS` 擴至 12;v9 舊檔(≤9 關)載入 L10 自然開放、L11/L12 - 迷霧鎖定(save.test/e2e 守門)。 -- 背景重用(§55 慣例,零新背景):`bg-lumen`→`bg-arena`(幽青 grade+冰青湖光塵)、 - `bg-magnetic`→`bg-eclipse`(磁紫 grade+磁紫晶塵)、`bg-prism`→`bg-arena`(稜晶薰衣草 - grade+虹彩稜塵);道具條沿用 arena 主題。 -- 攻略 PoC: - - L10 最佳線:吞 mirri+glowy 湊凝光系推進 → 星門捷徑跳過中段密集帶 → 精英拿 boomy - 味湊電鋸迴旋。保底線:全程地面吸射,星門可完全不用(折躍僅為捷徑與秘密,§26 保證律)。 - - L11 最佳線:吞 boomy+zappy 電鋸迴旋清簇 → 折躍跳過首精英房帶 → 雙精英拿 glowy/boomy - 補配方。保底線:貼地逐隻吸射,雙精英 60s 逾時可全略過;死亡自中點 checkpoint 重生。 - - L12 最佳線:前室拿星力果+滿匣 → P1 光束間隙輸出 → P2 集火單具入掙扎窗 → 窗內補殺 - 雙子連破(跳過 P3)。保底線:標準星逐具磨死,夾擊跳越、晶雨看預警走位。 - -## 66. v10 星門折躍(logic/warp.ts,pure TS 可測) - -- 新 stage element:`{ kind: 'warp', x, y, pairId }`——同 pairId 成對傳送(三區新機制 2/2)。 -- 傳送規則:觸發半徑 40px、進門保留速度向量(body.reset 後回寫)、出門 500ms 全域冷卻 - 防彈跳循環;相機硬切+白閃 0.2s+星塵演出。 -- 跳入制(anti-softlock 幾何設計):門心固定高於就地站立中心 80px——站立/走動不觸發、 - 單跳即入、出門落地即脫離觸發半徑(冷卻期內必然脫離,杜絕回彈循環)。 -- 資料不變式(levels.test 守門):warp 必成對;僅 L10/L11 配置;門心高度帶(站立中心 - -56~-138px);不落於精英房界(±300+觸發半徑)內側(主計畫交叉不變式 15);主線不依賴 - warp——地面路徑恆達星星門(§26 保證律不變)。 -- 呈現(systems/stage.ts):星環按 pairId 輪色(脈動外環+淡填內圈+自旋星芯+上飄星塵, - maxAlive 4/門);傳送後重置彈簧掃掠與星星門掃掠基準(onWarp hook),防前後幀大位移 - 誤觸背擋。 - -## 67. v10 卡點關中點重生(LevelSpec.checkpointX,§4 主計畫卡點緩解) - -- L11 首發:`checkpointX: 1850`(世界中點、落於雙精英房界外)。 -- 語義:本命最遠推進 x 越過 checkpoint 後死亡——就地自 checkpoint 重生(場景不重啟); - killCount/彩蛋進度/計時全數保留(bestTime 語義不變);血量回滿基礎 5、慈悲補血每命 - 狀態重置;死亡 i-frame(1.5s)覆蓋落地瞬間防秒殺。 -- 未越過 checkpoint 或非卡點關:維持既有整關重試。`forceLose` e2e 鉤子與真實死亡同分岔。 -- 純邏輯 `checkpointRespawnX(level, farthestX)` 供 vitest;資料不變式:僅 L11 配置、 - ≈worldWidth×0.5、遠離精英房界 300px(levels.test 守門)。 -- 主計畫 §4 兩案(checkpoint vs 密度降載)v10 以 checkpoint 定版首發;bot 實測死亡率 - 回填後若翻案再議(其後卡點關 L15/L19 統一採用)。 - -## 68. v10 第三魔王:稜晶雙子 Prismix(logic/prismixFsm.ts 表驅動,分裂型) - -與地面型(Jellord §6)、空中型(Noctra §54)區隔的**分裂型**——核心威脅是「目標數量 -變化」迫使玩家切換單體集火與多目標處理。HP 80(階梯 60→52→80)、體傷 1、狂暴 ×1.15、 -每損 10 HP 掉補給(§26)。 - -- 三階段(phase truth 全收斂 FSM;呈現層 systems/prismix.ts 接 BossHandle) - (v22 已由 §112 取代:固定循環改 `prismixMoveTable` 加權表選招,P2 追加鏡界反射與 - 鏡像殘影;招池數值與 telegraph 不變): - - P1 單體(總血 >66%):`idle(1.5s) → 晶柱衝擊(地面尖晶 ×3,落點預警 0.95s)→ idle → -折射光束(橫掃一次,預示線 0.5s)→ …` - - 晶柱預警(#810 修復):0.6s→0.95s——500ms 反應玩家迴避率 0%→88%(工具實測); - 預警視覺為落點橢圓+尖刺實際範圍白框+裂紋豎線閃爍(形狀與明滅雙訊號,色弱不依賴 - tint);下限 SSOT=`difficulty.AUDIT_THRESHOLDS.spikeTelegraphMinMs`(900ms)。 - - P2 分裂(≤66%):剩餘 HP 均分為**雙獨立血條**(HUD 魔王條雙節顯示,BOSS_TWIN_HP - 事件);鏡像雙子同一指令左右對稱執行——`雙生夾擊(同步閃爍 0.6s → 左右對衝互換位, -跳越可躲;#809 衝撞前搖對齊 ≥600ms 可讀性紅線)→ 交錯光束(一具地面帶、一具空中帶) -→ 召喚 mirri(場上限 2,雷化鏈電可中斷 §58 慣例)`。 - - 殘核掙扎(事件驅動):單具擊破 → 另一具入 1.0s 掙扎僵直(體色轉暗 telegraph、可傷); - 窗滿 → 存活具吸收殘核合體入 P3(裂核 HP=存活具剩餘)。 - - P3 裂核:環繞碎晶盾 ×4(可擊破星彈屏障,軌道公轉)→ 全域折射彈幕(放射 ×8,蓄能 - 轉白)→ 晶雨(落點預警 0.6s ×3)→ … -- **雙子連破**(§70 彩蛋):掙扎窗內補殺第二具=總血歸零直接擊破、跳過 P3。 -- 多本體工程契約:BossHandle 增選配 `getBodies()`/`applyDamageAt(x,y)`/`getShields()`; - GameScene 星彈/觸碰/下砸/反彈逐本體接線,受擊側依命中位置歸最近存活本體;準星輔助、 - 殼化反彈、鏈電束一律取最近存活本體。 -- 變身互動(優勢解非必需):雷形態鏈電同時波及雙子與碎晶盾;殼形態格擋夾擊;風形態 - 跨場重定位。下砸命中頭頂僅回彈免體傷(分裂型無暈窗)。 -- EX 差分(`EX_MODS` ×1.5/×1.15 共用):HP 120、分裂閾值 66%→75%、掙扎窗 1.0s→0.7s、 - 碎晶盾 4→6、雙子動作去同步(相位錯 260ms,讀招難度升級)。 - -## 69. v10 魔王關特殊體系(前室/短期增益/L12 首發;L4/L7 回補延 v11+) - -- **補給前室**(systems/bossRoom.ts prefab;`LevelSpec.anteroomPx` 資料驅動): - - arena 前 400px 廊道:runtime 世界寬=前室+動態視寬(854–1200);玩家自廊道起點入場。 - - 固定配置:慈悲愛心 ×1(tier-2 回 2 HP,禁止門口全滿血 P-65)+可吸補給怪 ×3(進場 - 即可滿匣)+增益二選一台座(`anteroomBuffs`,取一消一)。 - - 單向門:越過前室右緣即鎖閉(果凍門柱),重試自前室起;相機三段——廊道剛性跟隨 → - 入門停跟隨對齊 arena → 魔王入場運鏡。 - - 補給/慈悲錨點 arena 化:魔王補給與召喚自 arena 左右緣入場;慈悲愛心錨點下界改 - arena 左緣(防落於門後不可達)。 -- **短期增益表**(logic/buffs.ts `BUFF_SPECS`,純邏輯可測): - -| id | 名稱 | 效果 | 時效 | HUD | -| ------ | ------ | --------------------------------------- | ---------- | ----------------- | -| shield | 護盾泡 | 吸收 1 次任意傷害(彈幕/接觸/hazard) | 15s 或破盾 | 單一 icon+倒數環 | -| power | 星力果 | 星彈傷害 ×1.5(含混合星與變身射擊) | 10s | 同上(後拾覆蓋) | -| swift | 疾風靴 | 移速 ×1.3、加減速 ×1.4(movement 注入) | 12s | 同上 | - -- 規則(全部 MUST):同時僅存一個、後拾覆蓋;增益永不為破關必需(有界加成非無敵); - 走動關不投放;arena 內僅 P2 高風險位刷 1 顆(`arenaBuff`,10s 未拾淡逝)、EX 刷新減半 - =不投放;護盾格擋走 `damagePlayer` 單一受擊入口。 -- movement 契約更新:`approachVelocity` 增選配 `rateMul`(缺省 1 零回歸);速帽尊重提速 - 後目標值(同時修正 §57 雷化 +15% 被常速帽逐幀鉗回的既有缺陷)。 -- L12 配置:前室二選一=護盾泡/星力果;P2 稜晶柱頂刷疾風靴 ×1(高風險位 P-41)。 - -## 70. v10 魔王關專屬彩蛋與每關驗證 - -- 新觸發器 `twin-finish`(eggs.ts 第五型):時窗真值由 prismixFsm 持有(單一真值), - GameScene 收到 twinFinish 事件餵入觸發器——鎖存、gold-star 獎勵+全屏稜光演出; - `vent-hit-count` 已於 v11 落地(§75)、`survive-collect` 隨 v12(主計畫 §7.3)。 -- 慈悲補血:L12 沿用 §62 魔王房 override(HP≤2、12s 起評、18s 冷卻、上限 2;v19 已由 - §62 取代 60% 擲骰:改 pity 受傷 2 次/低血 15s 保底)——`bossRoom` 判定隨 `level.boss` - 泛化,零新碼。 -- anti-softlock 不變式(測試守門):warp 四不變式(§66);checkpoint 落點房界外(§67); - L12 補生全可吸且恆可吸佔比 ≥0.6;碎晶盾可全數擊破(星彈屏障非無敵殼);前室單向門 - 重試自前室起、arena 無門鎖擊破制(§10.2-10);增益永不必需(§69)。 -- e2e 通關 bot(v10.spec.ts):L10 不用星門全地面通關案(floorbot-no-warp-clear)、星門 - 折躍傳送案、L11 checkpoint 重生案、L12 前室→門鎖→三階段→雙子連破案、舊存檔十二節點 - 相容案、雙節血條案(HUD 直接觀測 `__sp.twinHud` 於 v11 補齊,見 v11.spec)。 - -## 71. v11 糖漿潮汐(logic/tide.ts,pure TS 可測) - -- 四區主機制 2/2(主計畫 §5 L14):關卡級配置 `LevelSpec.tide?: { maxY, periodMs, dutyPct }` - ——非 stage element;底部糖漿帶週期漲落,漲潮時強制走平台層。 -- 水位時間軸(tideWaterY):乾潮(收納世界底 y=600 等效無水)→ 漲坡 0.9s(地面頂→漲頂 - 線性)→ 滿潮持平 → 退坡 0.9s 回地面頂;漲潮前 1s 河面冒泡 telegraph(tidePhase)。 -- 浸水結算(GameScene.advanceTide 單點):接觸傷害 1 走 damagePlayer 單一入口(i-frame/ - 護盾泡自然生效)+強緩速(水平封頂 60px/s)+垂直鎖上推 -240(**永不吸底**, - anti-softlock §10.2-4)。 -- dry-window 不變式(levels.test 守門):主地面每週期露出 ≥40%(dutyPct ≤0.6)、平台層 - 頂恆高於漲頂 24px、僅 L14/L15 配置;等窗推進為合法保底行為(主計畫 §0.1 定義 6)。 -- 交叉不變式(主計畫 §10.2-13/-17,systems/tide 接線):漲潮期 Magno 生成替換為 jelly - (磁場不覆蓋漲潮期可站位)+補生落點上收至水面上方淨空帶(tideSpawnY,48px 淨空)—— - 均走 waves.adjustSpawn hook,缺省直通零回歸。 -- L16 場控沿用(§74):Syrona P2 潮汐入場、P3 大沸騰——同一 createTide 管線由魔王 hooks - 控制(startTide/boilTide),浸水與生成過濾自然生效。 - -## 72. v11 熱泉噴口(updraft 週期參數化,零新 element kind) - -- 四區主機制 1/2(主計畫 §5 L13):既有 `updraft` 增 `periodMs?/dutyPct?` 選配——缺省= - 恆常供力(**L5 氣流柱行為零回歸**,levels.test 斷言 L5 恆缺省);有值=週期噴發。 -- 相位(ventPhase):週期頭 idle(不供力、柱體幾近隱形)→ 末段 0.5s telegraph(蒸汽 - 微亮預警)→ 尾段 duty 比例噴發(erupt 供力,沿 §51 升力管線:加速 1600、升速夾限、 - blocked.up 斷供全數重用)。L13/L15 取 periodMs 2600/3200、dutyPct 0.31(≈0.8-1.0s)。 -- 資料不變式(levels.test 守門):週期噴口僅 L13/L15;periodMs ≥1500、dutyPct ∈(0, 0.6]; - 柱頂上方 160px 拋出弧淨空(防無限拋接)+柱頂 ≥100 沿 §51。 -- 呈現(systems/stage.ts):柱體/粒子隨相位開闔(idle α0.03 → telegraph α0.10 → - erupt α0.20+滿量粒子);`__spStage.vents()` 觀測點回報各柱 [x, 噴發中]。 -- 保底線(floorbot-vent-ground-pass,v11.spec):視噴口為普通地磚全程地面推進, - 升托僅為捷徑非必需。 - -## 73. v11 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) - -| 怪物 | FSM 四態 | 可吸性 | 星味映射 | -| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ----------------------------- | -| 焦糖泡 Bubbla | submerged 潛伏 2.2s(壓扁露頂,免傷不可吸)→ ripple 漣漪前搖 0.6s(telegraph)→ leap 拋物躍出 1.4s(升 0.5+頂點滯空 0.4+落 0.5,**可吸可傷窗**)→ dive 回潛 0.5s | 條件可吸(躍出窗) | 爆裂味(puffy) | -| 熔糖投手 Splatta | patrol 緩走 2.4s → aim 舉勺瞄準 0.5s(著色 telegraph)→ lob 投擲(單幀事件態,拋物糖球 ×1)→ cool 冷卻 1.6s | 恆可吸 | 孢子味(spora,黏緩語意一致) | - -- Bubbla 幾何:定點怪(重力關閉);躍出位移由 `bubblaLeapOffsetY` 純函式導出、逐幀 - 速度逼近驅動(沿 §64 噴口逼近制慣例,禁絕對座標直寫);受擊窗 resolveBubblaHit 沿 - drilly immune/vulnerable 慣例;isPhasedOut 半潛觸碰不結算、吸力不彈開。 -- Splatta 糖球:拋物彈道(重力開)、壽命 2.4s 逾時必回收(§56);落地轉灼燙糖斑 - (滯留 1.2s 區域拒止,走既有 hazards 管線,沿孢子雲模式)。 -- 精英化:焦糖泡霸(L13,躍出節奏 ×1.5、掉雷鏈味)、糖漿投擲隊長(L14,拋射 ×1.5、 - 掉重鑽味)——沿 §48 tint+scale+倍率零新美術。 -- 圖鑑(§36)收錄:十八格(十六小怪+雙魔王),欄數由條目數推導(9×2 於 854 寬 - cellW≈89 仍可讀;分頁與地圖分區分頁同批延後評估)。 - -## 74. v11 第四魔王:Syrona 熔糖窯后(logic/syronaFsm.ts 表驅動,場控型) - -與地面型(§6)、空中型(§54)、分裂型(§68)區隔的**場控型**——本體半定點於右側 -王窯座(不追打),威脅來自「地形被改寫」:潮汐、噴泉、滴落把可站空間動態壓縮, -考驗空間規劃。HP **90**(階梯 60→52→80→90)、體傷 1、狂暴 ×1.15、每損 10 HP 掉補給。 - -- 三階段(phase truth 全收斂 FSM;呈現層 systems/syrona.ts 接 BossHandle) - (v22 已由 §112 取代:固定循環改 `syronaMoveTable` 加權表選招,糖漿波追加焦糖化; - 招池數值與 telegraph 不變): - - P1(>66%):`糖漿噴泉(地面點 ×3 順序噴發,冒泡 telegraph 0.8s)→ 散熱僵直 2.5s → -焦糖射彈(拋物 ×3,舉臂 0.5s)→ 僵直 → …` - - P2(66-33%):**潮汐入場**(phase 事件觸發 startTide,沿 §71 管線);循環 - `熔糖滴落(天花板 ×4 預警光斑 0.7s → 直墜)→ 吟唱僵直 2.0s → 召喚 Bubbla(上限 2, -雷化鏈電可中斷 §58 慣例)→ 噴泉加密 ×4 → …` - - P3(≤33%):**大沸騰**(boilTide:潮汐週期 -30%、漲頂 +24px);循環 - `全場糖漿波(邊緣起浪 0.9s → 單向橫越 250px/s,跳越可躲)→ 波後僵直 2.0s → -噴口超載 2.6s(arena 雙噴口恆噴+升托增強至 -640,開放直達皇冠的垂直路線)→ …` -- arena 場控幾何(§28 禁硬編,呈現層依動態視寬比例佈建;LevelSpec 幾何表留空): - 浮台 ×3(22%/47%/70%,y 336/304/336——低台 P2 漲頂下可站、高台 304 沸騰期保底位, - FSM 測試守門「每循環必留 ≥1 保底位」)+噴口 ×2(30%/58%,週期同 L13)——供力由 - GameScene 逐幀委派 `getVentLift`(BossHandle 選配),浮台由 `getPlatforms` 接 collider。 -- 皇冠弱點:頂帶(本體頂緣 34px 內)命中 ×2 傷(applyDamageAt 位置判定);乘噴口 - 升空為主要到頂路徑。保底線:讀潮汐節拍站浮台點射,僵直窗(散熱/吟唱/波後 ≥2s) - 為固定輸出窗,時窗佔比 0.50 保證磨死(主計畫 §3.2 保底 TTK ≈58s)。 -- 變身互動(優勢解非必需):風形態滯空渡潮直取輸出窗;殼形態硬吃一次糖漿波保節奏; - 雷形態清召喚 Bubbla。場控型免暈:下砸命中僅回彈免體傷(trySlamStun false)。 -- EX 差分(EX_MODS ×1.5/×1.15 共用 → HP 135):噴泉 ×5、Bubbla 上限 3、滴落點 6、 - 大沸騰週期再 -25%;質性差分=**噴泉順序隨機化**(每循環 Fisher-Yates 洗牌出序, - rng 注入可測;一般模式恆固定升序可背板)。 - -## 75. v11 魔王關專屬彩蛋與每關驗證 - -- 新觸發器 `vent-hit-count`(eggs.ts 第六型):**窯風三連**——乘噴口升空期間命中 - Syrona 累計 3 次 → heal+窯火謝幕演出。命中計數真值由 syrona 呈現層持有(沿 - twin-finish 單一真值模式):命中當下玩家位於任一噴口柱域內即計數,滿 3 發 - onVentEgg 餵入 GameScene 觸發器鎖存。 -- L16 魔王關體系(§69 直接複用):前室 400px+護盾泡/疾風靴二選一+P2 噴口上方刷 - 星力果(`anteroomBuffs: ['shield','swift']`、`arenaBuff: 'power'`);補生 jelly 0.3/ - bubbla 0.4/floaty 0.3(恆可吸 0.6 保飢荒保證律)。 -- anti-softlock 不變式(測試守門):潮汐 dry-window 與永不吸底(§71);週期噴口 - 非噴發期不供力、L5 缺省零回歸(§72);Bubbla 躍出窗恆現(週期驅動非條件觸發)、 - 糖球/糖斑壽命有界(§73);Syrona 每循環必留 ≥1 保底位、僵直窗 ≥2s(§74); - L15 等窗推進合法(floorbot-tide-wait-window)。 -- e2e 通關 bot(v11.spec.ts 六案):舊存檔十六節點相容、L13 噴口週期翻轉+地面保底 - 通關、L14 潮汐浸水永不吸底+等窗通關、L15 checkpoint 重生、L16 Syrona 三階段 - (前室→P2 潮汐入場→P3 大沸騰→擊破寫檔)、L12 雙節 HUD 直接觀測(§70 收尾)。 - -## 76. v11 關卡 12→16 與世界地圖(levels.ts 資料驅動擴充) - -| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | -| --- | -------- | ----------- | ------------ | ---- | ------ | ------------------------------------------------- | --------------- | -| 13 | 焙糖丘陵 | bg-kiln | 3300 | 11 | 1400ms | 熱泉噴口首發(§72)×Bubbla/Splatta 亮相 | 焦糖泡霸 ×1 | -| 14 | 熔糖河谷 | bg-valley | 3600 | 12 | 1250ms | 糖漿潮汐首發(§71) | 糖漿投擲隊長 ×1 | -| 15 | 沸糖窯道 | bg-kilnway | 3800 | 14 | 1100ms | 潮汐×噴口複合 gauntlet(卡點二,checkpoint 1900) | 雙精英 | -| 16 | 熔糖王窯 | bg-kilnhall | 854+前室400 | — | 3000ms | 第四魔王 Syrona(§74)+魔王關體系(§69) | — | - -- 世界地圖十六節點:節點半徑再收斂 24→20(854 寬間距 ≈51px 單頁可容納);三階鋸齒 - 12 項循環下四魔王節點(L4/L7/L12/L16)恰全落最高階,EX 徽鈕淨空恆成立; - 雙位數關號字級 17px。**分區分頁為 v12 硬項**(主計畫 §2.2,20 節點單頁確定放不下)。 -- save schema v1 不變:`LEVEL_IDS` 擴至 16;v10 舊檔(≤12 關)載入 L13 自然開放、 - L14-L16 迷霧鎖定(save.test/e2e 守門)。 -- 美術(§9 主計畫 v11 批 5 張):`bg-kiln-l`(1536×512 無縫,四關共用 grade 區分)、 - `props-kiln` 道具條 4 件、`minion-bubbla`/`minion-splatta`/`boss-syrona`; - 缺件期間烘焙保底不阻開發。 -- 攻略 PoC: - - L13 最佳線:乘噴口越丘陵直取精英拿 zappy 味。保底線:地面吸射推進,噴口僅捷徑。 - - L14 最佳線:讀潮汐節拍退潮衝刺漲潮上台、風形態飛渡長浪段。保底線:主地面退潮窗 - 恆可通行,逐段等潮推進,全程可不碰平台層。 - - L15 最佳線:雷爆星清簇→乘噴口鏈跨大漲潮段→雙精英補味。保底線:**等窗推進**—— - 漲潮期安全帶原地等退潮、退潮窗地面逐段推進;雙精英 60s 略過;死亡自 1900 重生。 - - L16 最佳線:風形態滯空躲潮→噴口升空打皇冠 ×2。保底線:讀潮汐站浮台點射, - 僵直窗磨死。 - ---- - -# v11.1 熱修:站台下跳穿落回歸與吸入接觸豁免(P0) - -## 77. v11.1 熱修:下跳穿落根修、蹲姿指示與吸入豁免 - -### 77.1 站台「下+跳」穿落回歸根修(補訂 §29/§44) - -> 2026-07-26 取代注記(§117):本節根因鏈第 1 點「擠壓縮小 body」的耦合已由 -> visualScale 物理/視覺解耦通道根治——物理箱永不隨美術縮放,`LANDING_SQUASH_MIN_VY` -> 門檻補丁退場;`recentlyGroundedMs`/`restingOnOneWay`/`oneWayLandBand` 屬獨立 -> 語意修正(coyote 收斂、旗標抖動免疫、下砸防隧穿),維持有效。 - -**根因鏈**(worldstep 逐步 trace 實證): - -1. 落地擠壓 `squashStretch(1.25, 0.75)` 於每次「重新接觸」觸發——擠壓縮小 body - (scale 連動 `Body.updateBounds`)使腳底離台 → 微墜再落地 → 再擠壓,形成 ~20Hz - 自持迴圈;站立時接觸旗標(blocked/touching.down)僅 ~1/3 物理步為真。 -2. 「下+跳」落在假空中幀(~2/3 機率)時被 v7 下砸(`resolveJumpPress`)誤判接管; - 下砸啟動擠壓(scaleY×1.3)使身體單步位移 ~22px,超過 Phaser `OVERLAP_BIAS(4)+ΔY` - 防隧穿上限而貫穿單向平台——玩家所見即「有時暴力穿落、有時原地跳」的不確定行為。 -3. `standingOnOneWay` 舊 ±4px 容差小於迴圈震盪幅度(4.7px),接觸幀也會間歇漏判。 -4. 地形粉紅平台(`GameScene.addTerrain`)從未接入下穿系統,僅能靠隧穿 bug 下降。 - -**修法**(四點聯動,均有單測): - -- 落地擠壓加最低著地速度閘 `LANDING_SQUASH_MIN_VY=120`:微速重新接觸不再擠壓, - 迴圈斷根(實測站立接觸穩定度 120/120 步)。**已退場(§117 根治)**:解耦後擠壓 - 不再縮物理箱,門檻無存在必要。 -- `resolveJumpPress` 增 `recentlyGroundedMs`(傳 coyote 殘量):coyote 窗內視同在地, - 下砸僅「真空中」(離地 >150ms)觸發——§44 矩陣「空中」行語意收斂為真空中。 -- 站台判定抽 `stageModel.restingOnOneWay` 純函式:接觸旗標**或**沉降幾何 - (腳底於台頂 −6..+8px 帶內且 0 ≤ vy ≤ 90)擇一成立,對旗標抖動免疫。 -- 著地帶 `oneWayLandBand(stepΔY)=max(6, ΔY+2)` 動態放寬:下砸(~11.7px/步)與高處 - 落下不再隧穿單向平台;低速維持 +6 緊帶防側切。 - -**地形平台統一**:粉紅平台掛 `canLandOneWay` process callback+`terrainOneWay` hook -納入同一下穿裁決——玩家視角所有「單向平台」下+跳皆可穿落(S1 教學一致性)。 - -### 77.2 蹲姿視覺與跳鍵下跳指示(§21 控制補訂) - -- 蹲姿:地面壓下 120ms 內壓扁(scaleX +14%/scaleY −22%)+下沉 3px; - `walkFeel.advanceCrouch` 純函式驅動,走 bob 同款 POST_UPDATE 視覺通道、 - PRE_UPDATE 還原——**物理永不見蹲縮**(防 77.1 擠壓迴圈同型問題)。 -- 下跳指示:壓下且站單向平台(跳鍵此刻=下跳)→ 跳鍵轉琥珀+鍵帽箭頭翻轉朝下 - (`is-drop-ready` class,純 CSS clip-path 旋轉,零文字零 emoji);鬆開或離開 - 可穿落狀態即還原。決策重用 `shouldDropThrough`(單一裁決來源),controls 層 - 邊緣偵測 class 切換不逐幀碰 DOM。 - -### 77.3 吸入接觸豁免(§5 吸入補訂) - -- 規格:**被吸入中**(拉力作用中)的怪對玩家無接觸傷害;吞下判定照舊;未被吸入 - 的其他怪照常傷害——不做吸入全程無敵,風險回報保留。 -- 實作:`combat.inhaleGraceUntil / isContactHarmless` 純函式——`applyInhalePull` - 拉力逐幀刷新 250ms 豁免窗,接觸結算單點查窗;吸入中斷(鬆開/轉向/離錐)後 - 窗過期即恢復傷害性;enemies spawn 池重用重設防跨個體殘留。 -- 根因:拉近中的怪貼身瞬間(轉向/鬆開/出錐殘餘飛行)觸發受擊,實測 12-25% 命中; - 拉力結算與接觸結算間缺「被吸入中」狀態橋接。 - -### 77.4 吸入大嘴影格(素材;§61 慣例沿用) - -- `hero-inhale-big-1/2`(codex imagegen,512×512 webp 透明背景):吸入姿勢嘴部 - 誇張放大兩段影格,啟動吸入後兩影格 ~160ms 交替營造吸力節奏;素材未載入時 - 回退既有 `hero-inhale`(tex fallback 慣例)。 - -## 78. v12 分區分頁世界地圖(logic/zones.ts+MapScene,主計畫 §2.2 硬項落地) - -- 二十節點單頁確定放不下(v11 十六節點半徑 20 已是單頁極限):改「分區分頁」—— - 每區一頁 ≤5 節點(半徑回復 24 可讀性回升)、頁籤列直達任一已解鎖區(等效快速 - 旅行,零新系統)。 -- 五區資料 SSOT:`ZONES`(果凍平原 L1-L4/天風峽域 L5-L7/幻晶深域 L8-L12/ - 焙糖火山 L13-L16/星核聖域 L17-L20);頁內節點由 `LEVELS` 區間過濾推導—— - 列車過渡期末區未滿編自然收斂,關卡擴充分頁零改動。 -- 區解鎖=區首關解鎖(前區魔王擊破,引用 P-03 分頁即區域錨點);未解鎖區頁籤 - 灰顯無入口。頁標頭顯示該區彩蛋 found/total(P-11 分項透明化)。 -- 預設頁=當前可挑戰關所屬區;揭霧跨區自動開對應頁(reveal 帶入);頁籤切換以 - `scene.restart({ page })` 實作(DOM 鈕由 shutdown 自清,零洩漏);視寬變更重排 - 保留當前分頁。魔王節點固定最高階 y=224(EX 徽鈕淨空恆成立),走動關 300/262 交錯。 -- 存檔相容:schema v1 不變、`LEVEL_IDS` 擴至 20——v11 舊存檔(≤16 關條目)原樣 - 載入,L17 依解鎖鏈自然開放、L18-L20 迷霧鎖定(save.test/e2e 守門)。 - -## 79. v12 流星雨(logic/meteor.ts+systems/meteor.ts,pure TS 可測) - -- 關卡級環境彈幕(`LevelSpec.meteor?: { intervalMs, waveSize }`):波次節拍 → - 落點抽選 → 預警圈 0.8s(滿張即著地)→ 隕星恆速直墜 → 著地餘燼 0.4s 淡出。 -- anti-softlock 不變式(主計畫 §10.2-7):預警 ≥0.7s、同屏隕星 ≤3(效能預算)、 - 開門後門前 ±120px 禁投、玩家縱帶 ±48px 恆排除(滯空無水平逃逸速度與腳下連投 - 取聯集,交叉不變式 14 一併覆蓋)。 -- 交叉不變式 14(低重力×流星):隕星不掛重力、恆速 520px/s 直墜——低重力關落地 - 時刻不延後,生成高度由墜速×預警時長自著地點反推。 -- 落點抽選純函式 `pickMeteorX`:可投範圍挖除排除帶後 rand01 沿剩餘總長線性映射; - 無合法段回 null 棄投(永不強投排除帶)。 -- 隕星可被星彈擊碎(碎裂粒子、星彈吸收);隕星/餘燼命中玩家走 damagePlayer 單一 - 入口(i-frame/護盾泡自然生效)、隕星命中即碎。程序化貼圖零新美術。 -- Voidra P2 轟炸沿單一 meteor 管線:`setActive/setSpec` 開關與調參(§82)。 - -## 80. v12 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) - -| 怪物 | FSM 時序 | 可吸性 | 星味映射 | -| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------- | -| 星屑幽靈 Twinkla | phased 虛化 2.0s(半透明、不可吸不可傷、穿身無害)→ shimmer 星光聚攏 0.5s(telegraph)→ solid 實體 1.8s(緩慢追飄,可吸可傷窗)→ 回虛化 | 條件可吸(實體窗) | 流光味 | -| 彗尾飛魚 Cometa | glide 高處巡游 →(玩家進 230px 觸發域)→ lock 鎖定 0.55s(閃爍,鎖定後不修正)→ dash 斜向俯衝 0.6s(420px/s 沿路拖彗尾 hazards)→ recover 回升 | 恆可吸 | 疾風味 | - -- Twinkla 穿身無害=isPhasedOut(觸碰不結算、吸力不彈開)+damage 免傷雙閘; - 精英「星屑幽長」(×1.4)僅縮虛化期,telegraph 與實體窗不縮(§48 審查慣例)。 -- Cometa 彗尾段走 hazards 管線(tailIntervalMs 90/tailLifeMs 500 逾時必回收 - §56);精英「彗核疾魚」俯衝 ×1.4;鎖定後不修正=可預判閃避。 -- 圖鑑補完:雙新怪入鑑(18 小怪)+三新魔王徽記(Prismix/Syrona/Voidra,5 魔王) - ——23 格佈局沿 cols 條目數推導。 - -## 81. v12 低重力(LevelSpec.gravityScale,零新 element kind) - -- 關卡級重力係數(缺省 1.0=既有全關卡零回歸):GameScene create 以 - `GRAVITY_Y × gravityScale` 顯式重設世界重力(單點注入,movement/player 純函式 - 簽名不變;每次 create 必重設防前關/Voidra P3 注入殘留)。 -- L17/L18 取 0.55(浮月感)、L19 取 0.85(輕低重力);跳躍初速/拍翅次數/升力不變。 -- 值域 [0.5, 1.0] levels.test 守門(主計畫 §10.2-6);gravityScale ≤0.7 視為 - 208 高台的升降服務(低重力大跳+拍翅可達,levels.test 高台服務判定第三路)。 -- Voidra P3 runtime 注入 0.55(§82):hook 直寫世界重力、擊破/銷毀/段重試復原。 - -## 82. v12 最終魔王:蝕星魔核 Voidra(logic/voidraFsm.ts 表驅動,場控收束型) - -- HP 110(魔王階梯峰值 > Syrona 90);三段結構(主計畫 §6.3 v12 定案:P2=定點 - 轟炸生存段,追逐捲軸案落 backlog): - - **P1 王座戰(>70%)**:pull 重力牽引(漣漪 telegraph+水平 positional drift - 110px/s 恆低於玩家全速)→ ring 星屑彈環 ×6 → claw 虛空爪擊(落點紫紋 0.6s、 - 鎖定不修正);收爪僵直 2.5s 固定輸出窗。 - - **P2 生存段(70-40% 或 40s)**:核心升頂不可及(受擊體停用+FSM 免傷雙閘)、 - 40s 波次表定點轟炸——隕星波(沿 §79 meteor 管線連續投放)+晶柱崩落 ×7 波 - (落點預警 0.7s)+炮擊過熱窗 ×3(核心下沉 3.0s=唯一輸出窗);沿途空投星屑 - ×5(§83 彩蛋收集);段內固定慈悲愛心 1 顆(16s 投放)。時間驅動(40s 播完) - 與傷害驅動(過熱窗打穿 40%)雙轉換路徑入 P3。 - - **P3 核心決戰(≤40%)**:全場低重力 0.55 注入 → barrage 蝕星彈幕(放射 ×8+ - 螺旋雙層)→ crush 黑洞潮汐(水平牽引 150px/s < 玩家全速 220,交叉不變式 16; - arena 無坑洞+實牆邊界);裂核大窗 3.5s(金紋呼吸提示)。 - (v23 已由 §113 取代:P1/P3 固定循環改 `voidraMoveTable` 加權表選招並追加 - 星光虹吸;招池與 telegraph 數值不變、P2 波次表驅動不變。) -- anti-softlock(主計畫 §10.2-8):P2 零擊殺可過(純走位 40s)、無位置懲罰即死、 - 不設計時失敗;**段起點重試**——P2/P3 死亡不回滾整場(trySegmentRespawn:彈幕/ - 星屑/轟炸/殘留 delayedCall 清場+FSM resetToPhase+玩家沿 checkpoint 管線重生於 - arena 左帶);P1 死亡走一般敗北流程。defeated 單向鎖存冪等。 -- 段重試清場(審查根修):段起點重試保留同一場景——補給小怪與飛行中隕星/餘燼 - 必須隨重生全數清除(GameScene.clearFieldForSegmentRetry,比照整場重啟語義), - 且 spawnBossMinion 夾限場上 maxOnScreen+2(爆發傷害連觸掉落不得堆出接觸傷害牆; - 彈藥保證由 §26 飢荒立即補生承擔)。 -- 勝利結算窗防護(QA 根修):BOSS_DEFEATED 即授 i-frame(WIN_DELAY+2s)+ - PLAYER_DIED 於 bossDown 後直接忽略——殘餘 hazard(墜落中隕星/餘燼/潮汐)不得 - 奪走勝利(真實 e2e 抓出的競態)。 -- 呈現層(systems/voidra.ts):核心位置一律 approachPoint 逼近錨點(§64 慣例禁 - 絕對座標直寫;P1 中高懸浮/P2 升頂/過熱窗與 P3 下沉可打帶);魔王關體系沿用 - (前室 400px+星力果/疾風靴二選一;arena 增益 `arenaBuffPhase: 'p3'`——P2 為 - 生存段不投放,護盾泡延至 P3 高風險位)。 -- EX 差分:HP 沿 EX_MODS 共用 ×1.5=165(兩魔王既成慣例)、P2 轟炸密度 ×1.25、 - P3 螺旋三層;EX arena 增益不投放(§69 慣例)。 -- 補給:每損 10 HP 掉補給小怪(§26 飢荒保證律);L20 補生 jelly/floaty/glowy - 全可吸;P2 免傷帶內 waves 補給照常(彈藥為 P3 儲備)。 - -## 83. v12 魔王關專屬彩蛋與每關驗證 - -- **星核共鳴**(第七型觸發器 `survive-collect`):P2 生存段星屑 5 枚全收 → - full-magazine+星光謝幕演出(全屏金閃+星爆)。計數單一真值由 voidraFsm - `collectShard` 持有(沿 twin-finish/vent-hit-count 模式),滿 5 僅回報一次; - 段重試歸零重收。星屑收集判定沿 pickups 幾何慣例(AABB+水平掃掠,緩降至地面 - 帶後定點浮動可補收)。 -- 每關驗證(e2e v12.spec):v11 舊存檔載入五區分頁(L17 開放/L18·L20 迷霧)、 - L17 低重力全程地面通關(floorbot-lowgrav-landing 契約)、L18 預警圈→隕星→餘燼 - 可觀測+全程地面通關、L19 四機制終試全程地面通關(不用星門/噴口)、L20 三段 - 全流程(P2 免傷帶/過熱窗輸出/段起點重試/擊破→謝幕→Result→寫檔)。 - -## 84. v12 關卡 16→20 與全線收尾(levels.ts 資料驅動擴充) - -| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | -| --- | -------- | -------------- | ------------ | ---- | ------ | ------------------------------------------------------------------------------------------ | ---------------- | -| 17 | 星屑浮橋 | bg-astral | 3400 | 11 | 1350ms | 低重力 0.55 首發(§81)×Twinkla 亮相 | 星屑幽長 ×1 | -| 18 | 流星原野 | bg-meteorfield | 3700 | 13 | 1200ms | 流星雨首發(§79,4.5s×2)×低重力 0.55 | 彗核疾魚 ×1 | -| 19 | 星核前庭 | bg-starcourt | 4000 | 15 | 1000ms | 全機制終試(折躍+週期噴口+低重力 0.85+流星 5.2s×2);唯一六同屏;卡點三 checkpoint 2000 | 雙生鏡衛 ×2 同房 | -| 20 | 蝕星之心 | bg-voidcore | 854+前室400 | — | 2800ms | 最終魔王 Voidra(§82)+魔王關體系(§69) | — | - -- 曲線收束(主計畫 §4 CV-4):L17 緩衝 → L18 → L19 卡點三 → L20 全遊戲峰值; - 魔王 DPS 檢查點 Voidra 110 > Syrona 90。 -- L19 同房雙精英「雙生鏡衛」=20 關唯一變式:mirri ×2 同房近距(60px)雙門疊放 - ——兩具皆破才開門、60s 逾時保險各自有效(§48 全規則沿用);掉 glowy+zappy - 補凝光/追電配方。levels.test 豁免帶限定 L19。 -- 美術(主計畫 §9 v12 批 4 張,codex imagegen):`minion-twinkla`/`minion-cometa` - /`boss-voidra`(裁切球體佔比+q78 控預算)/`bg-astral-l`(1536×512 無縫, - 四關共用 grade 遞紫遞深:astral 淡紫 → meteorfield → starcourt → voidcore 深紫)。 -- **星光復甦謝幕**(CreditsScene):最終魔王關勝利(關卡鏈末端+魔王關資料驅動 - 判定,禁硬編關號)先播謝幕再進結算——星核金光脈動+星光上升粒子+製作名單 - 六段浮現(IP 安全全原創文案);任意點擊/ENTER 跳過、收尾冪等;播畢接 Result - 延續戰績資料。 -- 攻略 PoC: - - L17 最佳線:低重力大跳直上最高星橋速通+彩蛋。保底線:地面層恆連通,twinkla - 只在實體窗吸射。 - - L18 最佳線:星彈擊碎隕星保持節奏、追電星自動鎖 cometa。保底線:預警圈 0.8s - 純走位可躲(玩家縱帶恆排除),逐隻吸射推進。 - - L19 最佳線:凝光凍場過噴口鏈 → 折躍跳過流星走廊 → 雷形態鏈電雙殺鏡衛。 - 保底線:四機制段全有地面慢速路(各沿原區保底規則),死亡自 checkpoint 2000。 - - L20 最佳線:P2 風形態機動全收星屑 → P3 雷形態裂核大窗爆發。保底線:P2 零擊殺 - 純走位、P1/P3 讀 telegraph 打僵直/裂核窗,補給循環+段起點重試保障磨死。 - -## 85. v12.1 熱修:真實觸控下滑判定重修(補訂 §21/§23/§77) - -> §77 修復對「教科書式垂直長滑持住」有效,但真實拇指手勢(CDP 真觸控模擬實證) -> 四路全掛,生產回報「下滑+跳」仍不能下穿、蹲姿與琥珀鍵不出現。本章取代 §23 的 -> 下向判定與 §77.2 的指示觸發條件。 - -### 85.1 根因鏈(五情境真觸控探針實證) - -1. **底緣行程不足**:左手拇指自然定錨貼屏幕下緣,touchStart 後下滑物理行程僅剩 - 15-25px,舊閾值 30px(半徑一半)永遠達不到——蹲姿不出、鍵不變色、按跳變上跳。 -2. **flick 抬指**:真實手勢多為「滑完即抬指、數十至數百 ms 後按跳」;down 隨抬指 - 歸零,按跳瞬間已失去下向語意。 -3. **斜下滑帶走玩家**:拇指自然下滑常帶 ±20-45 度斜角,dx 分量觸發走路 - (220px/s)把玩家帶出平台邊緣;蹲姿因離地永遠到不了位。 - -### 85.2 修法(三點聯動,均有單測+真手勢 e2e) - -- **扇區+幅度判定**:`isJoyDown(dx, dy)` 改為 `dy ≥ 18px` 且向量在正下 ±60 度 - 扇區內(`|dx| ≤ dy·tan60°`);18px 高於死區(12)防誤觸、接住底緣短行程, - 扇區容納自然斜下滑、排除近水平走路語意。 -- **drop-intent 緩衝窗**:`advanceDownBuffer` 純函式維護 300ms 窗——down 釋放後 - 窗內 `downBuffered` 仍真;stage 下穿裁決(`shouldDropThrough`)與跳鍵琥珀指示 - (`isDropReady`)改吃 `downBuffered`,flick 後按跳仍判下跳。空中下砸 - (`resolveJumpPress`)維持即時 down,不吃緩衝窗防誤觸。 -- **蹲下鉗水平**:地面 down 成立即 `moveTarget=0`(平台遊戲蹲下靜止慣例), - 斜下滑不再把玩家帶出平台;空中不鉗,保留下砸前橫向微調。 - -### 85.3 真實手勢守門(e2e 常備) - -- CDP `Input.dispatchTouchEvent` 走瀏覽器觸控合成路徑(hit-testing、pointer - capture、多指分路全真),取代理想化 `dispatchEvent` 合成 pointer——防止未來 - 再以理想化輸入製造假綠燈。 -- 常備三變體:左手下滑持住+右手第二指點跳;flick 抬指停頓 150ms 再點跳; - 斜下 45 度滑動(斷言蹲住不位移+穿落成功)。 - -## 86. v13 EX 全魔王與星核制霸(EX 體系收尾+全制霸獎勵) - -> 20 關主線(v10-v12)完結後的 EX 收尾列車:把 v9 首發(§58 L4/L7)的 EX 變體 -> 體系補齊到全部 5 魔王,並為五王全制霸給一項有感獎勵。FSM 差分(EX_PRISMIX/ -> EX_SYRONA/EX_VOIDRA)與呈現層 ex 注入已隨 v10-v12 落地(§68/§74/§82), -> 本章收斂出貨面缺口與全制霸體系。 - -### 86.1 EX 差分總表(五王;HP 一律 EX_MODS ×1.5、節奏 ×1.15) - -| 魔王 | EX HP | 質變差分(每王一項,非純數值) | 反制語彙 | -| ----------- | ----- | --------------------------------------------------------------- | ------------------------ | -| 果凍王 L4 | 90 | 擊破分裂 3 小果凍(§58) | 保留彈藥收尾 | -| 蝠王 L7 | 78 | P3 月蝕彈幕矩陣(§58) | 讀缺口通道 | -| Prismix L12 | 120 | 雙子動作去同步(相位錯半拍 260ms;分裂 75%/掙扎窗 0.7s/盾 6) | 逐具讀招取代對稱背板 | -| Syrona L16 | 135 | 噴泉順序隨機化(每循環洗牌、seed 注入可測;潮汐再 -25%) | 讀 telegraph 取代背板 | -| Voidra L20 | 165 | P2 轟炸密度 ×1.25+P3 螺旋三層(愛心上限 1) | 走位風箏+過熱窗集中輸出 | - -(v24 取代標註:T6 EX 重設計於本表之上追加 EX 專屬 P4 第二血條——Prismix 已落地 -§114,Syrona/Voidra 於 W2/W3 落地。) - -### 86.2 出貨面收斂(本車實作) - -- **EX 徽鈕**:MapScene `addExEntrance` 自 §58 起即以 `level.boss` 通用掛載—— - L12/L16/L20 通關即出現,本車以 e2e 驗證收口(分頁地圖下三新王徽鈕全數可達)。 -- **exPending 提示**:改 `exConquestDone` 判定——L9 通關起提示,五王全制霸才消失 - (原 hardcode 只看 L4/L7)。 -- **EX 慈悲愛心上限**(主計畫 §7.4 補齊):`MERCY_HEAL.exMaxPerLife = 1`(一般 - 魔王房 2);Voidra P2 生存段固定愛心走獨立管線不計上限。 -- **EX 再戰保留**:`GameResultData.ex`——敗北結算「再戰魔王」與暫停「重新開始」 - 均保留變體模式;EX 擊破僅記 `exCleared` 星章,不動一般 cleared/bestTime(§58)。 -- **圖鑑紫星映射**:EX 星章補齊五王(原僅 L4/L7)。 - -### 86.3 星核制霸(全制霸獎勵,純呈現層 cosmetic) - -- 判定:`exConquestDone(save)`——`BOSS_LEVEL_IDS`(由 LEVELS 派生,禁第二份硬編 - 清單)全數 `exCleared === true`。 -- 獎勵(零平衡影響、零新素材): - - TitleScene:金色星噗噗換裝(金 tint)+金暈+「星核制霸」章。 - - CodexScene:圖鑑右上常設「星核制霸」金徽記(金星+金章)。 -- 裁決:Boss Rush 入口超出本車 timebox,落 backlog(主計畫 §11-7);cosmetic 案 - KISS 且與 §61 彩蛋紀律一致(不給永久成長)。 - -### 86.4 L4/L7 前室 retrofit(主計畫 §7.1 v11+ 擇機項,本車收掉) - -- 資料:L4 前室 400px+護盾/星力二選一+P2 疾風靴(沿 L12 攻壓型組合); - L7 前室 400px+護盾/疾風二選一+P2 星力果(空戰輸出窗短,沿 L16 語彙)。 -- 呈現層:stage elements 統一平移前室寬(與 decor 同語義「arena 相對座標」; - 走動關 xOffset=0 零影響)——L7 雙彈簧板資料座標不動、自動平移。 -- 全五魔王關前室體系一致性由 levels.test 資料驅動守門。 - -### 86.5 測試與保底實證 - -- vitest:exConquestDone/mercy EX 上限/L4·L7 前室一致性/EX 公平性下限 - (掙扎窗 ≥600ms、desync ≥200ms 且 < 最短 telegraph)四案新增。 -- e2e(v13.spec 七案):L12 EX 徽鈕全流程(HP 120 磨破寫 exCleared 不動 - bestTime)、L16/L20 EX smoke(HP 135/165)、星核制霸存檔三場景零錯誤、 - L4/L7 前室相機回歸網(入場運鏡後 scrollX 貼齊 anteroomPx、玩家恆在視窗內)、 - EX 中途退出防鎖、EX 敗北再戰(Result 保留變體重入 HP 120)、v9 世代舊存檔 - 相容(EX 紀錄保留)。 -- 保底實證(1200 寬 trace,`scripts/ex-bot-driver.mjs` 瀏覽器內 80ms tick - driver;EX 屬再戰內容、入場自願、可退出、不鎖主線進度): - - L16 EX 純標準星 **won 73.6s**(整場重試 1);L20 EX 純標準星 **won 129.8s** - (段重試 3 零卡關)——trace 存 `screenshots/starpuff-v13/`。 - - L12 EX 採**二段論**:輸出鏈 assist(受控 i-frame 隔離迴避軸)**won 30.8s** - 三階段擊破鏈完整無 DPS 死鎖;迴避軸由公平性下限單測(各招 telegraph - ≥500ms 不受 desync 侵蝕、掙扎窗 700ms)+純模式十輪 trace(最佳壓血 - 25/120、單輪最長 36.5s——輸出與存活各自成立)分別背書。規則 bot 的一維 - 決策(同 tick 僅一行為)在鏡像雙子去同步下組合不出全程,屬 bot 決策上限 - 而非已證實的設計軟鎖;人類具備並行操作與前室增益/變身資源(bot 自我設限 - 純標準星且不拾前室台座)。 -- 觀測點:`__sp.bossHazards()`(shockwave 型危害)+`__sp.enemyPositions()`+ - Prismix `getDebugState` 補齊(bot 讀招取樣);`__sp.gotoLevel(id, ex)` 支援 - EX 直達。 -- B1 修復(審查收斂):L4/L7 retrofit 初版漏掉 boss.ts/noctra.ts 呈現層的 - 世界座標平移(相機 pan/攻擊落點/投射物回收界皆以 0 為基準),入場運鏡把 - 相機拉回世界原點致玩家離屏——補 `arenaLeft` hook 注入(沿 prismix/syrona - 既有 pattern),全座標計算平移 arena 左緣;缺省 0 行為零變。 - -# v14 UX/PWA 列車:直持方向翻轉、控制自訂強化與安裝體驗(PM 派工) - -## 87. v14 直持預設旋轉方向翻轉(取代 §28 預設方向) - -### 87.1 背景與決策 - -- 使用者反映 v4–v13 的直持旋轉方向(cw:rotate 90deg、手機逆時針轉、鏡頭朝左) - 「沒有滿版的感覺、按鈕變成靠邊邊」;v14 翻轉預設為 ccw(rotate -90deg、 - 手機順時針轉、鏡頭朝右),瀏海側換至遊戲畫面右緣。 -- 方向與座標換算 SSOT 收斂至 `core/rotation.ts`:`ShellRotation`(none/cw/ccw) - 三態、`pointerToLocal` 統一逆變換(cw:localDx=screenDy、localDy=-screenDx; - ccw:localDx=-screenDy、localDy=screenDx);controls/keyConfig/shellLayout - 一律經本模組取向換算,禁止各自複製公式。 -- CSS:預設殼 `top:100%; left:0; rotate(-90deg)`(ccw);`html.sp-rot-cw` 切回 - 舊方向。safe-area 換軸表雙套:ccw=裝置 left→殼上、top→殼右、right→殼下、 - bottom→殼左;cw 維持 v4 原表。 -- 偏好持久化:localStorage `sp-rotation`('cw'|'ccw',缺省=ccw 新預設; - 不進 save schema);讀取走記憶體快取(pointer 熱路徑不重複讀 storage)。 - (v19 已由 §118.1 取代儲存位置:收斂為 `sp-settings.shellRotation`, - `null`=從未選擇;`sp-rotation` 僅作一次性 migration 來源,落盤後刪除。 - 記憶體快取語意不變。) - -### 87.2 回訪玩家保護(肌肉記憶) - -- 既有玩家(存檔有進度且未曾設定持向偏好——v19 §118.1 即 - `sp-settings.shellRotation === null`)首次進站於 Title 顯示一次性 - 方向告知卡(§92 殼層卡片):說明新方向並提供「切回舊方向」一鍵; - 已示記憶 localStorage `sp-rotation-notice`。全新玩家無感知不打擾。 -- 持向切換入口常駐「按鈕配置」操作列(§88),納入草稿語意:切換即時預覽、 - 儲存才落地、取消回滾。 - -### 87.3 驗證 - -- 座標矩陣單測(rotation.test.ts 九案):三態四角/中心/滑動向量映射斷言。 -- portrait e2e 雙案:ccw 新預設(上滑=往右)+持向偏好設為 cw 的舊方向回歸 - (下滑=往右、殼 matrix 斷言)。畫布覆蓋率 99.98% 不變。 - -### 87.4 方向解鎖引導+桌機正置(#817,T2) - -- 桌機判定(`detectDesktopEnvironment`,rotation.ts SSOT):`pointer:fine` 且 - `maxTouchPoints===0` 且視口寬 ≥1024——boot 一次判定掛 `html.sp-desktop` class - (session 內 SSOT,JS 與 CSS 恆一致)。 -- 桌機模式:方向恆正(`getShellRotation()` 恆 none+CSS 旋轉殼旁路)、虛擬鍵隱藏 - (鍵盤唯一操作面)、首次鍵位卡(← → 移動/Z 跳/X 吸射,記憶 `sp-desktop-keys`)、 - Title 常駐「操作說明」入口(`data-menu="keys"`)隨時重看。 -- 直持引導:卡片顯示當下仍為 portrait(延遲期間未轉橫=方向鎖定啟發式)→ 一次性 - shellCard「橫持遊玩體驗更佳(鏡頭朝右)」,記憶 `sp-orientation-hint` 不重複打擾; - 觸控裝置(含觸控筆電)恆不進桌機模式,旋轉殼語意保留。 -- e2e(t2.spec.ts 三情境 × 三 project):桌機(殼 transform none、#controls 隱藏、 - 鍵位卡一次性、鍵盤可操作)/直持未解鎖(提示卡一次性)/橫持(雙卡皆不誤觸)。 - -## 88. v14 按鈕配置頁操作列直欄化與標籤單行(取代 §34 操作列) - -- 根因:cfg-bar 橫排 flex 無寬度約束且鈕可壓縮,375/667 級殼寬下 - 「儲存並返回」被壓成兩行。 -- 修法:cfg-bar 直欄(提示列+操作列+縮放列分列)、`.cfg-btn` - `white-space:nowrap`+`flex-shrink:0`(禁字內斷行)、空間不足整鈕換列; - 「儲存並返回」精簡為「儲存」。 -- 驗收:854/1200 邏輯寬 × 直橫持 × 新舊持向矩陣全標籤單行(visualH=44)。 - -## 89. v14 虛擬鍵大小自訂(sp-key-layout schema v2) - -- schema v1→v2 versioned migration:v1 舊存檔鍵位保留、`scale` 補預設 1; - 未知版本回退預設。v2:`{version:2, a, b, scale}`,scale 夾限 0.8–1.3。 - (v19 已由 §118.1 取代儲存位置:**schema 形狀不變**,改存於 - `sp-settings.keyLayout` 子樹;`sp-key-layout` 僅作一次性 migration 來源。) -- 縮放經 CSS 變數 `--sp-key-scale` 單點驅動鍵體與鍵帽(clip-path 圖形同步), - 觸控熱區隨元素幾何自然同步;`KEY_BASE_PX`(A76/B72)與 style.css 以單測 - 跨檔守門防雙寫漂移。 -- 操作列縮放列:縮小/放大步進 5%+百分比顯示;即時預覽、儲存持久化、 - 取消回滾;與拖曳位置共存(夾限以縮放後 offsetWidth 計算)。 -- 觸控下限守門:最小縮放 80% 時最小鍵 57.6px ≥ 44px(單測)。 - -## 90. v14 PWA 安裝偵測與分平台指引 - -- 偵測矩陣(installGuide.ts,移植 RateWise 模式):platform - (ios/android/desktop/unknown,含 iPadOS 桌面模式 maxTouchPoints 辨識)、 - in-app browser(Threads/Barcelona、Messenger 先於 Facebook、Instagram、 - LINE、TikTok/musical_ly/trill、X)、已安裝雙訊號 - (display-mode standalone+navigator.standalone)。 -- 指引卡(§92 殼層卡片):iOS 分享→加入主畫面步驟;Android - beforeinstallprompt 一鍵安裝+選單步驟 fallback;in-app 引導外部瀏覽器開啟。 -- 出現邏輯:已安裝/已忽略(localStorage `sp-install-dismissed`,不進 save - schema)/桌面不打擾;首次到站延遲 2.5s 且僅 Title 安靜時刻顯示; - appinstalled 自動收卡並記憶。 - -## 91. v14 觸覺回饋與螢幕常亮(調研加碼,ROI 閘通過二項) - -- 觸覺(haptics.ts):查表跟隨 playSfx 觸發點——僅重擊/里程碑 - (hurt/slam-down/boss-slam/boss-roar/starstorm/win/lose)配短震(單段 - ≤100ms、總長 ≤200ms 守門單測);高頻一般音效不震防疲勞;靜音早退即同步 - 不震;iOS 無 Vibration API 靜默降級。 -- 螢幕常亮(wakeLock.ts):Screen Wake Lock 生命週期跟隨 `#controls.is-active` - (遊戲進行中取得、離場釋放、回前景重取);不支援或被拒(省電模式)靜默降級。 -- 落選(backlog):安裝後首啟引導(感知低)、豎屏提示動畫(與免轉向定位矛盾)、 - fullscreen API(iOS 不支援且與 standalone 重疊)。 - -## 92. v14 殼層卡片基建(shellCards.ts) - -- 安裝指引與方向告知共用:`whenShellIdle`(1s 輪詢)僅在 Title - (data-menu="start" 存在)且殼層安靜(無 controls is-active/is-configuring/ - pause-overlay/既有卡)時顯示——杜絕戰鬥中彈窗攔截操作。 -- 非模態頂緣左卡:overlay `pointer-events:none`、卡本體 `min(300px, 34%)` 寬、 - `max-height 72%`——不遮罩、不擋開始鈕與底部選單(320–844 五視口 AABB 零重疊 - 矩陣驗證);`aria-modal` 對話框語意+Escape 關閉。 -- 開玩自動收卡:MutationObserver 監聽 `#controls.is-active`,進遊戲即收 - (不記憶忽略,下次回 Title 再顯示)。 - -## 93. v14 殼局部 safe-area 量測(canvas 內 HUD 避讓預備) - -- `core/safeArea.ts`:讀 `#keys-layer` computed inset(CSS 已依 cw/ccw 換軸、 - 含地板值)→ 扣除地板取净 inset → 依邏輯寬/canvas CSS 寬換算邏輯 px; - 供 canvas 內 HUD(暫停/靜音鍵)避讓瀏海與 home indicator 接線。 - -## 94. v15 成就系統(logic/achievements.ts,純呈現層聚合) - -### 94.1 設計原則 - -- 成就 SSOT=`logic/achievements.ts` 單一資料表(id/名稱/描述/分類/隱藏與否/ - 判定函式),共 21 條;全部由既有 save 資料派生判定(`cleared`/`bestTimeMs`/ - `eggsFound`/`exCleared`),**禁止侵入式遊戲邏輯鉤子**——evaluator 讀 save 即得 - 已解鎖集合,遊戲熱路徑零新增寫入點。 -- 魔王條目(五王首勝+五王 EX)由 `LEVELS` 派生(沿 §86 `BOSS_LEVEL_IDS` 慣例, - 禁第二份硬編清單);命名表以 `Record` 鍵定,加王時型別強制補名。 - 隱藏成就對應關卡由彩蛋觸發器反查 LEVELS,彩蛋總數同樣派生。 -- 分類五種:進度(首關/全 20 關)、魔王(各王首勝/EX 各王/星核制霸——與 §86 - `exConquestDone` 同源判定)、收集(彩蛋 1/10/全收)、技巧(任一魔王關 - 120s/60s 內通關,門檻依 v13 bot trace 證據校準)、隱藏(三個魔王專屬彩蛋: - 雙子連破/窯風三連/星核共鳴,未解鎖顯示「???」)。 -- 玩法類(九系星彈全用過/星化三形態)裁決不做:save 無 flavor/form 使用紀錄, - 為此擴 save 需熱路徑攔截非極低成本,違反本章零侵入原則。 - -### 94.2 存檔 schema v2 與補發(versioned migration) - -- `SaveData.achievements: string[]`=已頒發成就 id——**toast 去重基準**,頒發紀錄 - 不可逆(資料回退不移除);解鎖「顯示」恆由 save 即時派生,stored 只管去重。 -- `SAVE_SCHEMA_VERSION` 升 2:`parseSave` 接受 v1(v9–v14 世代)與 v2——v1 缺 - achievements 補空集後照常收斂條目,**禁 discard**;寫出恆為 v2。 -- 補發單點=main.ts 開機:`awardAchievements(loadSave())` 依既有資料靜默補發 - 歷史成就(無 toast 轟炸),有增量才落盤(全新玩家不預建存檔);版本更新新增 - 成就同走此路自動補發。 - -### 94.3 呈現三層(解鎖不漏看) - -- 遊戲內 toast:GameScene `persistAndAward` 單點(彩蛋/通關/EX 三個存檔寫入點 - 寫後評估增量)→ **同批多解鎖合併單張橫幅**(頓號串接,勝利轉場 2.8s 窗口內必可 - 播完整批)、跨批序列佇列不重疊(約 2.1s/張);金色橫幅帶深色底襯(勝利白閃下 - 仍可讀),禁全屏遮罩;e2e 觀測點 `__sp.achievementToast()`(canvas 文字不可由 - DOM 查詢)。轉場即隨場景銷毀,由下兩層兜底。 -- 結算名單:`GameResultData.unlocked`(additive optional)帶本局勝利瞬間新頒發 - id 進 Result 金底列示(Credits 轉接保留)——魔王擊破多重解鎖不因 WIN_DELAY - 轉場漏看;敗北局內解鎖的彩蛋成就同樣如實列出。 -- 成就頁:CodexScene 第三分頁(`CodexTab` 加 'achievements',分頁鈕等距展開); - 6 欄徽章網格(fx-star tint+圓底程序繪製,零新圖)、已解鎖亮金微轉動/未解鎖 - 灰、隱藏未解鎖名稱「???」描述「隱藏成就」、右上「解鎖 n/21」計數; - 網格與計數依 §93 净 inset 收縮(854/1200/直持 390×844 三視口驗證)。 - -### 94.4 驗證 - -- 單測 achievements.test.ts:資料表不變式(id 唯一/21 條/boss 覆蓋派生守門)、 - 全類別邊界(19/20、4/5 EX、彩蛋 9/10、速通 120000/120001 與 0 不計)、 - awardAchievements 冪等與增量、v9–v14 各世代舊存檔載入補發精確集合。 -- 實測 scripts/v15-verify.mjs 五幕:v1 滿進度開機補發 21 條+schema 升 v2、 - 真實擊破管線多重解鎖(toast+Result 名單)、854/1200/直持成就頁、 - console error 全程 0。 - -# v16 產品缺陷修復列車:三席批評收斂(PM 派工) - -## 95. v16 直持預設鍵位重錨(D1,取代 §34 預設在直持殼的適用性) - -### 95.1 根因與決策 - -- 三席批評(Grok 席,PM 數學覆核成立):§34 預設鍵位以 keys-layer 層比例定義 - (A 0.92/0.78、B 0.92/0.34),直橫持共用;直持旋轉殼下層座標軸與裝置軸互換, - 同組比例把 A/B 映射到裝置螢幕頂端(實測 A 裝置 y≈78px、fy≈0.09),雙拇指 - 直握不可及——v14 只修了搖桿半邊(左半屏映射到裝置下半),按鍵半邊漏修。 -- 修法:預設分流、自訂不動。新增裝置比例錨點 SSOT `PORTRAIT_THUMB_ANCHORS` - (A fx 0.82/fy 0.86、B fx 0.80/fy 0.68——右下拇指帶、B 沿拇指弧在 A 上方), - `defaultLayoutFor(rotation)` 依殼向反算層比例:ccw cx=1−fy、cy=fx; - cw cx=fy、cy=1−fx(§87 軸向映射逆向);橫持沿用 v14 定案。 -- schema 不動(鍵位布局 v2 零遷移,§89):合法自訂資料在任何持向原樣適用; - 只有「無自訂/損毀回退」與「恢復預設」走旋轉感知預設。 -- 直持下 A/B 幾何上與 joy-zone 重疊(裝置下半即遊戲左半):keys-layer 為後繪 - 兄弟層,按鍵天然承接命中;誤觸空白處僅錨定浮動搖桿(點按零位移,無害)。 - -### 95.2 儲存語意(配置頁) - -- 預設態不落盤:從未自訂或按過「恢復預設」後儲存=清除布局(v19 §118.1: - `sp-settings.keyLayout` 置 null,v14–v18 為清除 `sp-key-layout` 鍵,語意等價), - 直橫持各自動態解析預設;拖曳/縮放屬自訂,儲存持久化具體布局(維持 v14 - 單一共用布局語意)。 -- 「恢復預設」依當前草稿持向給對的錨點;持向切換(cw/ccw)時預設態即時重映射, - 自訂布局不動;拖曳逆變換取草稿持向(修正切換未儲存期間軸向錯置)。 -- 局中轉向重套:controls 進場後監聽 resize(200ms)/orientationchange(400ms) - 重新解析布局,orientation 切換不殘留舊向預設。 -- CSS fallback 鏡像:style.css portrait 區塊鏡像反算值(14/82、32/80;cw - 86/18、68/20),JS 載入前鍵位即在拇指帶;單測跨檔守門防雙寫漂移。 - -### 95.3 驗證 - -- 單測 layout.test.ts:前向模擬(層比例→殼→裝置座標,390×844 含 inset)斷言 - cw/ccw 雙向 A/B 落帶、AB 裝置距離 ≥90px、夾限相容、錨點反算一致性、 - 深拷貝、CSS 鏡像;parseLayout 旋轉感知回退與 v1/v2 自訂資料不受旋轉影響。 -- e2e portrait.spec.ts:D1 案——幾何斷言(A fx≥0.72/fy 0.78–0.95、B 上方帶)+ - 真手勢(CDP dispatchTouchEvent 走瀏覽器 hit-test)點 A 起跳(walk().vy<0)、 - 點 B 進入按壓態;cw 舊方向案補同帶幾何斷言。 -- 前後對照截圖 screenshots/starpuff-v16/d1-\*.png(before A fy 0.092 → after 0.850)。 - -## 96. v16 圖鑑分頁有界網格(P1-01,取代 §36 技能雙欄與 §94.3 成就網格常數) - -- 根因(Sonnet 席數學實證):技能分頁雙欄 5 列(y=122+⌊i/2⌋×84)第 9 項 - y=458、說明底緣 486 超出邏輯畫布 480;內容卡背景亦僅至 457。 -- 修法:`core/gridLayout.ts` 有界網格純函式——可容列數由縱向預算推導 - (floor((maxY−itemH−startY)/rowH)+1,至少 1)、欄隨量增(仿 §76 固定列 - 策略);分頁參數收斂 `core/codex.ts` CODEX_TAB_GRIDS 單點(技能 - 122/100/90、成就 112/90/84,maxY 一律 470)。 -- 技能分頁 3 欄 3 列:操作方式緊隨名稱動態排列(非固定 96px 偏移,最窄格 - 不越格)、詳述 12px 逐字換行;成就分頁接同一工具(21 條維持 6 欄 4 列 - 零視覺變化),條目成長自動擴欄不溢出。 -- 守門單測 gridLayout.test.ts:任何分頁內容不得超出 y=470(含技能 12 項/ - 成就 30 條成長情境)、技能文案長度上限(詳述 ≤72 字)、CodexScene 引用 - SSOT 跨檔守門(禁第二份網格常數)。 - -## 97. v16 區/關命名層級標示(F-01 裁決) - -- 三席批評(Composer 席):地圖同屏「果凍平原」(區頁籤/標頭)與「果凍草原」 - (L1 節點)近義並列,讀感如命名漂移。 -- PM 裁決維持層級差:區=地域(果凍平原/天風峽域/…)、關=景點(果凍草原/ - 翔風峽谷/…),全五區皆同構,統一反而使 L1 與區 1 撞名。 -- 消除認知分裂:地圖標頭前綴「第 N 區」(`第 1 區 果凍平原・彩蛋 x/y`)、 - 區頁籤 aria「前往第 N 區 ○○」、節點 aria「進入第 N 關 ○○」——視覺與讀屏 - 同義:頁籤/標頭=區域、節點=關卡。 -- 資料面守門(zones.test.ts):區名不得與任何在編關名撞名。 - -## 98. v16 選單 DOM 鈕命中短邊保底(D2,補充 §33 條目 7) - -- 根因(Grok 席):DOM 鈕以邏輯尺寸 × canvas 縮放直出 CSS 尺寸;直持 390×844 - 殼縮放 ×0.812 把次選單 56 邏輯高壓到 45.5 CSS px(低於 HIG 44pt 帶餘裕的 - 48px 基準),主 CTA 72→58.5 尚可但無守門。 -- 修法:`core/domButton.ts` `menuHitCssRect` 純函式——命中短邊 48px 保底、 - 對稱擴張(中心不漂移、視覺不變);`hud.ts addDomButton` relayout 一律經此 - 換算(Title/Map/Codex/Result 全場景 DOM 鈕自動受益)。 -- 驗證:domButton.test.ts 量測單測(直持縮放矩陣全鈕 ≥48、已達標邊不放大、 - 中心對稱、未縮放殼同樣吃下限);portrait e2e 於 Title 實測五顆選單鈕 - AABB 短邊 ≥48。 - -## 99. v16 版本頁腳 SHA 來源修正(F-02,補充 §42) - -- 根因(Composer 席):Zeabur Docker build 提供 GIT_COMMIT_HASH build arg 但 - context 無 .git,starpuff 版本解析僅呼叫 git 指令,落 nogit 佔位並露出於 - production 頁腳(v0.14.0+nogit)。 -- 修法:SHA 來源優先序 GIT_COMMIT_HASH env(repo Docker 慣例,同 ratewise) - → 本地 git → 皆缺省略後綴(乾淨 vX.Y.Z,不再露佔位字樣)。 -- 後續修正(2026-07-26,取代上列來源優先序):`.dockerignore` 排除 `.git`,Zeabur 建置 - 容器內 git 指令必失敗,且平台不提供 `GIT_COMMIT_HASH`——production 恆落純 - `vX.Y.Z`,同版號兩次部署無鑑別力。改以 Zeabur 建置階段內建特殊變數 - `ZEABUR_GIT_COMMIT_SHA` 為首選來源(Dockerfile builder 段宣告 ARG 才會注入), - 來源鏈收斂於 `scripts/lib/build-commit-sha.mjs`(跨 app SSOT): - ZEABUR_GIT_COMMIT_SHA → GIT_COMMIT_HASH → git rev-parse → 省略後綴。 - -## 100. v16 勝利結算「下一關」主 CTA(D3,取代 §39 勝利回地圖單一動線) - -- 根因(Grok 席):魔王關擊破後結算僅「世界地圖」,接續遊玩需地圖折返一次, - 斷了闖關節奏。 -- 修法:一般勝利雙鈕——主 CTA「下一關」(nextLevelId 資料驅動,直入下一區 - 首關)+「世界地圖」降次選;ENTER 對應主 CTA。Result 勝利僅魔王關觸發 - (走動關經星星門直進地圖揭霧),L20 全破走謝幕不經 Result,故一般勝利必有 - 下一關(資料防禦仍回退地圖)。EX 勝利與敗北動線不變(再戰 EX/再戰魔王)。 -- 驗證:v16 e2e——L4 擊破後 next-level 直入 L5、map 次選並存;smoke 勝利案 - 改走 map 次選鈕。 - -## 101. v16 HUD 暫停/靜音 DOM 化(F-06+D4,取代 §35 暫停鍵與修復包 B 靜音鈕的命中層) - -- 根因(Composer/Grok/Sonnet 三席交集):局內暫停/靜音為 canvas 熱區—— - 自動化不可達、讀屏不可見,旋轉殼下依賴 transformPointer 補償。 -- 修法:命中改由同位 DOM 鈕承接(`addDomButton` 支援 rect getter 隨視寬/inset - 動態錨定,data-menu=pause/mute+aria-label;靜音帶 aria-pressed 狀態), - canvas 圖示保留純視覺、移除 interactive(沿 recon-v4 A.3 單一命中路徑); - `pause.ts addButton` 補 aria-label。 -- 命中尺寸:邏輯 44×44 經 §98 短邊 48px 保底,直橫持皆達標。 -- 驗證:v16 e2e(暫停開選單真凍結→繼續、靜音 aria-pressed 與靜音偏好同步 - 翻轉——v19 §118.1 後偏好真值為 `sp-settings.audioMuted`);portrait e2e - 真觸控點暫停即凍結、pause/mute AABB 短邊 ≥48。 - -## 102. v16 配置模式遮罩加深(F-04,補充 §34) - -- 根因(Composer 席):cfg-overlay 0.4 透明度下主選單文字仍清晰,與配置列 - 形成「哪層可互動」的視覺競爭。 -- 修法:遮罩加深至 0.62+backdrop 輕模糊 2px——主選單退為背景;虛擬鍵與 - 操作列(z 10/40)浮於遮罩(z 5)之上不受影響。 - -## 103. v16 標題字形品牌化(D6,補充 §36) - -- 根因(Grok 席):主標 system-ui 純白字+單層描邊,讀感是「預設字體」而非 - 品牌 logo。 -- 修法(零新字型檔):雙層字形——底層深紫厚描邊(stroke 12)下沉 5px 造 - 糖果貼紙立體感;頂層白字帶垂直粉漸層 tint(四角 tint 上白下粉)+柔影 - (blur 6)+細紫描邊;副標 StarPuff 加粗+白描邊。禁重依賴(不引字型檔)。 - -## 104. v16 怪物圖鑑分頁(F-03,取代 §76 單頁定案) - -- 根因(Composer 席):23 隻 × 12 欄 2 列——854 最窄殼 cellW 67px、行為敘述 - 4-5 字/行,直持過密難讀(§76 當年以 18 格評估的 cellW≈89 已被 v12 圖鑑 - 補完擠破)。(v17 訂正:CODEX_MONSTERS 實為 23 隻(12+11),原文 24 為 - 敘述失準;ceil 分頁斷言不受影響。) -- 修法:接 §96 有界網格——每頁 12 格 6×2(MONSTER_PAGE_SIZE,cellW 回到 - 134+),底緣「上一頁/第 n/N 頁/下一頁」翻頁列(restart 帶 monsterPage, - 沿分頁切換慣例;單頁不顯示);頁序沿 CODEX_MONSTERS,未來新增怪自動增頁。 -- 驗證:gridLayout 守門(每頁 6×2 ≤470、23 隻恰兩頁);v16 e2e 翻頁雙向; - 854/1200/直持截圖對照。 - -## 105. v16 前期節奏保守調參(D5+F-05,補充 §15 教學關與 §48 精英房) - -- 三席批評:L1 教學配額與死亡懲罰偏挫折(Grok -3)、L2 精英軟鎖門「卡住感」 - (Grok/Composer)——門柱無任何文字說明,60s 保險存在但玩家不知情。 -- 保守裁決(禁大改平衡): - - 教學關死亡配額結轉:僅 tutorial 關(L1)死亡重試保留一半擊殺數 - (floor(kills/2)、夾限至配額-1 不可能帶開門態重生);其餘關卡維持全重置, - 卡點關 checkpoint 路徑(§67)本就不重啟不受影響。實作: - `carryKillsOnDeath`(logic/levels.ts 純函式)+ waves runner initialKills - 種子+重生即補發 LEVEL_QUOTA 現值(既有事件,無契約變更)。 - - 精英門提示:門柱旁世界座標浮字「擊敗精英開門/60 秒後自動開啟」—— - 明示破關條件與保險,等待也是合法出路;開門隨門柱淡出。零平衡影響。 - - 不做項:L1 配額量/生成節奏調整(教學關幾乎不死的原設計仍成立,動供給 - 曲線風險大於收益);L2 精英數值調整(60s 保險+提示已消解卡住感)。 -- 驗證:levels 單測(結轉夾限/非教學歸零/種子推進);v16 e2e 真實戰鬥管線 - 擊殺 4 隻→死亡→重生 2/6;v7 精英房回歸全綠。 - -# v17 債務列車:行為零改變維護性收斂(PM 派工) - -## 106. GameScene strangler 拆解與守門(三席維護性 5/7/8 收斂) - -### 106.1 拆解記錄(行為零改變) - -- 性質:純維護性重構——玩法、數值、視覺、事件順序、存檔語意一律不動; - events 契約凍結(§11),本車為其補契約測試而非修改。 -- GameScene 2121 → 1196 行,職責收斂為一句話:orchestration+scene lifecycle - (create 接線、update 逐幀委派、事件路由、勝敗轉場、e2e 鉤子面)。 -- 六個抽取單元(每步先補 characterization test 鎖行為,全測綠才 commit, - 獨立可 revert): - - `systems/bossFactory`:魔王品種分派(never 守衛)、補給小怪節奏、召喚夾限。 - - `systems/starCombat`:星彈規格解析單一出口+技能世界結算(星暴/下衝擊/ - 殼盾反擊/鏈電束/風化落地/雷鏈/凍結場/爆裂波及)。 - - `systems/starSteering`:準星輔助/追電導引/磁場吸偏/拖尾附掛(導向順序凍結)。 - - `systems/overlaps`:戰鬥碰撞接線(接線順序凍結;damagePlayer/damageBossAt - 單一入口不變)。 - - `systems/eggTracker`:彩蛋進度鎖存/逐幀餵送/獎勵落地/crown 時間窗。 - - `systems/toasts`:成就 toast 佇列/星味首遇提示/彩蛋慶祝演出。 -- 新增測試:GameEvents 契約測試(事件名唯一、emit/on/off 對偶、FSM phase - 恰一次、waves 序列)+六模組 characterization——vitest 580 → 650。 -- ESLint 守門:apps/starpuff 範圍 `max-lines` error 1200(levels.ts 資料表 - 豁免),防 GameScene 再膨脹。 - -### 106.2 觀察項設計理由註記(不動行為) - -- 直持 joy-zone 幾何包住 A/B(Grok 席 v16 觀察項):維持 §95 設計定案—— - keys-layer 為後繪兄弟層天然承接命中,誤觸空白處僅零位移搖桿錨定(無害)。 - 若未來要消「右拇指邊緣偶發搖桿錨定」感,方向為 joy-zone 右緣排除鍵命中區; - 本車行為零改變原則下不動。 -- 教學關死亡結轉讀值時窗(§105 D5):retryLevel 於 350ms 延遲回呼讀取配額, - 理論上飛行中星彈可多算 1 殺——carryKillsOnDeath 夾限(≤配額-1)保證無害 - 且恆有利玩家,屬既有設計定案,不加鎖存。 - ---- - -# v18 修復列車:全 20 關實測回饋三修(PM 派工) - -## 107. 走動關供給保證與滿潮平衡(issue #804/#805/#806) - -> 出處:全 20 關實測攻略工(PR #802)回報三缺陷;量測工具 `scripts/v18-level-bot.mjs` -> (play/idle/stall/forage 四模式,真實鍵盤事件、不用受控賦星),前後數據 -> `screenshots/starpuff-v18/*.json`。 - -### 107.1 走動關飢荒救援律(#804,P1;擴充 §26) - -- 根因:「飢荒立即補生」保證律只在 `level.boss` 分支生效;走動關同屏上限(5)被 - 紮根/不可吸個體(chompy、spora、精英本體)佔滿時生成器停轉,玩家零彈陷入 - 「無彈、無可吸怪、無新生成」軟僵局——唯一自救是下砸,違反 anti-softlock - 「基礎星彈恆可通關」精神。 -- 修法(`logic/levels.ts`):`STARVATION_RESCUE_MS = 4000`——零彈且同屏無可吸怪 - 持續 4s → 強制補生可吸怪(**無視同屏上限**;品種沿 §26 `pickSpawnKind` 飢荒 - 覆蓋,僅自恆可吸子集抽選)。飢荒中斷歸零重計;開門後不救援;魔王關維持 - 立即補生分支(bossFactory 契約零漂移)。 -- 閾值設計:4000ms 長於全部走動關 `spawnIntervalMs`(1000–2600)——一般節流仍是 - 主要供給路徑,救援僅在停轉時兜底;同屏可短暫超編 +1,可吸怪被消化即回落。 -- bot 實證(stall 模式:官方 spawn 鉤子填滿 5 隻 chompy+零彈掛機 90s): - - 修復前:L3 停轉 87.8s、L5 停轉 89.9s(全窗凍結,重現軟僵局)。 - - 修復後:L3 最長停轉 3.4s(複測 3.9s)、L5 4.2s(救援閾值內必出可吸怪)。 - - 有機重現(L3 play 420s):修復前最長飢荒 293.4s(bot 卡死)→ 修復後 2.7s、 - 配額 210.8s 開門(複測 3.5s,全部走動關 play 複測飢荒窗 ≤3.5s); - L3/L5 idle 掛機 300s 最長飢荒 1.2s/1.4s。 - -### 107.1.1 救援可及性保證(#812,T2;擴充 §107.1) - -- 根因:§107.1 只保證「生成」不保證「可及」——救援自視野外側入場(~1 屏外)、 - 名義可吸但不可及個體(高空 gusty/遠端威脅型)阻斷飢荒計時,星暴誤放後 - 恢復 p50 5.5s/p95 19.9s、45s 未恢復 16 次(T1 基線)。 -- 修法(waves.ts+levels.ts 最小增量,不動 §107.1 觸發閾值): - - 生成位:玩家前方 100–150px 吸入錐內(`rescueSpawnX`,站定面向即可吸、漂移型 - 品種不逃錐;越界/尾端安全區改後方等距);懸浮定高品種降至站立錐可及帶 - y=300;潮汐上收沿 adjustSpawn(同層可達)。 - - 品種:恆可吸 ∩ 低威脅(safe)優先(`pickRescueKind`);滿潮排除位移壓迫型 - (gusty 側風);無 safe 候選回落恆可吸全集(anti-softlock 優先)。 - - 單席+逾時重定位:場上救援個體上限 1;5s 未取得重定位到玩家身旁 - (恢復機構上限=觸發 4s+窗 5s+取得 ≈ p95 門檻對齊)。 - - 飢荒判定改可及性口徑:走動關僅計「近域 400px 內、可及頂線 y≥280、非 ranged - 威脅型」可吸個體——視野外、高空定飄(需跳拍追擊)或遠端威脅型(零彈追擊 - 高成本)均不阻斷救援計時;魔王關單屏維持全域計數。 - - 救援個體近域豁免律(審查收斂):無 safe 候選關(L14 全 ranged mix)的救援怪 - 會被 ranged 過濾排除——救援存活且近域即視為供給恢復候補、解除飢荒計時, - 否則「生成→不計→4s 再觸發」重定位循環自我否定;被消化後追蹤釋放、計時恢復。 -- 工具實測(starburst 探針、mid bot、全 15 走動關 × 6 樣本=90):45s 未恢復 - 16→0(爆炸輪根除)、全域 p95 19.9→9.5s(≤10s 門檻達成)、p50 4.6s。殘餘 >10s - 樣本 4/90:L10 ×2(10.2/10.5s)、L15 ×1(11.5s)、L14 ×1(21.3s,滿潮相位 - 避難+bot 受擊循環窗)——原始 JSON 全數留檔 `.claude/product-intel/level-audits/ -t2b-812-sb-l*.json`。 - -### 107.1.2 L14 星暴恢復重尾根除(#841,T7;擴充 §107.1.1) - -- 逐幀驗屍(兩輪共 7 個 >10s 樣本、100ms 全敵座標+潮汐相位遙測)鎖定三機制: - 1. 紮根怪穿地:immovable 動態體與靜態地面不做分離——spora/chompy 生成即沉至 - 世界底(y≈462,全關卡皆然);L14 救援 spora 因此埋地不可及,§107.1.1 的 - rescueNear 豁免律又抑制新救援、5s 重定位再埋,為重尾主因。修法:解除 - setImmovable(紮根語意由更新迴圈不賦速維持;敵人唯一 collider 即 vs 地面, - 該旗標無保護對象)。 - 2. 滿潮救援沉水:不變式 17 上收僅保護無重力品種——重力型救援滿潮期必落回 - 水下主地面,平台層避難玩家構不到、等退潮即成殘尾。修法(機制級泛化): - 所有「潮汐關+有平台」的滿潮救援一律錨定最近平台頂(固定紮根 spora+ - 關重力,比照 bubbla「生成 y 即錨點」慣例;救援路徑本就覆寫品種,不依賴 - 關卡表含 spora——L14/L15 同享);退潮/無平台關維持既有路徑。 - 3. 貼身錐形死角軌道:追擊過衝站上 splatta/spora(dx≈0)時 45° 錐形必敗、 - 不拉不吞,反覆繞軌 3-8s。修法:§107.1.1 殼殼貼身豁免泛化為全可吸品種 - (INHALE_NEAR_PX=60 近域圈 face-agnostic;#844 候選 zone 反向帶已對齊)。 -- 工具實測(starburst 探針、mid bot):L14 基線 p95 18.9s(3/10 超標)→ 修後 - 官方 ×10 p95 5.0s、驗屍 ×14 p95 4.6s、逐關批 ×6 p95 5.2s;全域 15 走動關 - ×6=90 樣本 p95 9.3s(§107.1.1 基線 9.5s 不回退)、45s 未恢復 0。原始 JSON - 留檔 `841-fix-l14.json`/`841-global-l*.json`。 - -### 107.2 L5 供給節奏調參(#805,P2;補充 §52) - -- 根因:L5 缺「主動接近玩家」的供給怪——gusty 於生成點高空盤旋(drift 錨定 - y≈220,玩家不入 200px 觸發域即永不俯衝)、spora 遠處紮根,兩者名義可吸但 - 不可及(合計 50%),佔滿同屏後地面帶供給真空;唯一追蹤型供給 jelly 僅 15%。 - 掛機探針實錄:兩隻 gusty 停在 x≈1160–1290 全程 120s 不移動。 -- 修法(資料單點,`levels.ts` L5 enemyMix):gusty 30→25%、spora 20→15%, - 讓渡地面帶 jelly/floaty 各 +5%——駐留型假供給 50%→40%、可及供給 30%→40%; - 可吸佔比 0.8 不變、gusty 主場(≥25%)契約維持、spiky 威脅面 20% 不變。 -- 巡航高度 lever 否決記錄:收割微測(gusty 單體,走近+跳躍吸入 ×6)y=220 與 - y=240 平均收割耗時同為 1.1s——高度動全域五關(L5/L6/L9/L14/L18)卻無主動 - 收割收益,選 level-scoped mix 調參。 -- bot 前後(forage 錨定量測:x=1400 定點吃怪換血、滿匣傾瀉、精英隔離,300s; - 指標=最長彈藥斷檔,>60s 計爆炸輪)——三批次全樣本 provenance,量測 JSON - 全數留存 `screenshots/starpuff-v18/`: - - | 批次(時序) | 組態歸屬 | 各輪(s) | 中位 | 平均 | 最大 | 爆炸輪 | - | ------------------- | ------------------------------------------------------------------------------------------- | -------------------------- | ---- | ---- | ----- | ------ | - | oldmix ×2+base2 ×3 | 舊 mix(base2 為回到 HEAD 重測基準) | 9.0/10.1/5.4/1.0/229.5 | 9.0 | 51.0 | 229.5 | 1/5 | - | newmix ×4 | 不可考——量測期間工作樹來回切換、未逐一 commit,JSON 無組態指紋欄;時序上為第一候選 mix 量測 | 16.7/1.2/5.4/236.7 | 11.1 | 65.0 | 236.7 | 1/4 | - | fix2 ×3 | 新 mix(09410c71 版 levels.ts) | 193.6/2.9/3.4 | 3.4 | 66.6 | 193.6 | 1/3 | - -- 誠實結論(全樣本口徑,取代早期僅列基準+fix2 的選擇性敘述): - - 基準側 base2-r3=229.5s 證明爆炸輪為舊 mix 既有尾部行為,非新 mix 引入。 - - 最對抗性合併口徑(newmix+fix2 全 7 輪)中位 5.4s,仍優於 L6 鄰關對照 - 29.9s——#805「回落至鄰關水準」驗收以中位數口徑成立。 - - 爆炸輪率未改善(基準 1/5 vs 合併 2/7):尾部凍結組態與 mix 調參無關, - 收斂歸 issue #812。 - - idle 中場站定複測 reach 真空最長 1.8s(<30s 門檻)。 -- 已知缺口(#812,誠實聲明):爆炸輪=同屏 5 席被「名義可吸但不可及」個體 - (高空 gusty/遠端 spora)佔滿且 bot 不跳吸、不下砸、不死亡的凍結組態。 - gusty/spora 屬 `canInhale` 真值集,佔滿時 `aliveInhalableCount > 0`—— - §107.1 救援律僅在「同屏零可吸」成立時觸發,此凍結組態**不在其涵蓋範圍**, - 無系統面兜底;可及性保證歸 issue #812(T2 修復列車:救援供給改可及性口徑)。 - 真人玩家走近 gusty 觸發域即誘導俯衝、走向 spora 即可吸,bot 固定策略不做 - 此補償。mix 內合法調參空間已用盡(gusty 主場 ≥25% 契約),若需再收斂需 - PM 裁決放寬主場契約或引入駐留型個體同屏壽命機制。 -- 三軸不倒掛:D 軸威脅面不變(spiky 0.2、gusty 俯衝機制不動,僅密度 -5pt)、 - M/P 軸不動——L5 3.2 分持平或微降,CV-1(L5 < L6 4.4)與 CV-3(L5 < L4 3.6) - 均成立。 - -### 107.3 L14 滿潮死亡螺旋雙修(#806,P2;補充 §71) - -- 根因:滿潮期主地面淹沒(漲頂 352 < 地面頂 400),被擊退落水後「浸水扣血 - (每 1.5s i-frame 到期即再扣)+水平強緩速 60px/s 掙扎」;同時漲潮期生成上收 - (交叉不變式 17)把新怪全堆到平台層,避難點擁擠、splatta 拋物壓制。 - 死因取樣:修復前 L14 bot 死亡 56% 發生於 flood 相位窗。 -- 修法一(浸水甦醒無敵,`logic/tide.ts`):浸水受擊「實際掉血」→ 授予 - 基礎受擊 i-frame(1500ms)+甦醒追加窗 `soakWakeInvulnMs = 1000`(沿 - `grantInvulnerability` 取 max 語意)——總保護 2.5s 涵蓋「浮出水面+跳回平台層」 - 重站位;未掉血(i-frame 期/護盾格擋)不追加,杜絕無成本刷無敵。 - enemy 接觸傷不變;Syrona P2/P3 潮汐同規則受益。 -- 修法二(滿潮生成降載,`floodHold`):滿潮(flood 相位)暫停走動關一般補生 - ——計時照走、凍在滿格,退潮首 tick 即刻補回,總供給節奏近似不變、只是 - 錯開滿潮窗;**飢荒救援(§107.1)與魔王關供給不受閘**(anti-softlock 優先, - Syrona 供彈節奏零漂移,契約測試守門)。 -- 修法一單獨實測:平均死亡循環 37.2s → 44.8/43.6s(存活 +20%)但總死亡未顯著 - 回落(25/28 → 24/24)——螺旋另一半是滿潮平台層擁擠,故加修法二成組合拳。 -- bot 前後(play 420s,基準 5 輪 vs 組合拳 4 輪):總死亡 27.0 均(25/28/28/ - 27/27)→ 21.3 均(20/22/22/20),-21%(區間無重疊);平均死亡間隔 - 15.2s → 19.6s,+28.8%(≥25% 門檻);L6 對照 play 死亡 21.5 均 → 19.5 均、 - L13 對照 0-1 死且 76.7s 開門(基準 4 死未開門),對照組零惡化。 -- 退潮生成尖峰驗證:idle 乾淨儀器(不推進、不跨精英線、授長無敵)300s 33 次 - flood 結束轉換,滿潮內生成 0、轉換後 1s 窗增量 >1 者 0——floodHold 釋放 - 無 burst(退潮首 tick 恰 +1)。play 口徑偶見同窗 +2 樣本,經驗屍為 - 「held 釋放 +1 疊加跨精英觸發線生成 +1」巧合,非生成器 burst。 -- 獨立核實欄(審查收斂補測):bot idle 輸出新增 `floodSpawns`(flood 相位內 - alive 總數逐 tick 上升量);複測 `post2-l14-idle.json` 300s 32 次 flood - 結束轉換、`floodSpawns: 0`——「滿潮內生成 0」可由 JSON 單欄直接核實, - 不再依賴 samples 逐秒推導。 - -### 107.4 量測方法備註 - -- `v18-level-bot.mjs` 四模式:play(推進通關)/idle(掛機觀察生成器,授長無敵 - 隔離存活軸)/stall(#804 定向重現)/forage(#805 供給可及性——錨定覓食、 - 滿匣傾瀉、`slayElite` 隔離精英噪音)。 -- bot 為固定策略非人類水準:跨修復前後同構可比,絕對值不代表玩家體感; - play 模式死亡重試會重置關卡,指標僅取開門前窗。 -- 指標層次口徑(引用時必須標明):`fullStall` 量測「生成飢荒」(零彈+同屏 - 零可吸+滿席,§107.1 對象);`longestAmmoZeroSec`/`reachVacuum` 量測 - 「可及/推進」層(含 bot 策略盲區與地形卡位)——兩層各自成立、不可互相 - 換算,同輪 fullStall 3.5s 與 quotaStall 326.8s 並存(post-l03-play)即 - 正常樣貌,非數據矛盾。 - -## 108. 難度量化工具(#818,T1 量測基礎設施) - -常備 CLI 單指令輸出任一關(走動/魔王/EX)難度報告;所有列車(#809–#814) -的驗收探針收斂於此,遊戲行為零改變。 - -- 入口:`node scripts/level-audit.mjs [--ex] [--bot low|mid|high] -[--runs N] [--cap 秒] [--probe jump|telegraph|swallow|starburst] [--all]`; - 報告(JSON+Markdown)寫入 `.claude/product-intel/level-audits/`(gitignored)。 -- SSOT 分層:三軸公式、驗收門檻(機制 brief §10)、分級 bot 參數、跳越運動學 - 全數住 `src/game/logic/difficulty.ts`(vitest 錨定行守門);CLI 經 Node 24 - type stripping 直接 import(`scripts/lib/ts-bridge.mjs` 補副檔名解析), - 禁止在腳本內維護第二份公式或門檻。 -- 三軸自動計算:主計畫 §3.1 錨定關卡(走動 D 取 L1/L3/L6/L19、M 取 L1/L5/L19、 - P 取 L1/L2/L18;魔王取 L4/L20 全軸)經 raw 公式反推錨點後分段線性校準—— - 錨行精確重現、其餘關卡由靜態資料插值,實測修正(死亡/重試)折入 P 軸封頂 - +1.5。人工評分自此退役,主計畫 §4 折線由 `--all` 重生成。 -- 分級 bot:單一策略引擎+感知延遲快照環(決策一律讀 reactionMs 前的世界), - 低 500ms 基礎策略/中 350ms+dodge/高 250ms 完整策略(讀招/風箏), - 對齊機制 brief §10 EX 驗收口徑(#814)。 -- 四專項探針:jump(#809 解析矩陣+強制 P2 貼牆逃脫實證)、telegraph(#810 - 30ms 細粒度入態→實體化量測+250/350/500ms 反應注入迴避率,幾何重疊判定+ - 無敵隔離存活軸)、swallow(#811 chompy 滿席凍結生成後以可吸計數轉移標定 - 暈眩窗,正確時機/衝刺期雙臂)、starburst(#812;v19 §109 改注入:混味連授 - 5 槽滿匣自動結晶+SP 鍵引爆,量測引爆後零彈恢復時間分佈 p50/p95——B 長按 - 誤放路徑已消滅,探針改守恢復保證不回退)。 -- 量測方法沿 §107.4 口徑:bot 為固定策略非人類水準,跨版本同構可比; - 走動關指標僅取開門前窗;魔王招式序列以條件熵(bits)量化可背板度(#813 - 去固定基線)。`v18-level-bot.mjs` 保留為 #804–#806 修復證據的凍結重現腳本, - 新量測一律走 `level-audit.mjs`。 - -## 109. v19 星暴 2.0+SP 情境鍵+B 鍵收斂(#815,修 #812 輸入面;輸入層 SSOT) - -外部評審 P0-3(B 鍵五語意超載)與 #812(星暴長按誤放清匣卡關)的根治:輸入仲裁 -狀態機重寫。機制 brief §2–§3 落地;本節為現行輸入 SSOT,取代 §23 星暴長按行、 -§40 滿匣讓位行與 §57 觸發面(各節已加取代標註)。 - -### 109.1 B 鍵最終語意(僅三項,`resolveActionPress`) - -| 操作 | 條件 | 行為 | -| -------------- | ------------ | -------------------------------------------------- | -| 點按(<150ms) | 有彈藥 | 發射(後進先出;滿匣亦即按即射,不再 defer) | -| 按住 | 頂槽非殼盾星 | 吸入 | -| 按住 | 頂槽殼盾星 | 舉盾(殼盾情境走延遲:放開 <150ms 結算為點按發射) | - -**退場**:長按 0.8s 星暴、地面長按 0.6s 變身——全部移出 B 鍵(誤觸根因消滅); -`advanceStarstormHold`/`starstormReady`/`starstormProgress`/`resolveTransformHold` -自 logic 層刪除。 - -### 109.2 SP 情境鍵(唯一新輸入面;`logic/starburst.ts`+`controls.setSpMode`) - -- 位置:右側 B 鍵「裝置空間上方」食指區 52px(48–56 帶內),恆由 B 鍵位置派生 - (`layout.spKeyPosition`,cw/ccw 旋轉殼換軸沿 §87 映射;不入自訂布局 schema, - 拖曳 B 鍵時跟隨);僅「有技能可用」時淡入 150ms 浮現,無技能完全隱藏。 -- 圖形:子 canvas 繪製(禁 emoji/文字鍵帽)——蓄能星暴=金色大星;變身=形態色 - 圓徽(tint 取 `TRANSFORM_FORMS` SSOT);變身中=解除迴旋箭。浮現輕震一次 - (沿 §91 觸覺管線,尊重靜音偏好)。 -- 語意(天然互斥,`resolveSpPress`;圖示即行為,`resolveSpMode` 同序): - 1. 變身中 → 點按=提前解除(優先序最高,圖示一致性)。 - 2. 蓄能星存在 → 點按=引爆星暴。 - 3. 無蓄能星且變身資格成立(同系 ≥3、地面)→ 點按=立即變身(0.6s 門檻廢除)。 -- 鍵盤映射:`C`=SP(`Z` 跳、`X` 吸/射不變);§89 桌機鍵位卡與 Title 操作說明 - 同步標示。 - -### 109.3 星暴 2.0——蓄能結晶+手動引爆 - -- 彈匣擴為 5 槽(`STAR.maxAmmo`);滿 5 槽瞬間**自動結晶**——彈匣清空、頭頂 - 生成蓄能大星(金色自轉+呼吸縮放+微光暈,頭頂 22px 軌道,`systems/chargedStar`); - 結晶後立即可繼續吸怪(anti-softlock:基礎星彈吸怪循環即時可用)。 -- 不疊加:蓄能星存在時再滿匣不再結晶(HUD 滿匣金色脈動提示;彈匣維持滿可正常 - 射擊/殼盾)。變身窗口=同系 3–4 發按 SP;滿匣即選擇星暴線(L3 hint 明示一次)。 -- 跨關持有/死亡清除/EX 進場清除:session 記憶(`systems/starburstDirector`, - 不動 save schema);首次結晶浮字「星力結晶!按 SP 鍵引爆」、首次帶星過關 toast - 「蓄能星會跟你到下一關」各一次。已知行為(設計取捨):detonating 相位過關 - (0.3s 蓄爆窄窗撞入門)不持有也不結算——引爆效果隨場景凍結靜默丟棄。 -- 引爆:SP 點按 → 0.3s 蓄爆(`STARSTORM.chargeMs`,不可取消)→ 清場全小怪+ - 魔王 12 傷+5s 無敵窗(沿 §64.2 取 max 不疊加)+既有震屏白閃星雨呈現。 -- 事件契約:新增 `STARBURST_CHANGED { phase }`(producer player;consumer - starburstDirector/e2e);`SKILL_STARSTORM` 世界結算管線不變。 -- 驗收(§108 探針改口徑;序列化單跑官方真值):引爆需顯式 SP 點按(e2e 守 B 長按 - 不觸發);引爆後零彈恢復全 15 走動關 90 樣本 pooled p95 8.85s ≤10s(T2 交付基線 - 9.5s,無回退且略優)、45s 未恢復=0;最難尾 L14 同樣本量 22.6s→12.2s 顯著改善。 -- 平衡 A/B 對照(審查收斂輪;main@977968280 vs v19 HEAD,cap 420s、序列化, - L6 mid 各 6 樣本、其餘各 3;JSON 留檔 `level-audits/ab-*`): - L2 mid 33%→100%(122.8→94.3s)、L2 high 雙 100%;L6 mid 雙 67%(通關均時 - 194→317s,見下方觀察項)、L6 high 0%→33%(基線既有困難,v19 略優); - L12 魔王 mid/high 雙 100%(TTK 11.1→10.6s/18.8→17.4s)。裁定:短 cap - (120–300s)×runs 2 的 L6 clearRate=0 量測為口徑假陽性——base 通關樣本均時 - 194s、v19 317s,短 cap 會把兩者都截成 0%;clearRate、ammoZero 峰(17.2 vs - 16.8s)與飢荒峰皆同水準,「5 槽惡化火力節奏」不成立,無回歸。 - 觀察項(非門檻):L6 mid 通關均時 +123s 偏移——bot 滿匣結晶後引爆時機非最優 - 所致,人類玩家可自主擇時;列 T4 教學矩陣觀察清單,門檻指標全數持平不調參。 - -## 110. v20 變身系統 2.0——三形態加深+教學矩陣(#816;T4 列車) - -### 110.1 三語彙表(機制 brief §4;表驅動 `logic/transform.ts`,每形態 ≤3 守門) - -| 形態 | 攻(保留+補齊) | 防(新增) | 機動(新增) | -| -------------- | ---------------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------- | -| 雷化 Voltpuff | 鏈電束+帶電接觸(§57 既有) | 受擊放電反擊(120px、傷 1、每形態期 2 次) | 磁力域免疫(磁彎折不作用;L8/L11 優勢解) | -| 風化 Galepuff | 穿透風刃+落地衝擊(§57 既有) | 落地滾翻(落地瞬間 0.3s 免傷,自動) | 滑翔(空中按住跳鍵=緩降帽+水平漂移 ×1.6) | -| 殼化 Shellpuff | 滾殼衝撞(B 點按,0.7s/CD 0.9s,接觸傷 2)+下砸加倍(§57 既有) | 受身入殼(受擊自動全免+0.5s 免傷,每形態期 1 次) | 衝撞躍(衝撞中按跳=低弧跳、保持衝撞態) | - -- 工程接點:`TransformFormSpec` 擴欄(`dischargeCharges`/`landingRollMs`/`tuckCharges`/ - `magnetImmune`/`glide`/`chargeDash`);`TransformState` 增 `dischargeLeft`/`tuckLeft` - 每形態期計數(`consumeDischarge`/`consumeTuck` 純函式裁決,vitest 對象)。 -- 世界結算:放電反擊走 `SKILL_TRANSFORM_STRIKE`(kind 增 `volt-discharge`,additive) - → `starCombat.resolveVoltDischarge`;滾殼衝撞接觸傷沿 overlaps 既有 contactDamage - 通道(`player.isShellCharging()` 改判);磁免疫於 `starSteering.steerMagnetizedStars` - 依 spec 短路。 -- anti-softlock 不變式(§57 硬規則):全部語彙為威力/防禦加成路徑,基礎星彈保底線 - 零改動;受身入殼/放電反擊次數隨形態期歸零,無跨期累積。 - -### 110.2 MechanicProgressionMatrix(機制 brief §6.1;`levels.ts` 資料驅動) - -- `LevelSpec` 增 `teaches[]`(本關首教機制)+`bossApplies[]`(魔王驗收機制)+ - `drillSpawns[]`(教學供給固定生成);`MechanicId` 13 機制 union。 -- 教學前置完整性由 `levels.test` 圖遍歷守門:任一關 `bossApplies` 機制必已在較早關 - `teaches`;機制唯一首教;各魔王關驗收含 `transform`。 -- L3 變身首教位點:進關前段(x 460–600)drillSpawns 保證 3 隻 floaty(同系→風化); - SP 資格徽章首次浮現時一次性教學浮字「同系星彈 ×3!按 SP 鍵立即變身」(session 慣例)。 -- 首教關對映(依 repo 資料實況錨定):L1 吸射、L2 殼盾+下砸、L3 變身+星暴、L5 氣流、 - L8 磁力域、L9 鏡性、L10 折躍、L13 噴口、L14 潮汐、L17 低重力、L18 流星讀影。 - -### 110.3 變身優勢情境模板+TTK 對照 hook(機制 brief §4/§10) - -- `TRANSFORM_ADVANTAGE`(`logic/difficulty.ts`):每王一個「優勢解但永不必需」情境; - T4 先落 Jellord(殼化反彈線,shelly)與 Noctra(雷化斷召線,zappy),其餘三王隨 - T5 魔王主題化補齊。 -- bot hook:`node scripts/level-audit.mjs --transform`——driver 以正式 - swallow 管線集齊優勢味 ×3(集星期間停火防射空資格)→ 按 SP 變身(空中裁決 none - 逐 tick 重試);報告輸出 `transformsPerRun` 與情境描述。 -- 驗收口徑:同 bot 分級、同 runs 的有/無 `--transform` 兩份報告對照,TTK 改善 - ≥15%(`AUDIT_THRESHOLDS.transformTtkGainMinPct`)且無變身仍可通關(非必需)。 - -## 111. v21 魔王主題化 W1——加權選招+Jellord/Noctra 主題招式(#813;T5 列車) - -取代標註:§6 P1/P2 固定循環與 §54 `noctraAttackCycle` 循環游標敘述由本節加權表驅動取代 -(招池與數值不變,僅選招機制升級);telegraph 窗全部維持現值不降(可讀性紅線)。 - -### 111.1 FSM 加權選招基礎設施(logic/moveTable.ts,SSOT) - -- 招式序由固定循環改**加權表驅動**:`weight`(權重欄)+`condition`(條件欄,宣告式 - HP 帶 `minHpRatio`/`maxHpRatio` 與玩家距離帶 `band: near|far`,門檻 300px、未知視 far)。 -- rng 注入可測(`createSeededRng` mulberry32,同 seed 完整重放);缺省 `Math.random`。 -- 連續同招上限 2(防隨機劣化體感);條件全剔除時回退整表(anti-softlock 永不空手)。 -- 兩王 FSM 增 `setTargetDistance`(呈現層逐幀餵送);`JELLORD_MOVES` 與 `noctraMoveTable` - 為招池 SSOT——Jellord dash 限遠距帶(貼身衝撞不可讀),其餘權重對齊原循環頻率。 - -### 111.2 Jellord 主題招式「果凍回彈」(logic/jellyPatch.ts) - -- P2 起 slam 指令帶 `jelly` 旗標:踩踏落點地面果凍化 3s(粉色地塊,壽命內淡出)。 -- 玩家踩上被彈起(非傷害):初速 -560(高於跳躍 -420、低於彈簧 -640),可接漂浮控高 - ——果凍地形=免費跳台;經既有 `getVentLift` 管線結算(GameScene 零接線變更), - 彈起 200ms 冷卻防連觸。既有下砸暈窗反制(§58 slamStun)不變。 - -### 111.3 Noctra 主題招式「蝕月斗篷」(logic/eclipseCloak.ts) - -- P2 起低頻(權重 1,全表最低)新招 `cloak`:隱形 1.2s 固定不隨狂暴速率縮放, - 僅月牙軌跡粒子可見;進出各 180ms fade 無跳變。 -- 反制(吸入第二用途):按住吸入產生氣流擾動使輪廓顯形(alpha 0.06 → 0.5); - hooks `isPlayerInhaling` 由 bossFactory 接線 player.isInhaling()。 - -## 112. v22 魔王主題化 W2——Prismix/Syrona 加權選招與主題招式(#813;T5 列車) - -取代標註:§68 P1-P3 固定循環由 `prismixMoveTable` 加權表取代、§74 三階段循環由 -`syronaMoveTable` 加權表取代(既有招池數值不變,僅選招機制升級+主題招式擴池); -telegraph 窗全部維持現值不降(可讀性紅線)。基礎設施沿 §111.1 moveTable SSOT。 - -### 112.1 加權選招接入(沿 §111.1,兩王 FSM 增 rng/setTargetDistance) - -- Prismix:P1 晶柱 3/光束 3;P2 夾擊 3/交錯光束 3/召喚 2/鏡界反射 2/鏡像殘影 1 - (條件欄 `maxHpRatio: 0.5`——總血 ≤50% 深段才入池,HP 帶條件示例);P3 彈幕 3/晶雨 3。 -- Syrona:P1 噴泉 3/射彈 3(條件欄 `band: 'far'`——貼身拋物不可讀,沿 Jellord dash - 遠距帶理據);P2 滴落 3/噴泉 3/召喚 2;P3 糖漿波 3/超載 3。 -- 換階段清空同招記錄;rng 注入同 seed 可重放(Syrona 與噴泉洗牌共用同一 rng)。 -- 條件熵驗收(#818 口徑,seed 13 × 60 招):Prismix P1 0.90/P2 1.47(≤50% 深段 1.93)、 - Syrona P1 0.90/P2 1.38/P3 0.90 bits,全數 ≥ `AUDIT_THRESHOLDS.moveEntropyMinBits`(0.5)。 - -### 112.2 Prismix 主題招式「鏡界反射」(FSM 態內建) - -- P2 新招 `mirror`:單具開鏡 0.8s(銀白鏡光面板 telegraph,固定不隨狂暴縮放); - 開鏡側受擊零傷、FSM 回 `reflect` 事件,呈現層自該具生成折返彈射向玩家。 -- 反制(可學習):開鏡窗內打另一具照常結算;折返彈帶 `inhalable` 標記——吸入中接觸 - 即回收為彈藥(免費彈藥=獎勵理解,L9 mirri 已預教鏡性);不吸則照常 1 傷。 -- 開鏡側由 rng 抽選(同 seed 可重放);單側殘存防呆歸存活具。 - -### 112.3 Prismix 主題招式「鏡像殘影」(logic/mirrorShadow.ts) - -- P2 深段(總血 ≤50%)低頻新招 `shadow`:玩家鏡影自 arena 中線鏡射位現身—— - 水平反向移動(玩家逐幀位移取負向套用)、垂直速度上限跟隨、觸傷 1、6s 壽命、 - 1 發星彈即破;單具重生刷新(不疊加)。 -- 反制(mirri 鏡性課):反向移動特性=向遠離殘影方向移動即以雙倍速率分離; - 一發基礎星彈即可拆除(anti-softlock:基礎星彈恆可清)。 -- 工程接點:殘影 sprite 雙掛既有 `shields`(星彈可破)+`shockwaves`(觸傷)群組, - BossHandle 零新選配;碎晶盾軌道迴圈以 `shadow` data 旗標跳過。 - -### 112.4 Syrona 主題招式「焦糖化」(logic/caramel.ts + systems/caramelStatus.ts) - -- P3 糖漿波帶 `caramel` 旗標:沾身減速 30%/3s(琥珀色腳部沾糖粒子),重複沾波刷新 - 不疊加;狀態真值收斂 logic/caramel.ts,呈現編排收斂 systems/caramelStatus.ts - (守 GameScene 1200 行閘),移速與 buff 倍率單點合成注入 player(防互相覆寫)。 -- 反制(可學習):乘噴口氣流吹乾即解除(`getVentLift` 供力當幀清除);雷化放電瞬除 - (volt 形態既免疫沾身也瞬除既有沾身——變身優勢解);首次沾身浮字教學(session 一次)。 -- overlaps 接點:shockwave 命中玩家時讀 `caramel` data 旗標經 `applyCaramel` hook 結算, - 傷害照常走 `damagePlayer` 單一入口。 - -## 113. v23 魔王主題化 W3——Voidra 加權選招與星光虹吸(#813;T5 列車) - -取代標註:§82 P1/P3 固定循環由 `voidraMoveTable` 加權表取代(既有招池數值不變, -僅選招機制升級+主題招式擴池);P2 生存段仍為波次表驅動(§82 不變); -telegraph 窗全部維持現值不降(可讀性紅線)。基礎設施沿 §111.1 moveTable SSOT。 - -### 113.1 加權選招接入(沿 §111.1,FSM 增 rng/setTargetDistance) - -- P1 牽引 3/彈環 3/爪擊 3/虹吸 2;P3 彈幕 3/潮汐 3/虹吸 2(虹吸為低頻主題招, - 權重全表最低);P2 波次表驅動不變(`voidraMoveTable('p2')` 僅供對表)。 -- 換階段清空同招記錄;rng 注入同 seed 可重放;連續同招上限 2;死碼 - `voidraAttackCycle` 移除。 -- 條件熵驗收(#818 口徑,seed 13 × 60 招):P1 1.76、P3 1.38 bits,均 ≥ - `AUDIT_THRESHOLDS.moveEntropyMinBits`(0.5)。 - -### 113.2 Voidra 主題招式「星光虹吸」(logic/starSiphon.ts) - -- P1/P3 新招 `siphon`:紫色吸流 0.8s 窗(固定不隨狂暴速率縮放,≥600ms 可讀性紅線) - ——吸流粒子沿玩家→核心路徑收斂+核心紫染 telegraph;窗滿抽走彈匣頂槽 1 發化為 - 自身護盾 1 層(環繞核心紫星軌道,上限 2 層,每層抵銷 1 次受擊零傷、不掉補給)。 -- 反制(高技巧獎勵):窗內朝吸流發射=星彈逆流爆盾——護盾全清+回傷 4(與來彈 - 傷害取較大值,不懲罰重彈)+取消本次抽取;把損失變輸出窗。 -- 空匣防呆(anti-softlock):窗滿無彈可抽=僅演出不獲盾;護盾僅來自實際抽取, - 基礎星彈恆可於窗內爆盾(§10.2 不變式維持)。 -- 工程接點:窗長/上限/回傷 SSOT `logic/starSiphon.ts`;FSM 窗滿發 `siphonDrain` - 指令,呈現層經 hooks `drainTopStar()`(bossFactory 接 `player.stealTopStar()`, - 彈匣單一真值、HUD ammo 事件自動同步)回餵 `absorbSiphonStar()` 夾限化盾; - 段起點重試清空護盾層(§82 清場語義);save 零改動、BossHandle 零新選配。 - -## 114. v24 EX 全面重設計 W1——Prismix P4 裂核殘響(#814;T6 列車) - -> EX 挑戰全面升級:每王 EX 追加專屬第四型態(P4)=第二血條,總有效 HP 相對一般 -> 約 ×2.25(難度翻倍);技巧破關、非 RNG 死牆。W1 落地 Prismix;Syrona/Voidra -> P4 於 W2/W3 落地(差分定稿見 `.claude/epics/starpuff-t6/updates/stream-main.md`)。 -> 取代標註:§86.1 Prismix EX 差分列由本章擴充(原差分保留,追加 P4)。 - -### 114.1 型別基建:BossPhase 擴為四段 - -- `BossPhase` 聯集加 `'p4'`(EX 專屬型態);五 FSM 的 `Record` - 補 p4 鍵、moveTable switch 補 p4 分支——Jellord/Noctra 執行期不可達(沿 p3 值), - Syrona/Voidra 暫沿 p3 待 W2/W3 落真 P4;Voidra 段起點重試明確限 p2/p3。 -- HUD `BOSS_PHASE` p4 → 血條金緋換色(0xe8b45a)+滿灌重灌=第二血條視覺。 - -### 114.2 Prismix EX P4「裂核殘響」(prismixFsm SSOT) - -- 觸發:EX 限定,P3 裂核歸零不死——`enterRebirth`:phase p4、第二血池 - `rebirthHpRatio 0.5`(EX 120 → 60)、`maxHp` getter 換刻度供 HUD 重灌; - 僅可重生一次(p4 歸零才 `defeated`)。 -- EX 雙子連破:掙扎窗補殺彩蛋保留(twinFinish 照發),改跳過 P3 直入 P4 - (跳段不跳王——技巧獎勵仍成立且 EX 專屬型態不可跳過)。 -- P4 招池:稜光行牆 3/彈幕 3/晶雨 2;P4 speedFactor 沿狂暴帶 1.15(疊 EX - 1.15 ≈ 1.32——W1.6 合規修正:初版 1.25 終段加壓違反 §8.1 面板紅線已收回)。 -- 新招「稜光行牆」(sweep):起掃側 rng 抽側(同 seed 可重放)、側緣豎線閃爍 - telegraph 700ms(固定不縮放)後,全高 120px 光牆以 180px/s 橫掃全場,出界回收。 - 跳越窗=跳+拍翅時機(`maxJumpClearancePx≈210` vs 牆高 120,vitest 錨定 - `sweepWallHeightPx ≤ maxJumpClearancePx()-60` 裕度)。 -- anti-softlock:供彈保證律(每 10 傷 minionDrop)跨 P4 延續;telegraph 紅線 - ≥600ms 全數維持;碎晶盾於重生時全數碎裂(P4 無盾環,輸出路徑純淨)。 -- 呈現層:重生演出(閃屏+震動+核體金緋重構 Back.easeOut);EX 緋紅呼吸循環 - 於 P4 讓位金緋定色;受擊白閃 restore 對 p4 回金緋。 - -### 114.3 驗收探針(#818 level-audit) - -- `node scripts/level-audit.mjs 12 --ex --bot low|high --runs N`:低階 clearRate - <20%、高階 ≥60%(門檻 SSOT `AUDIT_THRESHOLDS.exLowPassMaxRate/exHighPassMinRate`)。 - -### 114.4 W1.6 調參(PM 裁決落地:段檢查點+滑近週期化) - -W1.5 分級 bot 死因取證(高階 0%:p2 死 41/51、機制全解、輸出可用但 180 有效血 -無檢查點=90s 單命耐力牆)後 PM 裁決: - -- **EX 段檢查點 P3/P4**(裁決①,後經裁決 A 修訂為進度保留): - `prismixFsm.resetToPhase('p3'|'p4')`——EX 限定,P3/P4 死亡不回滾整場, - 沿 voidra `trySegmentRespawn` 清場管線(投射物/排程/鏡界全清+HUD 同步); - P1/P2 與非 EX 走一般敗北流程。難度語意自「單命耐力」轉「分段技巧驗收」。 -- **進度保留語意(PM 裁決 A,取代初版段門檻回灌)**:死亡僅重置玩家、 - boss 血不回灌——量測實證回灌語意在 P3/P4 形成「段命磨量 vs 段血回灌」 - 臨界輪迴(段內死牆:五測 p4 死 110/162、通關 1);voidra 回灌慣例的 - 存在理由(P2 波次表重播 anti-softlock)於 P3/P4 不適用。技巧性不降 - (每招仍需應對)、面板紅線不動;碎晶盾亦不隨段重試重生(同語意)。 -- **P1 滑近週期化**(裁決③輕量版):EX 限定 `glidePursuing`(追 3.2s/歇 1.4s, - 追擊窗佔主導守「不站樁」紅線)——消恆時追擊的強制跨越稅、給明確輸出窗; - 非 EX 與 P3/P4 恆時滑近不動。 -- **觀察項(PM 裁決④記錄)**:非 EX L12 高階 bot 通過率 50%(其他王 100%)—— - Prismix 主線難度曲線相對同儕右移,主線調參另議、本輪不動。 - -## 115. v24 EX 全面重設計 W2——Syrona 窯心暴走+Voidra 內核裸奔(#814;T6 列車) - -依 §8.2 表落地後二王 EX 專屬型態(phase+1),HUD 雙血條沿 BOSS_PHASE/ -BOSS_DAMAGED 既有管線泛化(barTint 覆寫欄,零新 HUD 系統)。 - -### 115.1 Syrona EX P4「窯心暴走」(syronaFsm SSOT) - -- 觸發:EX 限定,P3 血量跌破 `EX_SYRONA.rampageHpRatio`(15%)入 P4。 -- 皇冠唯一可傷點:`takeDamage(amount, crown)` P4 期體傷歸零(可傷性裁決收斂 - FSM);皇冠 ×2 倍傷沿 §74 呈現層結算——登頂技巧強制驗收(單跳頂帶窗/ - 噴口升托皆可達,anti-softlock 基礎星彈恆可通關)。 -- 全場沸騰:週期 ×`rampageBoilPeriodMul`(0.45)、漲頂 `rampageBoilMaxYDeltaPx` - (-40 → 312)——恆低於最高浮台(304),保底立足位不變式;退潮窗照常 - (無計時失敗紅線)。 -- 血條結構:單條+暴走段深紅(`barTint` 覆寫;與 p2 常規紅區隔);本體紅化。 -- 招池沿 p3(wave/overload)——overload 升托即登頂輸出窗。 - -### 115.2 Voidra EX P4「內核裸奔」(voidraFsm SSOT) - -- 觸發:EX 限定,外核(既有三段全池 165)歸零不死——內核獨立血池滿灌。 -- 雙血條:外核 60%/內核 40%(`innerHpRatio` 2/3 推導:165:110);HUD 血條 - 重灌換刻度+亮紫換色(沿 Prismix P4 慣例)。 -- 裸奔差分:體積 ×0.6、移速 ×1.4(呈現層 EX_VOIDRA SSOT)、招式間隔 ×0.8 - (SPEED_FACTORS.p4 分母化;僵直窗/吸流窗固定值不縮,hit window 紅線保留)。 -- 段重試擴 P4(進度保留語意,沿 Prismix PM 裁決 A:無波次表重播需求, - 死亡僅重置玩家、內核血不回灌;p2/p3 沿既有回灌慣例不動)。 -- 招池沿 p3(barrage/crush/siphon)——語彙不變、節奏與幾何差分。 - -### 115.3 T6 終局驗收(#818 分級 bot,各 6 runs,2026-07-24) - -| 王 | EX high(≥60%) | EX low(<20%) | 非 EX high 對照 | -| ----------- | ----------------------- | -------------- | ------------------------ | -| L4 Jellord | 83% ✓(TTK 27s) | 0% ✓ | 100%(0 死) | -| L7 Noctra | 67% ✓(TTK 29s) | 17% ✓ | 100%(0.17 死) | -| L12 Prismix | **100%** ✓(TTK 74.5s) | 0% ✓ | 50%(右移觀察項 §114.4) | -| L16 Syrona | 67% ✓(TTK 32s) | 17% ✓ | 100%(0 死) | -| L20 Voidra | 67% ✓(TTK 236s) | 0% ✓ | 100%(2.17 死) | - -- 十門檻全 PASS(#814 驗收標準達成)。量測口徑:EX high 一律 cap 540s - (checkpoint 架構通關期望 200-400s;歷史 artifact 中 L20 曾以 360s 量得 - 67%——W3 已按 540 口徑重跑回填,見 §115.4)、bot 分級 SSOT - `difficulty.BOT_TIERS`(low 恆基礎策略——bossForage/crown 節拍等完整 - 策略均 tier gate)。 -- L12 決定性因素=段重試進度保留(回灌語意 0-17% → 保留語意 100%); - L16 low 首測 33% 為 crown 節拍漏 tier gate 的量測污染,gate 後 17%。 - -## 116. v24 EX 全面重設計 W3——Jellord 果凍狂潮+Noctra 月相雙血條+皇冠共鳴(#814;T6 收斂) - -W3 合議收斂:補齊 §8.2 表前二王真 P4(stub 落地)+Syrona 暴走段 incidental -可傷面收斂+段重試雙語意局內提示。 - -### 116.1 Jellord EX P4「果凍狂潮」(bossFsm SSOT) - -- 觸發:EX 限定,主條(90)歸零不死——狂潮小條滿灌(`EX_JELLORD.frenzyHp` - 15,§8.2 表定值),phase 單向鎖存(`phaseForHp` 由 hp 推導不回落)。 -- 全地板果凍化:週期全場重鋪果凍地塊(壽命 3s/重鋪 2.2s 覆蓋連續)—— - 強制彈跳中作戰沿 §5 果凍回彈既有機制(零新系統)。 -- 分裂小果凍(§58 EX 彩蛋)改隨狂潮入場(演出+場上補給),真擊破不重發。 -- 血條:單條+狂潮段果凍粉(barTint 泛化);招池/節奏沿 p3(§8.1 面板紅線)。 -- P4 段重試(W3 終局,沿裁決 A 同構):狂潮死亡進度保留(小條不回灌、 - 地塊/彈幕清場重鋪)——取證:high bot 每命抵達 P4 殘血 1-2、無檢查點 17% - 結構死牆(與 L12/L16 同簽名);P1-P3 維持整場重打。 - -### 116.2 Noctra EX P4「月相雙血條」(noctraFsm SSOT) - -- 觸發:EX 限定,亮月條(主池 78)破而不死——暗月條滿灌 - (`EX_NOCTRA.darkMoonHpRatio` 0.5 → 39;「各 50%」=暗月為亮月半值, - 沿 Prismix rebirthHpRatio 同構),HUD 重灌換色(銀紫)。 -- 暗月差分:隱形頻率 ×2(p4 招池 cloak 權重 1→2)+月牙軌跡變細 - (`darkSweepScaleMul` 0.65:掠行判定帶與本體縱向縮細;telegraph 時長 - 不縮——可讀性紅線只縮體不縮窗);月蝕矩陣(EX 質性差分)續存。 -- P4 段重試(W3 終局,沿裁決 A 同構):暗月死亡進度保留(暗月條不回灌、 - 彈幕清場+隱形/俯衝態復位回盤旋)——取證:high bot 每命抵達 P4 殘血 0-2、 - 無檢查點 0% 結構死牆;P1-P3 維持整場重打。 - -### 116.3 Syrona 皇冠共鳴連擊(W3 Blocking 收斂) - -- 問題:crown tier gate 後 low 仍 33%(>20%)——overload 升托/高台誤射的 - incidental 皇冠命中 ×2 倍傷可 2 發偶中秒掉暴走池(20 血)。 -- 修法(v2 共鳴解鎖制;v1 單發節拍窗 900ms 實測誤傷 high——體傷命中不入 - 節拍、跨跳輪 crown 命中間隔 ~950-1600ms 致 25/26 全 glance):窗內 - (`crownComboWindowMs` 1600)累積 `crownResonanceHits`(3)中解鎖全額、 - 斷窗重計;解鎖前皆 `crownGlanceDamage`(1 點,anti-softlock 恆可磨)。 - 低階 overload 單簇(2-4 發)解鎖後至多 1 發全額(≤13 < 暴走池 20) - 不秒池、簇間 8-12s 必斷窗。 -- 技巧語意:「登頂後維持命中流」=主動技巧驗收升級,偶中簇不再成立。 - -### 116.4 段重試雙語意局內提示(W3) - -- 同王雙語意(Voidra p2/p3 回灌 vs p4 進度保留;Syrona p4 進度保留見 - §116.5)以 `BOSS_SEGMENT_RETRY` 事件(producer:boss systems - trySegmentRespawn)→ systems/toasts 浮字區分「段首重試——魔王傷勢保留 - /魔王氣力回復」;每語意每局一次。 -- 受擊白閃 restore-tint(voidra/syrona 同構修復):P4 段位相色(裸奔亮紫 - /暴走紅化)白閃回落復原而非 clearTint 洗掉。 -- EX 緋紅呼吸循環 P4 讓位(W3 收斂):呼吸 onUpdate 每幀 setTint 會覆寫 - 段位相色——voidra/syrona 補 `fsm.phase === 'p4'` 早退 guard(鏡 prismix - W1 既有慣例),P4 定色不再被洗掉。 - -### 116.5 Syrona EX P4 段重試(W3 v2 收斂) - -- 取證:共鳴 v2+登頂窄窗(airMs 380-560、節流 90ms)後 L16 EX high 仍 - 0%(寬窄窗兩測 6-run 全 timeout、15.17 死/次)——高階 bot 每命例行抵達 - P4 並磨池至 11-12,但 Syrona 無段重試:死亡=135 整場重打、暴走池 - (135×0.15≈20)隨之重灌,單命皇冠輸出上限 ~9 < 20 ⇒ P4 結構性不可完成 - (與 L12 W1.6 六輪 0-17% 死牆同簽名)。 -- 修法(沿 Prismix/Voidra PM 裁決 A 同構):P4 死亡段內重試「進度保留」—— - hp/供彈累計不回灌、共鳴窗歸零(新命重啟命中流,不繼承解鎖態)、殘留 - 彈藥/衝擊波/延時全清(死亡前排程不得於新命憑空觸發)、全場沸騰以同 - spec 自新週期起漲(重生喘息窗);P1-P3 維持整場重打(抵達暴走的耐力 - 驗收保留)。`BOSS_SEGMENT_RETRY` kept 語意浮字沿 §116.4 管線。 -- anti-softlock:進度單調不退+供彈保證律延續——基礎星彈恆可磨死暴走池; - 面板紅線不動(EX_MODS/暴走池比率均未調)。 - -### 116.6 Syrona P4 噴口氣流登頂(W3 終局,PM 裁決) - -- 取證(真值探針,兩層幾何互鎖):跳打 apex 僅入皇冠帶 3px 的根因—— - (a)皇冠帶錨定 sprite 視覺框頂,但可命中物理箱頂緣低數十 px,帶內幾乎 - 無可重疊面;(b)§54 魔王準星輔助把長程星彈導向本體中心,主動拉出皇冠帶 - (懸停帶內 800 發零傷實測)。近距跳射僅因飛行短、彎不下去而偶中。 -- 皇冠帶錨點修正:`isCrownHit` 錨點自視覺頂收斂至「物理箱頂緣」單一真值 - (帶寬 `CROWN_BAND_PX` 34 不變,精準度保留;`__sp.bossPos().top` 供 bot - 取樣)。 -- 乘流登頂:P4 暴走段噴口窯壓恆噴(不看週期,柱色紅金訊號)+皇冠帶氣墊 - `crownHoverLift`(位置伺服懸停於物理箱頂+22,≥600ms 級穩定滯空輸出窗) - ——「像素級擦帶跳」升級為可學習的乘流登頂技巧;水平離柱即交還重力, - 無滯留軟鎖。 -- 準星輔助讓位:`BossHandle.aimAssistMode`——Syrona P4 回 `'off'`,星彈平飛 - 保留「乘流懸停高度=皇冠命中」的精準語意;其餘魔王/相位維持 center 既有 - 行為(低階保底線不動)。 -- 持鍵乘流(低門檻洩漏修正 v2):氣墊懸停僅跳躍鍵持按時供力 - (`getVentLift` rideHeld 參數,GameScene 餵 `controls.state.jumpHeld`)—— - 首版被動抬升使誤入噴口的低階 bot 假性通關(12-run 58% 取證);低階只點跳 - 不持鍵,天然被擋。 -- 窯風共振(低門檻洩漏修正 v2):P4 皇冠命中必須乘流中(`targetRidingVent`) - 才有效——未乘流命中一律體傷語意(0 傷金屬聲),關閉中台站射免技巧 chip - 通道;P1-P3 皇冠 ×2 維持純幾何。技巧門檻=「會用噴口」(PM 裁決語意 - 機械化);乘流中節拍仍由 §116.3 共鳴解鎖制收斂。 -- anti-softlock 複核:噴口恆噴保證可乘、持鍵=基礎輸入、彈盡可落地吃補給怪 - 再返場——基礎星彈恆可通關不變式成立;無計時失敗、沸騰不淹保底高台照舊。 - -## 117. 物理/視覺縮放解耦 visualScale(#819 子項 3;T7-B 列車) - -§77 型缺陷家族的架構級根治:Phaser 4 Arcade `Body.updateBounds` 每物理步以 -`sourceWidth × |scale|` 重算碰撞箱(官方 API 文檔+Body.js 原始碼實證,無凍結旗標), -且 TweenManager 與物理 world 同掛 `SceneEvents.UPDATE`——任何直接 tween sprite scale -的視覺效果都會在同幀被物理讀到,衍生落地擠壓迴圈、腳底離台、穿台與 overlap 漏檢。 - -### 117.1 通道架構(game/systems/visualScale.ts,場景鍵入單例) - -- 沿 §77.2 蹲姿/§45 走 bob 已驗證的 PRE/POST_UPDATE 視覺通道模式全遊戲統一: - `PRE_UPDATE` 還原物理基準(物理步只見基準)、`POST_UPDATE` 套用 - `base × fx × mod`(渲染見形變);tween 一律以 fx 代理為標的,物理永不見瞬態縮放。 -- 三層語意:`base`=物理基準(精英體型、鑽地鰭、半潛、縮殼、月牙縮體、裸核、 - texture 切換後 rebase);`fx`=tween 代理(squash/stretch、popIn、wobble、翼拍、 - 怒吼脈動、死亡收縮);`mod`=逐幀直寫(idle 呼吸、蹲縮),擁有者每幀維護。 -- 覆蓋面:玩家(擠壓/呼吸/蹲縮/受擊)、18 怪(popIn/wobble/呼吸/死亡/狀態造型)、 - 五王(wobble/翼拍/攻擊擠壓/怒吼/碎裂/死亡/相位縮體)。柱/爪/糖泉等升起中的 - 危害判定屬蓄意成長 hitbox,維持直接縮放不遷移。 -- 補丁退場:`LANDING_SQUASH_MIN_VY`(§77.1 單案例門檻)刪除——擠壓不再縮物理箱, - 任意著地皆可安全觸發;碰撞箱不再隨 wobble 每拍脈動(怪 ±8%、魔王 ±5-7%)、 - popIn 生成期物理箱不再僅 30%。 -- 行為錨:visualScale.test 鎖住「動畫期間物理讀取窗 scale 恆為基準」契約與 - 池重用重錨、shutdown 清理語意;行為零改變由全量 vitest+e2e 全套+ - level-audit L1/L14/L16 EX 對比 base 佐證。 - -## 118. 使用者設定 SSOT、存檔備援與 PWA 更新閘(#819;T7-A 列車) - -現行偏好與持久化 SSOT。取代散落 localStorage 鍵敘述:§9 靜音鍵、§34/§89/§95.2 鍵位 -布局鍵、§87.1 旋轉方向鍵,以及 §38 的「本遊戲無設定頁」偏離備註與重置範圍描述。 - -### 118.1 UserSettings 單鍵 SSOT(core/settings.ts) - -- 儲存鍵 `sp-settings`(`SETTINGS_SCHEMA_VERSION = 1`)為**唯一偏好真相**,欄位: - `audioMuted`/`hapticsEnabled`/`wakeLockEnabled`/`reducedMotion`/`screenShake` - (`off|low|full`)/`shellRotation`(`cw|ccw|null`,null=從未選擇供 §87.2 一次性 - 告知判定)/`keyLayout`(§89 v2 子樹,null=預設態不落盤,§95.2 語意不變)。 -- `reducedMotion` 預設尊重系統 `prefers-reduced-motion`(WCAG 2.3.3);非瀏覽器環境 false。 -- **一次性 migration**:首次讀取時吸收 legacy 散鍵 `sp-muted`/`sp-rotation`/ - `sp-key-layout` 為初始值(值損毀逐項回預設),**落盤成功即刪除三個 legacy 鍵** - (單真相;PWA 部署單向前進,回滾非支援路徑,殘留舊值會在主鍵遺失時被吸回過期偏好)。 - 例外語意:`persist` 失敗(隱私模式/配額滿)**保留 legacy 作下次開機來源**。 -- 主鍵損毀(JSON 壞損/版本不符/形狀損毀):回退 legacy 吸收並回寫修復,不以預設 - 靜默覆蓋;置 `wasSettingsRecoveredFromCorruption` 旗標,main.ts 於 Title 安靜時刻 - 以殼卡(§92)明確告知。 -- 一次性記憶鍵(`sp-rotation-notice`/`sp-install-dismissed`/`sp-desktop-keys`/ - `sp-orientation-hint` 等)非偏好,**不入本 schema**。 -- 已知限制:偏好經記憶體快取、無 storage event 跨分頁同步——多分頁併發寫入為 - last-writer-wins(單分頁互動情境,接受此限制)。 - -### 118.2 統一設定頁(systems/settingsPage.ts,取代 §38「無設定頁」備註) - -- Title 次選單第四鈕「設定」(`data-menu="settings"`)開啟純 DOM overlay(沿 - keyConfig/shellCards 慣例,不進 Phaser Scene);容器沿用 `.install-overlay` - class,`isShellBusy` 天然視為忙碌(與 PWA 套用/殼卡排隊互斥)。 -- 內容:音效/震動回饋/遊戲中螢幕常亮/減少動態效果四開關+震屏強度三段 - (關/弱/全)+「按鈕配置(鍵位與持向)」轉入口(§34 keyConfig 專頁由此轉入, - 不再是 Title 獨立鈕)+「完成」。ESC 關閉。 -- **即改即存**,無草稿語意(草稿/取消回滾僅存在於按鈕配置頁,§87.2/§95.2 不變); - 音效切換同步 mute 系統,震動開啟時輕震一次即時回饋。 -- 震屏/閃光偏好落地(`systems/cameraFxGate.ts`):一次性包裝 main camera 的 - `shake`/`flash`,全部 boss/fx 呼叫端零改動即受管——`reducedMotion` 或 - `screenShake:'off'` 時震屏強度 ×0(直接不震)、`low` ×0.5、`full` ×1; - `reducedMotion` 另將 flash 時長 ×0.3(未帶參呼叫以 Phaser 預設 250ms 為基準)。 - 偏好每次呼叫重讀,設定頁改動即時生效。 - -### 118.3 存檔備援與 checksum(core/save.ts,補訂 §38) - -- schema 現值 v2(§94.2 已升版;§38 的 v1 敘述為 v6 歷史值)。寫入時附 - `checksum` 欄;解析時 checksum 不符/JSON 壞損/未知版本一律判**損毀**。 - legacy 存檔(無 checksum 欄)視為合法,不誤殺舊玩家。 -- 備援鍵 `sp-save-backup`:每次寫入前把**上一份合法主檔**輪替至備援(損毀資料不 - 污染備援);主檔損毀時自備援恢復並回寫自癒,備援亦不可用才回退預設——兩路徑 - 皆 `console.warn` 留痕,不再默默歸零。備援輪替失敗(配額不足/隱私模式)不得 - 阻斷主檔寫入。 -- **重置進度範圍修正**(取代 §38 的「僅清 `sp-save`」):`resetSave` 同時清除 - `sp-save` 與 `sp-save-backup`(否則重置後會自備援恢復出舊進度);偏好 - (`sp-settings`:靜音/鍵位/持向等)不動。入口與兩步確認語意沿 §38 不變。 - -### 118.4 PWA 更新套用時機閘(pwaUpdateGate.ts) - -- 新版 SW ready 只標記 pending,**遊戲進行中絕不 reload**;僅在殼層安靜 - (非 GameScene/非配置中/無殼卡=Title/Map/Result 選單面,忙碌訊號沿 - `shellCards.isShellBusy` 單一 SSOT)才自動套用。 -- 套用寬限 1500ms:條件成立後再等寬限期並重驗,期間殼層轉忙(再入遊戲)即放棄 - 本次套用交還重試管線——避免場景切換瞬間 reload 吃掉使用者正要按下的點擊 - (Result「下一關」CTA 競態,§100)。 -- 邊界事件漏接保險:pending 期間每 5s 低頻重試;`#controls` class 變化 - (MutationObserver)=遊戲進出場邊界,離開 GameScene 當下即嘗試套用。 -- 取代 §35 的已知邊界敘述「autoUpdate 完成後的 reload 會蓋過暫停選單」——該競態 - 已由本閘根治(暫停選單期間 `#controls.is-active` 仍為真=殼層忙碌,不會套用)。 +> 路由:`https://app.haotool.org/starpuff/` + +本檔是**設計 SSOT 的入口索引**,不含規格內容。規格依主題拆在 [`design/`](design/) 下, +每檔開頭都有「職責範圍/不在本檔」聲明,照著找即可。 + +## 怎麼用這份文件 + +- **要查某個機制怎麼設計** → 先看下方「主題檔一覽」挑檔,再用檔內目錄找章節。 +- **手上有章號**(程式註解常見 `// …(GAME_DESIGN §62)`)→ 用下方「章號對照表」查它在哪一檔。 +- **不確定某段還算不算數** → 看 [`design/99-superseded.md`](design/99-superseded.md) + 的取代對照表,它逐條列出被取代的敘述與現行規則位置。 +- **要玩/要驗收** → 全 20 關實測攻略見 [`WALKTHROUGH.md`](WALKTHROUGH.md)。 + +### 章號紀律(MUST) + +章號 §N 是全專案穩定識別碼——`src/**` 程式註解、測試 describe 名稱與 issue 都直接引用。 +因此**主題拆檔不重新編號、不回收號碼**,新章一律接續遞增;跨檔引用一律只寫 §N, +不寫檔名路徑,避免日後再搬檔時全域失效。 + +## 主題檔一覽 + +| 檔案 | 這裡放什麼 | +| ----------------------------------------------------- | ------------------------------------------------------------------------------ | +| [`00-foundations.md`](design/00-foundations.md) | 產品定位、場景流程、技術架構與事件契約、品質門檻、版本號、跨系統架構級契約 | +| [`01-controls-input.md`](design/01-controls-input.md) | 搖桿與 A/B/SP 鍵語意、輸入矩陣、觸控判定、移動手感、旋轉殼、虛擬鍵布局與配置頁 | +| [`02-combat-star.md`](design/02-combat-star.md) | 戰鬥數值、九系星味與混合星、殼盾與雷鏈、星化三形態與教學矩陣 | +| [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | 主角與 18 隻小怪 FSM、精英系統、五座魔王階段與招式、EX 變體與 P4 第二血條 | +| [`04-levels-world.md`](design/04-levels-world.md) | 20 關資料與節奏、五區分頁世界地圖、彩蛋、平台與環境機制、魔王關前室與增益 | +| [`05-save-settings.md`](design/05-save-settings.md) | 存檔 schema 與備援、重置語意、成就系統、使用者偏好 SSOT 與設定頁、PWA 更新閘 | +| [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | 主選單與圖鑑分頁、暫停系統、HUD 命中層、結算動線、殼層卡片、PWA 安裝指引 | +| [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | 美術資產批次與風格關鍵詞、背景視差與裝飾密度、Juice 清單、zzfx 音效表 | +| [`08-safety-nets.md`](design/08-safety-nets.md) | 反卡死保證律、慈悲補血 pity 保底、供給可及性、難度量化 CLI 與分級 bot 口徑 | +| [`99-superseded.md`](design/99-superseded.md) | 取代對照表(權威索引)、版本列車沿革、已完全失效的搬遷內容 | + +## 硬不變式(使用者明令,跨檔恆成立) + +- **基礎星彈恆可通關**:混合星、變身、增益、精英與彩蛋全部是加成路徑,永不為破關必需。 +- **魔王關須有多種可行破關策略**(每王 ≥3 條,見 §58)。 +- **難度循序漸進,永不無限卡關**:關卡難度以分級 bot 勝率量化驗收(普通 ≥40%、熟練 ≥80%)。 +- **telegraph 可讀性紅線 ≥600ms**:EX 差分只縮體不縮窗。 +- **全遊戲禁 emoji 與文字鍵帽**;按鍵一律 canvas/CSS 繪製圖形。 + +## 章號對照表 + +| 章號 | 標題 | 檔案 | +| ---- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------- | +| §1 | 產品定位 | [`00-foundations.md`](design/00-foundations.md) | +| §2 | 核心循環 | [`00-foundations.md`](design/00-foundations.md) | +| §3 | 場景流程 | [`00-foundations.md`](design/00-foundations.md) | +| §4 | 操作(行動裝置優先) | [`01-controls-input.md`](design/01-controls-input.md) | +| §5 | 角色設定(全部原創) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §6 | 魔王 AI(有限狀態機,pure TS 可測) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §7 | 戰鬥數值 | [`02-combat-star.md`](design/02-combat-star.md) | +| §8 | Juice 清單(品質關鍵,全數必做) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §9 | 音效(zzfx,零音檔資產) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §10 | 美術資產規格(codex imagegen 專用;除此之外嚴禁動用 codex) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §11 | 技術架構 | [`00-foundations.md`](design/00-foundations.md) | +| §12 | 品質門檻 | [`00-foundations.md`](design/00-foundations.md) | +| §13 | 安全與合規 | [`00-foundations.md`](design/00-foundations.md) | +| §14 | 效能與範圍紀律 | [`00-foundations.md`](design/00-foundations.md) | +| §15 | 關卡系統(levels.ts 為 SSOT,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §16 | 新怪物 ×2(多樣性;全原創) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §17 | 魔王關演出強化(動畫品質關鍵) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §18 | 動畫流暢度打磨清單(全實體) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §19 | v2 美術資產增補(codex 專用;生成尺寸同 §10 規範) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §20 | 技能系統:吞噬賦星(v2.1,PM 親撰) | [`02-combat-star.md`](design/02-combat-star.md) | +| §21 | v3 橫式轉向(PM 親撰) | [`01-controls-input.md`](design/01-controls-input.md) | +| §22 | iOS 觸控直通(研究回寫後定稿) | [`01-controls-input.md`](design/01-controls-input.md) | +| §23 | 技能組合 v3:吞噬連鎖(表驅動,logic/skills.ts) | [`02-combat-star.md`](design/02-combat-star.md) | +| §24 | 關卡彩蛋(data-driven:levels.ts easterEggs[]) | [`04-levels-world.md`](design/04-levels-world.md) | +| §25 | 背景連續感與視覺升級 | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §26 | 反卡死保證(softlock 防護,全部 MUST) | [`08-safety-nets.md`](design/08-safety-nets.md) | +| §27 | v3 美術資產(codex 專用;橫向平鋪) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §28 | v4 免轉向橫式與響應寬幅(PM 親撰) | [`01-controls-input.md`](design/01-controls-input.md) | +| §29 | v4 平台玩法元素包(調研回寫後定案數值) | [`04-levels-world.md`](design/04-levels-world.md) | +| §30 | v4 內容擴充:新技能、新怪物、魔王 P3(PM 親撰) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §31 | v4 美術資產(codex 專用) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §32 | 場景裝飾密度規範 | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §33 | v5 iOS PWA UX 調研回寫(2026-07-15 定稿) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §34 | v5 控制布局重設計與按鈕自訂 | [`01-controls-input.md`](design/01-controls-input.md) | +| §35 | v5 暫停系統與離頁自動暫停 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §36 | v5 開場主選單與圖鑑/技能介紹 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §37 | v5 全元素位置稽核 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §38 | 存檔系統(core/save.ts 為 SSOT,pure TS 可測) | [`05-save-settings.md`](design/05-save-settings.md) | +| §39 | 迷霧世界地圖(MapScene,data-driven 自 LEVELS) | [`04-levels-world.md`](design/04-levels-world.md) | +| §40 | v6 新技能:殼盾與雷鏈(PM 原創,補防禦與群戰原型) | [`02-combat-star.md`](design/02-combat-star.md) | +| §41 | v6 移動手感打磨(logic/movement.ts,pure TS 可測) | [`01-controls-input.md`](design/01-controls-input.md) | +| §42 | 版本號顯示 | [`00-foundations.md`](design/00-foundations.md) | +| §43 | 每關攻略 PoC 與反卡關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | +| §44 | v7 下衝擊觸發改制與跳躍鍵輸入矩陣(PM 親撰,取代 §23 下+B 觸發) | [`01-controls-input.md`](design/01-controls-input.md) | +| §45 | v7 走動手感根修與抖動歸因(logic/walkFeel.ts,pure TS 可測) | [`01-controls-input.md`](design/01-controls-input.md) | +| §46 | v7 雙味混合星彈(config STAR_MIXES 為 SSOT,表驅動) | [`02-combat-star.md`](design/02-combat-star.md) | +| §47 | v7 新怪物 ×2(全原創;素材 codex imagegen 僅此 2 張,風格與既有嚴格一致) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §48 | v7 中魔王精英系統(levels.ts elite 為 SSOT,零新美術) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §49 | v7 每關攻略 PoC 與節奏補訂(引入→練習→考驗→獎勵) | [`04-levels-world.md`](design/04-levels-world.md) | +| §50 | v8 關卡 4→7 與雙魔王總覽(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | +| §51 | v8 上升氣流機制(logic/updraft.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §52 | v8 新怪物 ×3 與雙精英(FSM-first;素材 §55) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §53 | v8 星彈九系與新混合三式(config 表驅動擴充) | [`02-combat-star.md`](design/02-combat-star.md) | +| §54 | v8 第二魔王:暗月蝠王 Noctra(logic/noctraFsm.ts 表驅動,空中型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §55 | v8 美術資產(codex imagegen 專用;配額 6/6 用滿) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §56 | v8 每關攻略 PoC 與 anti-softlock 不變式 | [`04-levels-world.md`](design/04-levels-world.md) | +| §57 | v9 星化變身系統(logic/transform.ts 純狀態機,表驅動) | [`02-combat-star.md`](design/02-combat-star.md) | +| §58 | v9 魔王攻略多樣化與 EX 變體(表驅動擴充,禁止散落 scene) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §59 | v9 新怪物 ×2(FSM-first 進 enemyFsm,均歸既有味系) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §60 | v9 關卡 7→9 與世界地圖(levels.ts 資料驅動擴充)(v10 已由 §65 取代:十二關與十二節點) | [`04-levels-world.md`](design/04-levels-world.md) | +| §61 | v9 美術資產(codex imagegen 專用;配額 5/5) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §62 | v9 慈悲補血愛心(logic/mercyHeal.ts 純決策,保底機制非資源農場) | [`08-safety-nets.md`](design/08-safety-nets.md) | +| §63 | v9 Noctra 難度根修(實測席稽核回寫;bot 勝率門檻收斂定案) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §64 | v9.1 熱修:Noctra 返空連續飛行與星暴無敵窗(P0) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §65 | v10 關卡 9→12 與世界地圖(levels.ts 資料驅動擴充)(v11 已由 §76 取代:十六關與十六節點) | [`04-levels-world.md`](design/04-levels-world.md) | +| §66 | v10 星門折躍(logic/warp.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §67 | v10 卡點關中點重生(LevelSpec.checkpointX,§4 主計畫卡點緩解) | [`04-levels-world.md`](design/04-levels-world.md) | +| §68 | v10 第三魔王:稜晶雙子 Prismix(logic/prismixFsm.ts 表驅動,分裂型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §69 | v10 魔王關特殊體系(前室/短期增益/L12 首發;L4/L7 回補延 v11+) | [`04-levels-world.md`](design/04-levels-world.md) | +| §70 | v10 魔王關專屬彩蛋與每關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | +| §71 | v11 糖漿潮汐(logic/tide.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §72 | v11 熱泉噴口(updraft 週期參數化,零新 element kind) | [`04-levels-world.md`](design/04-levels-world.md) | +| §73 | v11 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §74 | v11 第四魔王:Syrona 熔糖窯后(logic/syronaFsm.ts 表驅動,場控型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §75 | v11 魔王關專屬彩蛋與每關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | +| §76 | v11 關卡 12→16 與世界地圖(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | +| §77 | v11.1 熱修:下跳穿落根修、蹲姿指示與吸入豁免 | [`01-controls-input.md`](design/01-controls-input.md) | +| §78 | v12 分區分頁世界地圖(logic/zones.ts+MapScene,主計畫 §2.2 硬項落地) | [`04-levels-world.md`](design/04-levels-world.md) | +| §79 | v12 流星雨(logic/meteor.ts+systems/meteor.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §80 | v12 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §81 | v12 低重力(LevelSpec.gravityScale,零新 element kind) | [`04-levels-world.md`](design/04-levels-world.md) | +| §82 | v12 最終魔王:蝕星魔核 Voidra(logic/voidraFsm.ts 表驅動,場控收束型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §83 | v12 魔王關專屬彩蛋與每關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | +| §84 | v12 關卡 16→20 與全線收尾(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | +| §85 | v12.1 熱修:真實觸控下滑判定重修(補訂 §21/§23/§77) | [`01-controls-input.md`](design/01-controls-input.md) | +| §86 | v13 EX 全魔王與星核制霸(EX 體系收尾+全制霸獎勵) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §87 | v14 直持預設旋轉方向翻轉(取代 §28 預設方向) | [`01-controls-input.md`](design/01-controls-input.md) | +| §88 | v14 按鈕配置頁操作列直欄化與標籤單行(取代 §34 操作列) | [`01-controls-input.md`](design/01-controls-input.md) | +| §89 | v14 虛擬鍵大小自訂(sp-key-layout schema v2) | [`01-controls-input.md`](design/01-controls-input.md) | +| §90 | v14 PWA 安裝偵測與分平台指引 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §91 | v14 觸覺回饋與螢幕常亮(調研加碼,ROI 閘通過二項) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §92 | v14 殼層卡片基建(shellCards.ts) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §93 | v14 殼局部 safe-area 量測(canvas 內 HUD 避讓預備) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §94 | v15 成就系統(logic/achievements.ts,純呈現層聚合) | [`05-save-settings.md`](design/05-save-settings.md) | +| §95 | v16 直持預設鍵位重錨(D1,取代 §34 預設在直持殼的適用性) | [`01-controls-input.md`](design/01-controls-input.md) | +| §96 | v16 圖鑑分頁有界網格(P1-01,取代 §36 技能雙欄與 §94.3 成就網格常數) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §97 | v16 區/關命名層級標示(F-01 裁決) | [`04-levels-world.md`](design/04-levels-world.md) | +| §98 | v16 選單 DOM 鈕命中短邊保底(D2,補充 §33 條目 7) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §99 | v16 版本頁腳 SHA 來源修正(F-02,補充 §42) | [`00-foundations.md`](design/00-foundations.md) | +| §100 | v16 勝利結算「下一關」主 CTA(D3,取代 §39 勝利回地圖單一動線) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §101 | v16 HUD 暫停/靜音 DOM 化(F-06+D4,取代 §35 暫停鍵與修復包 B 靜音鈕的命中層) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §102 | v16 配置模式遮罩加深(F-04,補充 §34) | [`01-controls-input.md`](design/01-controls-input.md) | +| §103 | v16 標題字形品牌化(D6,補充 §36) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §104 | v16 怪物圖鑑分頁(F-03,取代 §76 單頁定案) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §105 | v16 前期節奏保守調參(D5+F-05,補充 §15 教學關與 §48 精英房) | [`04-levels-world.md`](design/04-levels-world.md) | +| §106 | GameScene strangler 拆解與守門(三席維護性 5/7/8 收斂) | [`00-foundations.md`](design/00-foundations.md) | +| §107 | 走動關供給保證與滿潮平衡(issue #804/#805/#806) | [`08-safety-nets.md`](design/08-safety-nets.md) | +| §108 | 難度量化工具(#818,T1 量測基礎設施) | [`08-safety-nets.md`](design/08-safety-nets.md) | +| §109 | v19 星暴 2.0+SP 情境鍵+B 鍵收斂(#815,修 #812 輸入面;輸入層 SSOT) | [`01-controls-input.md`](design/01-controls-input.md) | +| §110 | v20 變身系統 2.0——三形態加深+教學矩陣(#816;T4 列車) | [`02-combat-star.md`](design/02-combat-star.md) | +| §111 | v21 魔王主題化 W1——加權選招+Jellord/Noctra 主題招式(#813;T5 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §112 | v22 魔王主題化 W2——Prismix/Syrona 加權選招與主題招式(#813;T5 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §113 | v23 魔王主題化 W3——Voidra 加權選招與星光虹吸(#813;T5 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §114 | v24 EX 全面重設計 W1——Prismix P4 裂核殘響(#814;T6 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §115 | v24 EX 全面重設計 W2——Syrona 窯心暴走+Voidra 內核裸奔(#814;T6 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §116 | v24 EX 全面重設計 W3——Jellord 果凍狂潮+Noctra 月相雙血條+皇冠共鳴(#814;T6 收斂) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §117 | 物理/視覺縮放解耦 visualScale(#819 子項 3;T7-B 列車) | [`00-foundations.md`](design/00-foundations.md) | +| §118 | 使用者設定 SSOT、存檔備援與 PWA 更新閘(#819;T7-A 列車) | [`05-save-settings.md`](design/05-save-settings.md) | diff --git a/apps/starpuff/docs/design/00-foundations.md b/apps/starpuff/docs/design/00-foundations.md new file mode 100644 index 000000000..db0e7019c --- /dev/null +++ b/apps/starpuff/docs/design/00-foundations.md @@ -0,0 +1,132 @@ +# 星噗噗 — 產品定位與工程契約 + +> **職責範圍**:遊戲是什麼、場景怎麼串、程式怎麼分層、什麼算過關(品質門檻)、版本號怎麼來,以及跨系統的架構級契約(事件契約、GameScene 職責邊界、物理/視覺縮放解耦)。 +> +> **不在本檔**:任何玩法數值與機制規格。操作與輸入見 `01-controls-input.md`;星彈與變身見 `02-combat-star.md`;怪物與魔王見 `03-enemies-bosses.md`;關卡與世界地圖見 `04-levels-world.md`。 +> +> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 + +## 1. 產品定位 + +- 橫式(landscape)四關側向卷軸動作遊戲:三關走動探索 + 魔王關(Boss Rush 收尾),單局 2–4 分鐘,可無限重玩。(v8 已由 §50 取代:七關雙魔王;v9 已由 §60 取代:九關——七關走動探索+兩座魔王關+雙 EX 變體。) +- 原創 IP:主角與怪物皆為原創設計(果凍星球世界觀),嚴禁使用任天堂卡比之名稱、造型、配色構圖。 +- 目標體驗:Q 彈、可愛、爽快——大量擠壓拉伸、粒子、震屏、音效回饋。 + +## 2. 核心循環 + +移動/跳躍/漂浮 → 長按吸入小怪 → 吞下獲得星彈(上限 5,v19 §109)→ 點按發射星彈打魔王 → 閃避彈幕與衝撞 → 擊破勝利。 + +## 3. 場景流程 + +`BootScene`(載入+進度條)→ `TitleScene`(標題、開始按鈕、音效提示)→ `MapScene`(v6 世界地圖 hub,§39)→ `GameScene`(四關制)(v8 已由 §50 取代:七關流程;v9 已由 §60 取代:九關流程)→ `ResultScene`(勝/敗)。 + +四關制流程(v8 已由 §50 取代:七關流程——L1-L3 → L4 果凍王 → L5-L6 → L7 暗月蝠王):Title → Stage 1-3 側向卷軸(擊殺配額達成 → 星星門開啟 → 走入過關)→ Stage 4 魔王戰(入場動畫 → Boss 戰,期間補生可吸小怪供彈藥)→ 勝利星爆 / 敗北。死亡處理:Stage 1-3 重試當前關;魔王關進敗北結算。關卡資料驅動細節見 §15。(v6 已由 §39 取代直達下一關的轉場卡:過關寫入存檔後自動進世界地圖,自地圖節點進下一關或重玩。) + +## 11. 技術架構 + +- Vanilla TypeScript + Vite + Phaser(最新穩定版)+ vite-plugin-pwa + zzfx。**不用 React**(遊戲 canvas 無需,KISS)。 +- Arcade Physics、object pool(彈幕/粒子)、`base: '/starpuff/'`。 +- 目錄契約(並行開發邊界,各 stream 只改自己的檔): + +``` +src/game/core/ config.ts events.ts types.ts ← scaffold 定義,凍結 +src/game/scenes/ Boot/Title/Game/Result ← 整合 stream 專屬 +src/game/systems/ player controls enemies waves boss fx hud +src/game/audio/ sfx.ts bgm.ts +src/game/logic/ combat.ts bossFsm.ts levels.ts ← pure TS,vitest 對象 +``` + +- 事件契約(`events.ts`,跨系統唯一溝通管道;v3 增列 `player:healed` 與 `skill:*` 技能結算事件;v4 增列 `boss:quake` P3 全場震落事件): + `player:damaged, player:healed, player:died, ammo:changed, enemy:inhaled, enemy:killed, star:fired, skill:starstorm, skill:slam-landed, boss:spawned, boss:damaged, boss:phase, boss:quake, boss:defeated, level:changed, level:quota, level:gate-opened, game:won, game:lost` + +## 12. 品質門檻 + +- 效能:60fps(中階機)、JS gzip < 1.6MB、首屏 < 3s(4G)。 +- PWA:可安裝、離線可玩、manifest 完整、無 console error。 +- 測試:logic/ 模組 vitest 全綠;playwright 手機視窗 smoke(載入→開始→canvas 運行→無錯誤)。 +- 每 commit 過 repo hooks(lint-staged、typecheck、format、commitlint)。 + +## 13. 安全與合規 + +純前端、無資料收集、無 API、無 secrets;原創角色(§5);依賴僅 phaser/zzfx(MIT);CSP 相容(無 eval)。 + +## 14. 效能與範圍紀律 + +能 10 行不寫 50 行;能用套件不手刻;嚴禁提前抽象與過度工程;註解預設不寫,僅必要處簡短正式繁體中文。 + +## 42. 版本號顯示 + +- SSOT:package.json `version` + short git SHA,經 vite `define __APP_VERSION__` 嵌入(`v0.X.Y+abcdef`;無 git 環境標記 nogit)。 +- 呈現:Title 頁腳小字(12px、violet、alpha 0.75);`window.__sp.version()` production 也掛載供現場排障(其餘 \_\_sp 除錯鉤子維持 DEV/test 限定)。 + +## 99. v16 版本頁腳 SHA 來源修正(F-02,補充 §42) + +- 根因(Composer 席):Zeabur Docker build 提供 GIT_COMMIT_HASH build arg 但 + context 無 .git,starpuff 版本解析僅呼叫 git 指令,落 nogit 佔位並露出於 + production 頁腳(v0.14.0+nogit)。 +- 來源鏈(收斂於 `scripts/lib/build-commit-sha.mjs`,跨 app SSOT): + **`ZEABUR_GIT_COMMIT_SHA`(Zeabur 建置階段內建,Dockerfile builder 段宣告 ARG 才會 + 注入)→ `GIT_COMMIT_HASH` → `git rev-parse` → 皆缺則省略後綴**(乾淨 vX.Y.Z, + 不露佔位字樣)。 + +> **已廢止**(2026-07-26 #877 起):以 `GIT_COMMIT_HASH` env 為首選來源——`.dockerignore` +> 排除 `.git` 使建置容器內 git 指令必失敗,Zeabur 又不提供該變數,production 恆落純 +> `vX.Y.Z`,同版號兩次部署無鑑別力。 + +## 106. GameScene strangler 拆解與守門(三席維護性 5/7/8 收斂) + +### 106.1 拆解記錄(行為零改變) + +- 性質:純維護性重構——玩法、數值、視覺、事件順序、存檔語意一律不動; + events 契約凍結(§11),本車為其補契約測試而非修改。 +- GameScene 2121 → 1196 行,職責收斂為一句話:orchestration+scene lifecycle + (create 接線、update 逐幀委派、事件路由、勝敗轉場、e2e 鉤子面)。 +- 六個抽取單元(每步先補 characterization test 鎖行為,全測綠才 commit, + 獨立可 revert): + - `systems/bossFactory`:魔王品種分派(never 守衛)、補給小怪節奏、召喚夾限。 + - `systems/starCombat`:星彈規格解析單一出口+技能世界結算(星暴/下衝擊/ + 殼盾反擊/鏈電束/風化落地/雷鏈/凍結場/爆裂波及)。 + - `systems/starSteering`:準星輔助/追電導引/磁場吸偏/拖尾附掛(導向順序凍結)。 + - `systems/overlaps`:戰鬥碰撞接線(接線順序凍結;damagePlayer/damageBossAt + 單一入口不變)。 + - `systems/eggTracker`:彩蛋進度鎖存/逐幀餵送/獎勵落地/crown 時間窗。 + - `systems/toasts`:成就 toast 佇列/星味首遇提示/彩蛋慶祝演出。 +- 新增測試:GameEvents 契約測試(事件名唯一、emit/on/off 對偶、FSM phase + 恰一次、waves 序列)+六模組 characterization——vitest 580 → 650。 +- ESLint 守門:apps/starpuff 範圍 `max-lines` error 1200(levels.ts 資料表 + 豁免),防 GameScene 再膨脹。 + +### 106.2 觀察項設計理由註記(不動行為) + +- 直持 joy-zone 幾何包住 A/B(Grok 席 v16 觀察項):維持 §95 設計定案—— + keys-layer 為後繪兄弟層天然承接命中,誤觸空白處僅零位移搖桿錨定(無害)。 + 若未來要消「右拇指邊緣偶發搖桿錨定」感,方向為 joy-zone 右緣排除鍵命中區; + 本車行為零改變原則下不動。 +- 教學關死亡結轉讀值時窗(§105 D5):retryLevel 於 350ms 延遲回呼讀取配額, + 理論上飛行中星彈可多算 1 殺——carryKillsOnDeath 夾限(≤配額-1)保證無害 + 且恆有利玩家,屬既有設計定案,不加鎖存。 + +## 117. 物理/視覺縮放解耦 visualScale(#819 子項 3;T7-B 列車) + +§77 型缺陷家族的架構級根治:Phaser 4 Arcade `Body.updateBounds` 每物理步以 +`sourceWidth × |scale|` 重算碰撞箱(官方 API 文檔+Body.js 原始碼實證,無凍結旗標), +且 TweenManager 與物理 world 同掛 `SceneEvents.UPDATE`——任何直接 tween sprite scale +的視覺效果都會在同幀被物理讀到,衍生落地擠壓迴圈、腳底離台、穿台與 overlap 漏檢。 + +### 117.1 通道架構(game/systems/visualScale.ts,場景鍵入單例) + +- 沿 §77.2 蹲姿/§45 走 bob 已驗證的 PRE/POST_UPDATE 視覺通道模式全遊戲統一: + `PRE_UPDATE` 還原物理基準(物理步只見基準)、`POST_UPDATE` 套用 + `base × fx × mod`(渲染見形變);tween 一律以 fx 代理為標的,物理永不見瞬態縮放。 +- 三層語意:`base`=物理基準(精英體型、鑽地鰭、半潛、縮殼、月牙縮體、裸核、 + texture 切換後 rebase);`fx`=tween 代理(squash/stretch、popIn、wobble、翼拍、 + 怒吼脈動、死亡收縮);`mod`=逐幀直寫(idle 呼吸、蹲縮),擁有者每幀維護。 +- 覆蓋面:玩家(擠壓/呼吸/蹲縮/受擊)、18 怪(popIn/wobble/呼吸/死亡/狀態造型)、 + 五王(wobble/翼拍/攻擊擠壓/怒吼/碎裂/死亡/相位縮體)。柱/爪/糖泉等升起中的 + 危害判定屬蓄意成長 hitbox,維持直接縮放不遷移。 +- 補丁退場:`LANDING_SQUASH_MIN_VY`(§77.1 單案例門檻)刪除——擠壓不再縮物理箱, + 任意著地皆可安全觸發;碰撞箱不再隨 wobble 每拍脈動(怪 ±8%、魔王 ±5-7%)、 + popIn 生成期物理箱不再僅 30%。 +- 行為錨:visualScale.test 鎖住「動畫期間物理讀取窗 scale 恆為基準」契約與 + 池重用重錨、shutdown 清理語意;行為零改變由全量 vitest+e2e 全套+ + level-audit L1/L14/L16 EX 對比 base 佐證。 diff --git a/apps/starpuff/docs/design/01-controls-input.md b/apps/starpuff/docs/design/01-controls-input.md new file mode 100644 index 000000000..b81950b61 --- /dev/null +++ b/apps/starpuff/docs/design/01-controls-input.md @@ -0,0 +1,373 @@ +# 星噗噗 — 操作、輸入與虛擬鍵布局 + +> **職責範圍**:玩家怎麼操作遊戲。搖桿與 A/B/SP 鍵語意、跳躍與下衝擊輸入矩陣、觸控寬容度與真實手勢判定、走動與移動手感、直持旋轉殼與座標換算,以及虛擬鍵布局 SSOT 與按鈕配置頁。 +> +> **不在本檔**:按下之後發生什麼事——星彈與技能效果見 `02-combat-star.md`;暫停選單、主選單、HUD 命中層見 `06-ui-shell-pwa.md`;偏好如何持久化見 `05-save-settings.md`。 +> +> **現行輸入 SSOT = §109**(B 鍵三語意+SP 情境鍵);§23/§57 的長按觸發面已退場。 +> +> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 + +## 4. 操作(行動裝置優先) + +- 左半屏:浮動搖桿(觸點即中心、半徑 60px、死區 12px;水平移動 + 下向偵測供下衝擊,規格見 §21)。 +- 右側:A/B 圖形圓鍵(斜排布局 v5 已由 §34 取代:B 移右側偏上食指區、位置可自訂)——A 跳躍(空中連按=拍翅漂浮,最多 3 次,落地重置);B 吸/射(無彈藥=按住吸入;有彈藥=點按發射,長按仍可吸)。 +- 鍵盤(桌機備援):←→ / Z 跳 / X 吸射。 +- 全域:`touch-action: none`、禁雙擊縮放、首次觸控解鎖 AudioContext。 + +## 21. v3 橫式轉向(PM 親撰) + +- 邏輯畫布 854×480(橫式),Scale.FIT + CENTER_BOTH;manifest orientation 改 landscape(v4 已由 §28 免轉向旋轉殼取代:manifest 不鎖 orientation);直向持機時顯示「請轉橫」遮罩(v4 已由 §28 免轉向旋轉殼取代:遮罩廢除)。 +- 世界尺寸:高 480;寬放大至 S1 2700 / S2 3100 / S3 3500(視野變寬 1.78 倍,維持等效走動時長);平台改雙層以內(天花板變低),高度差以跳躍 -420 可達為準。 +- HUD 重排:頂列橫排——HP 心心左上、STAGE 標示中上、配額右上;Boss 條頂中置。全部 HUD 圖示改 graphics 繪製(星形/心形程序化),全遊戲禁用 emoji 與文字字元鍵帽。 +- 虛擬手柄(參考實體手柄配置):左側浮動搖桿(觸點即中心、半徑 60px、死區 12px、水平為主 + 下向偵測供下衝擊);右側 A(跳,右下)/ B(吸/射,A 左上 45 度)雙鍵 64px+ 斜排、間距 16px+(v5 已由 §34 取代:B 移右側偏上食指區、支援拖曳自訂布局);橫持 iPhone safe-area 側邊 inset 必須套用。按鍵一律 canvas/CSS 繪製圖形(無文字節點)。 + +## 22. iOS 觸控直通(研究回寫後定稿) + +- 已知基線:控制層與 canvas 套 `-webkit-touch-callout: none`、`-webkit-user-select: none`、`user-select: none`、`touch-action: none`、`-webkit-tap-highlight-color: transparent`;pointerdown/contextmenu preventDefault;按鍵不含可選取文字(無障礙走 aria-label)。 +- 長按放大鏡(iOS 17+ text loupe)根除:按鍵去文字化 + callout/select 全關 + 必要時 touchstart passive:false preventDefault——以調研結論為準補齊。 +- 研究項:Safari gesturestart 縮放攔截、standalone PWA 與瀏覽器內差異、audio unlock 於橫式的相容性。 + +## 28. v4 免轉向橫式與響應寬幅(PM 親撰) + +- 免轉向:偵測 portrait viewport 時,以 CSS 旋轉容器方案將整個遊戲容器(canvas + DOM 控制層)旋轉 90 度呈現橫式——使用者直持手機即玩,不再顯示轉橫遮罩(遮罩廢除)。技術定案依調研回寫(Phaser 4 相容性、pointer 座標映射、safe-area 換軸)。(v14 已由 §87 取代預設旋轉方向:預設 ccw(rotate -90deg、鏡頭朝右),cw 舊方向降為可切換偏好。) +- 響應寬幅:邏輯高固定 480,寬依裝置比例擴展(下限 854、上限 1200);Scale 模式依調研定案(EXPAND/RESIZE 擇一)。HUD 錨定鏡頭邊緣自適應;世界生成邊距、星星門偵測、boss 單屏佈局以動態視寬計算,禁止硬編 854。 +- 驗收基準機型:390×844(iPhone 13 直持)、430×932(Pro Max 直持)、844×390(橫持)三態皆可玩。 + +## 34. v5 控制布局重設計與按鈕自訂 + +- 人體工學定案(§33 條目 7):雙手橫持時拇指錨於下側角、食指自然落在裝置上緣——A 跳躍維持右下(拇指連打),B 吸/射移至右側偏上(食指按壓;與 A 垂直遠離杜絕誤觸);方向搖桿維持左半屏。 +- 布局 SSOT:`core/layout.ts`——按鍵中心以 keys-layer 安全區內比例(cx/cy 0-1)表示,直橫持共用;`DEFAULT_LAYOUT`:A (0.92, 0.78)、B (0.92, 0.34)。(v16 已由 §95 取代「預設」的直持適用性:預設依殼旋轉態分流 `defaultLayoutFor`,直持採右下拇指帶錨點;自訂布局仍直橫持共用。) +- `#keys-layer`:安全區內鋪滿的定位容器(四向 `max()` 地板+portrait 換軸表),按鍵以 `left/top %` + `translate(-50%,-50%)` 定位。 +- 按鈕自訂(KISS:拖曳+儲存+重置,不做進階編輯器)(v19 已由 §118.1/§118.2 取代入口與儲存位置:入口自 Title 直鈕改為設定頁轉入,布局改存 `sp-settings.keyLayout`,`sp-key-layout` 僅作 migration 來源):Title「按鈕配置」→ `systems/keyConfig.ts` DOM 覆層——直接拖曳真實 A/B 鍵即時預覽,「儲存並返回」寫入 localStorage `sp-key-layout`(schema `{version:1, a:{cx,cy}, b:{cx,cy}}`;版本不符/損毀回退預設),「恢復預設」一鍵還原。拖曳座標經 `pointerToLocal` 換軸,夾限 `KEY_CLAMP` 保證按鍵完整在畫面內。(v14 已由 §88/§89 取代操作列結構與 schema:schema 升 v2 增全域縮放、操作列直欄化並增持向切換與縮放列。) + +## 41. v6 移動手感打磨(logic/movement.ts,pure TS 可測) + +- 加減速曲線取代瞬時 setVelocity:加速 1400px/s²(約 0.16s 達全速 220)、減速 2000px/s²(約 0.11s 停定)、反向轉身加+減速疊加率(即刻有力);殘速 <8 吸附歸零防微速漂移。 +- 超速殘速(擊退 234 等)先夾回常速帶再逼近,無殘速滑行(v7 §44 移除疾衝後僅餘擊退來源)。 +- 手感事件(邊緣觸發,`detectMoveFx`):起跑塵埃(靜止起步)、急停塵埃(高速鬆手 ≥160)、轉身塵埃+小幅擠壓(高速反向 ≥120,遮蓋翻面瞬間)。塵埃 ≤4 顆/次、tween 自毀,60fps 安全。 +- 既有落地 squash(§18)、走路 bob(§18/§25 PRE/POST_UPDATE 視覺偏移)維持不動;嚴禁重新引入抖動——相機 lerp(1,1)/roundPixels:false 現值不動,改後必跑既有抖動與 portrait e2e(本版已全綠)。 + +## 44. v7 下衝擊觸發改制與跳躍鍵輸入矩陣(PM 親撰,取代 §23 下+B 觸發) + +- 下衝擊改為「空中搖桿下+跳躍鍵(A)」觸發:B 鍵回歸純吸/射/技能語意,空中吞含 + (puffed,腹中有怪)狀態不影響觸發——矩陣不讀彈匣。數值不變(下墜 700、落地 60px + 衝擊波傷害 2、CD 1.2s、零彈藥消耗、可破磚)。 +- 空中疾衝(§30 Air Dash)整體移除:雙擊 A 與拍翅節奏衝突且誤觸率高;相關輸入、 + 純邏輯、殘影 fx、音效、圖鑑條目與測試全數清除(movement 夾速鏈保留供擊退殘速)。 +- 跳躍鍵輸入矩陣(`logic/skills.ts` `resolveJumpPress`,pure TS 可測): + +(v10.1 已由 §71.1 補訂:「空中」判定收斂為真空中——coyote 窗內視同在地不觸發下砸; +地面主地面下+跳自 §71.2 起帶蹲姿視覺,跳躍裁決不變。) + +| 情境 | 下 | 跳 | 裁決 | +| -------------- | --- | --- | --------------------------------------------------------------------------------- | +| 空中(CD 完) | ✓ | ✓ | 下衝擊(吞含狀態同樣觸發;§71.1:coyote 歸零的真空中才成立) | +| 空中(CD 中) | ✓ | ✓ | 回落一般跳躍鏈(拍翅/buffer),不吞輸入 | +| 空中 | ✗ | ✓ | 拍翅(≤3 次)/ jump buffer | +| 地面站單向平台 | ✓ | ✓ | 下落穿透(§29 `shouldDropThrough` 於 stage 層裁決,覆蓋跳躍脈衝——既有優先序不變) | +| 地面主地面 | ✓ | ✓ | 一般跳躍(無蹲下語意,無衝突) | +| 地面 | ✗ | ✓ | 一般跳躍(coyote/buffer 寬容不變) | + +## 45. v7 走動手感根修與抖動歸因(logic/walkFeel.ts,pure TS 可測) + +- 根因結論(依序排查證據,`sp-jitter-probe` 逐幀取樣): + 1. 物理 velocity 震盪:無(approachVelocity 曲線平滑)。 + 2. render rounding:無(roundPixels:false 現值正確,維持不動)。 + 3. camera 耦合:剛性跟隨段 screen-space 幀間位移恆 0(角色與捲軸完全同步);非跟隨段 + (相機貼世界邊緣)幀間位移呈 0/3.667/7.333px 三值跳動——根因為 Arcade fixedStep + 60Hz 與渲染幀率錯拍(單一渲染幀吞 0/1/2 個物理步)。實測 `fixedStep:false` 可消除 + 該錯拍但在低幀率下重力穿地(8 連測 1-2 次沉地 ~80px、彈簧判定帶失效)——**裁決維持 + fixedStep:true(確定性物理),禁止以 variable step 或全域取整掩蓋**。 + 4. sprite anchor / CSS 旋轉殼:無異常(座標鏈 §28/§34 現值正確)。 + 5. 動畫姿態層:v5「走動不像走動」主因——貼圖平移滑行,僅低頻 bob,無步頻/姿態/音畫拍點。 +- 速度驅動步頻系統(零新素材,程序化): + - 相位累積 ∝ |vx|/moveSpeed,全速步頻 3.2Hz;停走相位歸零凍結。 + - y 軸 bob:|sin| 雙頻小彈跳(峰值 3.2px,速度比縮放),沿用 PRE/POST_UPDATE 視覺 + 偏移通道(不污染物理)。 + - 前傾 lean 0.06rad + 步頻搖擺 sway 0.045rad(面向鏡像);空中依 vy 前後傾 + (上升後仰 -0.1、下墜前傾 +0.14 夾限)。 + - 落腳拍點(|sin| 每半週期回零):池化腳塵 emitter explode ×2+低量 footstep zzfx。 + - idle 呼吸:週期 2.4s、scaleY ±1.8%(squash tween 進行中讓位)。 + - 既有起跳 stretch / 落地 squash / 起跑急停轉身塵埃(§41)維持不動。 + - 主角輪廓對比(三席審查補修):深紫剪影背襯(本體 1.1 倍 FILL tint image,POST_UPDATE + 鏡像貼圖/翻面/縮放/bob),草原亮底對比 1.81:1 提升至實測 10.23:1(≥3:1 門檻); + 不用 Glow filter——SwiftShader/低階 GPU 逐幀模糊採樣致幀率崩跌。 +- 幀證據:`screenshots/starpuff-v6/before/`(v6 基準連拍)與 `screenshots/starpuff-v6/after/` + (v7 步頻連拍+idle 呼吸);e2e 行為斷言走 `__sp.walk()`(rotation 振盪、bob>0、停走歸零)。 + +## 77. v11.1 熱修:下跳穿落根修、蹲姿指示與吸入豁免 + +### 77.1 站台「下+跳」穿落回歸根修(補訂 §29/§44) + +> 2026-07-26 取代注記(§117):本節根因鏈第 1 點「擠壓縮小 body」的耦合已由 +> visualScale 物理/視覺解耦通道根治——物理箱永不隨美術縮放,`LANDING_SQUASH_MIN_VY` +> 門檻補丁退場;`recentlyGroundedMs`/`restingOnOneWay`/`oneWayLandBand` 屬獨立 +> 語意修正(coyote 收斂、旗標抖動免疫、下砸防隧穿),維持有效。 + +**根因鏈**(worldstep 逐步 trace 實證): + +1. 落地擠壓 `squashStretch(1.25, 0.75)` 於每次「重新接觸」觸發——擠壓縮小 body + (scale 連動 `Body.updateBounds`)使腳底離台 → 微墜再落地 → 再擠壓,形成 ~20Hz + 自持迴圈;站立時接觸旗標(blocked/touching.down)僅 ~1/3 物理步為真。 +2. 「下+跳」落在假空中幀(~2/3 機率)時被 v7 下砸(`resolveJumpPress`)誤判接管; + 下砸啟動擠壓(scaleY×1.3)使身體單步位移 ~22px,超過 Phaser `OVERLAP_BIAS(4)+ΔY` + 防隧穿上限而貫穿單向平台——玩家所見即「有時暴力穿落、有時原地跳」的不確定行為。 +3. `standingOnOneWay` 舊 ±4px 容差小於迴圈震盪幅度(4.7px),接觸幀也會間歇漏判。 +4. 地形粉紅平台(`GameScene.addTerrain`)從未接入下穿系統,僅能靠隧穿 bug 下降。 + +**修法**(四點聯動,均有單測): + +- 落地擠壓加最低著地速度閘 `LANDING_SQUASH_MIN_VY=120`:微速重新接觸不再擠壓, + 迴圈斷根(實測站立接觸穩定度 120/120 步)。**已退場(§117 根治)**:解耦後擠壓 + 不再縮物理箱,門檻無存在必要。 +- `resolveJumpPress` 增 `recentlyGroundedMs`(傳 coyote 殘量):coyote 窗內視同在地, + 下砸僅「真空中」(離地 >150ms)觸發——§44 矩陣「空中」行語意收斂為真空中。 +- 站台判定抽 `stageModel.restingOnOneWay` 純函式:接觸旗標**或**沉降幾何 + (腳底於台頂 −6..+8px 帶內且 0 ≤ vy ≤ 90)擇一成立,對旗標抖動免疫。 +- 著地帶 `oneWayLandBand(stepΔY)=max(6, ΔY+2)` 動態放寬:下砸(~11.7px/步)與高處 + 落下不再隧穿單向平台;低速維持 +6 緊帶防側切。 + +**地形平台統一**:粉紅平台掛 `canLandOneWay` process callback+`terrainOneWay` hook +納入同一下穿裁決——玩家視角所有「單向平台」下+跳皆可穿落(S1 教學一致性)。 + +### 77.2 蹲姿視覺與跳鍵下跳指示(§21 控制補訂) + +- 蹲姿:地面壓下 120ms 內壓扁(scaleX +14%/scaleY −22%)+下沉 3px; + `walkFeel.advanceCrouch` 純函式驅動,走 bob 同款 POST_UPDATE 視覺通道、 + PRE_UPDATE 還原——**物理永不見蹲縮**(防 77.1 擠壓迴圈同型問題)。 +- 下跳指示:壓下且站單向平台(跳鍵此刻=下跳)→ 跳鍵轉琥珀+鍵帽箭頭翻轉朝下 + (`is-drop-ready` class,純 CSS clip-path 旋轉,零文字零 emoji);鬆開或離開 + 可穿落狀態即還原。決策重用 `shouldDropThrough`(單一裁決來源),controls 層 + 邊緣偵測 class 切換不逐幀碰 DOM。 + +### 77.3 吸入接觸豁免(§5 吸入補訂) + +- 規格:**被吸入中**(拉力作用中)的怪對玩家無接觸傷害;吞下判定照舊;未被吸入 + 的其他怪照常傷害——不做吸入全程無敵,風險回報保留。 +- 實作:`combat.inhaleGraceUntil / isContactHarmless` 純函式——`applyInhalePull` + 拉力逐幀刷新 250ms 豁免窗,接觸結算單點查窗;吸入中斷(鬆開/轉向/離錐)後 + 窗過期即恢復傷害性;enemies spawn 池重用重設防跨個體殘留。 +- 根因:拉近中的怪貼身瞬間(轉向/鬆開/出錐殘餘飛行)觸發受擊,實測 12-25% 命中; + 拉力結算與接觸結算間缺「被吸入中」狀態橋接。 + +### 77.4 吸入大嘴影格(素材;§61 慣例沿用) + +- `hero-inhale-big-1/2`(codex imagegen,512×512 webp 透明背景):吸入姿勢嘴部 + 誇張放大兩段影格,啟動吸入後兩影格 ~160ms 交替營造吸力節奏;素材未載入時 + 回退既有 `hero-inhale`(tex fallback 慣例)。 + +## 85. v12.1 熱修:真實觸控下滑判定重修(補訂 §21/§23/§77) + +> §77 修復對「教科書式垂直長滑持住」有效,但真實拇指手勢(CDP 真觸控模擬實證) +> 四路全掛,生產回報「下滑+跳」仍不能下穿、蹲姿與琥珀鍵不出現。本章取代 §23 的 +> 下向判定與 §77.2 的指示觸發條件。 + +### 85.1 根因鏈(五情境真觸控探針實證) + +1. **底緣行程不足**:左手拇指自然定錨貼屏幕下緣,touchStart 後下滑物理行程僅剩 + 15-25px,舊閾值 30px(半徑一半)永遠達不到——蹲姿不出、鍵不變色、按跳變上跳。 +2. **flick 抬指**:真實手勢多為「滑完即抬指、數十至數百 ms 後按跳」;down 隨抬指 + 歸零,按跳瞬間已失去下向語意。 +3. **斜下滑帶走玩家**:拇指自然下滑常帶 ±20-45 度斜角,dx 分量觸發走路 + (220px/s)把玩家帶出平台邊緣;蹲姿因離地永遠到不了位。 + +### 85.2 修法(三點聯動,均有單測+真手勢 e2e) + +- **扇區+幅度判定**:`isJoyDown(dx, dy)` 改為 `dy ≥ 18px` 且向量在正下 ±60 度 + 扇區內(`|dx| ≤ dy·tan60°`);18px 高於死區(12)防誤觸、接住底緣短行程, + 扇區容納自然斜下滑、排除近水平走路語意。 +- **drop-intent 緩衝窗**:`advanceDownBuffer` 純函式維護 300ms 窗——down 釋放後 + 窗內 `downBuffered` 仍真;stage 下穿裁決(`shouldDropThrough`)與跳鍵琥珀指示 + (`isDropReady`)改吃 `downBuffered`,flick 後按跳仍判下跳。空中下砸 + (`resolveJumpPress`)維持即時 down,不吃緩衝窗防誤觸。 +- **蹲下鉗水平**:地面 down 成立即 `moveTarget=0`(平台遊戲蹲下靜止慣例), + 斜下滑不再把玩家帶出平台;空中不鉗,保留下砸前橫向微調。 + +### 85.3 真實手勢守門(e2e 常備) + +- CDP `Input.dispatchTouchEvent` 走瀏覽器觸控合成路徑(hit-testing、pointer + capture、多指分路全真),取代理想化 `dispatchEvent` 合成 pointer——防止未來 + 再以理想化輸入製造假綠燈。 +- 常備三變體:左手下滑持住+右手第二指點跳;flick 抬指停頓 150ms 再點跳; + 斜下 45 度滑動(斷言蹲住不位移+穿落成功)。 + +## 87. v14 直持預設旋轉方向翻轉(取代 §28 預設方向) + +### 87.1 背景與決策 + +- 使用者反映 v4–v13 的直持旋轉方向(cw:rotate 90deg、手機逆時針轉、鏡頭朝左) + 「沒有滿版的感覺、按鈕變成靠邊邊」;v14 翻轉預設為 ccw(rotate -90deg、 + 手機順時針轉、鏡頭朝右),瀏海側換至遊戲畫面右緣。 +- 方向與座標換算 SSOT 收斂至 `core/rotation.ts`:`ShellRotation`(none/cw/ccw) + 三態、`pointerToLocal` 統一逆變換(cw:localDx=screenDy、localDy=-screenDx; + ccw:localDx=-screenDy、localDy=screenDx);controls/keyConfig/shellLayout + 一律經本模組取向換算,禁止各自複製公式。 +- CSS:預設殼 `top:100%; left:0; rotate(-90deg)`(ccw);`html.sp-rot-cw` 切回 + 舊方向。safe-area 換軸表雙套:ccw=裝置 left→殼上、top→殼右、right→殼下、 + bottom→殼左;cw 維持 v4 原表。 +- 偏好持久化:localStorage `sp-rotation`('cw'|'ccw',缺省=ccw 新預設; + 不進 save schema);讀取走記憶體快取(pointer 熱路徑不重複讀 storage)。 + (v19 已由 §118.1 取代儲存位置:收斂為 `sp-settings.shellRotation`, + `null`=從未選擇;`sp-rotation` 僅作一次性 migration 來源,落盤後刪除。 + 記憶體快取語意不變。) + +### 87.2 回訪玩家保護(肌肉記憶) + +- 既有玩家(存檔有進度且未曾設定持向偏好——v19 §118.1 即 + `sp-settings.shellRotation === null`)首次進站於 Title 顯示一次性 + 方向告知卡(§92 殼層卡片):說明新方向並提供「切回舊方向」一鍵; + 已示記憶 localStorage `sp-rotation-notice`。全新玩家無感知不打擾。 +- 持向切換入口常駐「按鈕配置」操作列(§88),納入草稿語意:切換即時預覽、 + 儲存才落地、取消回滾。 + +### 87.3 驗證 + +- 座標矩陣單測(rotation.test.ts 九案):三態四角/中心/滑動向量映射斷言。 +- portrait e2e 雙案:ccw 新預設(上滑=往右)+持向偏好設為 cw 的舊方向回歸 + (下滑=往右、殼 matrix 斷言)。畫布覆蓋率 99.98% 不變。 + +### 87.4 方向解鎖引導+桌機正置(#817,T2) + +- 桌機判定(`detectDesktopEnvironment`,rotation.ts SSOT):`pointer:fine` 且 + `maxTouchPoints===0` 且視口寬 ≥1024——boot 一次判定掛 `html.sp-desktop` class + (session 內 SSOT,JS 與 CSS 恆一致)。 +- 桌機模式:方向恆正(`getShellRotation()` 恆 none+CSS 旋轉殼旁路)、虛擬鍵隱藏 + (鍵盤唯一操作面)、首次鍵位卡(← → 移動/Z 跳/X 吸射,記憶 `sp-desktop-keys`)、 + Title 常駐「操作說明」入口(`data-menu="keys"`)隨時重看。 +- 直持引導:卡片顯示當下仍為 portrait(延遲期間未轉橫=方向鎖定啟發式)→ 一次性 + shellCard「橫持遊玩體驗更佳(鏡頭朝右)」,記憶 `sp-orientation-hint` 不重複打擾; + 觸控裝置(含觸控筆電)恆不進桌機模式,旋轉殼語意保留。 +- e2e(t2.spec.ts 三情境 × 三 project):桌機(殼 transform none、#controls 隱藏、 + 鍵位卡一次性、鍵盤可操作)/直持未解鎖(提示卡一次性)/橫持(雙卡皆不誤觸)。 + +## 88. v14 按鈕配置頁操作列直欄化與標籤單行(取代 §34 操作列) + +- 根因:cfg-bar 橫排 flex 無寬度約束且鈕可壓縮,375/667 級殼寬下 + 「儲存並返回」被壓成兩行。 +- 修法:cfg-bar 直欄(提示列+操作列+縮放列分列)、`.cfg-btn` + `white-space:nowrap`+`flex-shrink:0`(禁字內斷行)、空間不足整鈕換列; + 「儲存並返回」精簡為「儲存」。 +- 驗收:854/1200 邏輯寬 × 直橫持 × 新舊持向矩陣全標籤單行(visualH=44)。 + +## 89. v14 虛擬鍵大小自訂(sp-key-layout schema v2) + +- schema v1→v2 versioned migration:v1 舊存檔鍵位保留、`scale` 補預設 1; + 未知版本回退預設。v2:`{version:2, a, b, scale}`,scale 夾限 0.8–1.3。 + (v19 已由 §118.1 取代儲存位置:**schema 形狀不變**,改存於 + `sp-settings.keyLayout` 子樹;`sp-key-layout` 僅作一次性 migration 來源。) +- 縮放經 CSS 變數 `--sp-key-scale` 單點驅動鍵體與鍵帽(clip-path 圖形同步), + 觸控熱區隨元素幾何自然同步;`KEY_BASE_PX`(A76/B72)與 style.css 以單測 + 跨檔守門防雙寫漂移。 +- 操作列縮放列:縮小/放大步進 5%+百分比顯示;即時預覽、儲存持久化、 + 取消回滾;與拖曳位置共存(夾限以縮放後 offsetWidth 計算)。 +- 觸控下限守門:最小縮放 80% 時最小鍵 57.6px ≥ 44px(單測)。 + +## 95. v16 直持預設鍵位重錨(D1,取代 §34 預設在直持殼的適用性) + +### 95.1 根因與決策 + +- 三席批評(Grok 席,PM 數學覆核成立):§34 預設鍵位以 keys-layer 層比例定義 + (A 0.92/0.78、B 0.92/0.34),直橫持共用;直持旋轉殼下層座標軸與裝置軸互換, + 同組比例把 A/B 映射到裝置螢幕頂端(實測 A 裝置 y≈78px、fy≈0.09),雙拇指 + 直握不可及——v14 只修了搖桿半邊(左半屏映射到裝置下半),按鍵半邊漏修。 +- 修法:預設分流、自訂不動。新增裝置比例錨點 SSOT `PORTRAIT_THUMB_ANCHORS` + (A fx 0.82/fy 0.86、B fx 0.80/fy 0.68——右下拇指帶、B 沿拇指弧在 A 上方), + `defaultLayoutFor(rotation)` 依殼向反算層比例:ccw cx=1−fy、cy=fx; + cw cx=fy、cy=1−fx(§87 軸向映射逆向);橫持沿用 v14 定案。 +- schema 不動(鍵位布局 v2 零遷移,§89):合法自訂資料在任何持向原樣適用; + 只有「無自訂/損毀回退」與「恢復預設」走旋轉感知預設。 +- 直持下 A/B 幾何上與 joy-zone 重疊(裝置下半即遊戲左半):keys-layer 為後繪 + 兄弟層,按鍵天然承接命中;誤觸空白處僅錨定浮動搖桿(點按零位移,無害)。 + +### 95.2 儲存語意(配置頁) + +- 預設態不落盤:從未自訂或按過「恢復預設」後儲存=清除布局(v19 §118.1: + `sp-settings.keyLayout` 置 null,v14–v18 為清除 `sp-key-layout` 鍵,語意等價), + 直橫持各自動態解析預設;拖曳/縮放屬自訂,儲存持久化具體布局(維持 v14 + 單一共用布局語意)。 +- 「恢復預設」依當前草稿持向給對的錨點;持向切換(cw/ccw)時預設態即時重映射, + 自訂布局不動;拖曳逆變換取草稿持向(修正切換未儲存期間軸向錯置)。 +- 局中轉向重套:controls 進場後監聽 resize(200ms)/orientationchange(400ms) + 重新解析布局,orientation 切換不殘留舊向預設。 +- CSS fallback 鏡像:style.css portrait 區塊鏡像反算值(14/82、32/80;cw + 86/18、68/20),JS 載入前鍵位即在拇指帶;單測跨檔守門防雙寫漂移。 + +### 95.3 驗證 + +- 單測 layout.test.ts:前向模擬(層比例→殼→裝置座標,390×844 含 inset)斷言 + cw/ccw 雙向 A/B 落帶、AB 裝置距離 ≥90px、夾限相容、錨點反算一致性、 + 深拷貝、CSS 鏡像;parseLayout 旋轉感知回退與 v1/v2 自訂資料不受旋轉影響。 +- e2e portrait.spec.ts:D1 案——幾何斷言(A fx≥0.72/fy 0.78–0.95、B 上方帶)+ + 真手勢(CDP dispatchTouchEvent 走瀏覽器 hit-test)點 A 起跳(walk().vy<0)、 + 點 B 進入按壓態;cw 舊方向案補同帶幾何斷言。 +- 前後對照截圖 screenshots/starpuff-v16/d1-\*.png(before A fy 0.092 → after 0.850)。 + +## 102. v16 配置模式遮罩加深(F-04,補充 §34) + +- 根因(Composer 席):cfg-overlay 0.4 透明度下主選單文字仍清晰,與配置列 + 形成「哪層可互動」的視覺競爭。 +- 修法:遮罩加深至 0.62+backdrop 輕模糊 2px——主選單退為背景;虛擬鍵與 + 操作列(z 10/40)浮於遮罩(z 5)之上不受影響。 + +## 109. v19 星暴 2.0+SP 情境鍵+B 鍵收斂(#815,修 #812 輸入面;輸入層 SSOT) + +外部評審 P0-3(B 鍵五語意超載)與 #812(星暴長按誤放清匣卡關)的根治:輸入仲裁 +狀態機重寫。機制 brief §2–§3 落地;本節為現行輸入 SSOT,取代 §23 星暴長按行、 +§40 滿匣讓位行與 §57 觸發面(各節已加取代標註)。 + +### 109.1 B 鍵最終語意(僅三項,`resolveActionPress`) + +| 操作 | 條件 | 行為 | +| -------------- | ------------ | -------------------------------------------------- | +| 點按(<150ms) | 有彈藥 | 發射(後進先出;滿匣亦即按即射,不再 defer) | +| 按住 | 頂槽非殼盾星 | 吸入 | +| 按住 | 頂槽殼盾星 | 舉盾(殼盾情境走延遲:放開 <150ms 結算為點按發射) | + +**退場**:長按 0.8s 星暴、地面長按 0.6s 變身——全部移出 B 鍵(誤觸根因消滅); +`advanceStarstormHold`/`starstormReady`/`starstormProgress`/`resolveTransformHold` +自 logic 層刪除。 + +### 109.2 SP 情境鍵(唯一新輸入面;`logic/starburst.ts`+`controls.setSpMode`) + +- 位置:右側 B 鍵「裝置空間上方」食指區 52px(48–56 帶內),恆由 B 鍵位置派生 + (`layout.spKeyPosition`,cw/ccw 旋轉殼換軸沿 §87 映射;不入自訂布局 schema, + 拖曳 B 鍵時跟隨);僅「有技能可用」時淡入 150ms 浮現,無技能完全隱藏。 +- 圖形:子 canvas 繪製(禁 emoji/文字鍵帽)——蓄能星暴=金色大星;變身=形態色 + 圓徽(tint 取 `TRANSFORM_FORMS` SSOT);變身中=解除迴旋箭。浮現輕震一次 + (沿 §91 觸覺管線,尊重靜音偏好)。 +- 語意(天然互斥,`resolveSpPress`;圖示即行為,`resolveSpMode` 同序): + 1. 變身中 → 點按=提前解除(優先序最高,圖示一致性)。 + 2. 蓄能星存在 → 點按=引爆星暴。 + 3. 無蓄能星且變身資格成立(同系 ≥3、地面)→ 點按=立即變身(0.6s 門檻廢除)。 +- 鍵盤映射:`C`=SP(`Z` 跳、`X` 吸/射不變);§89 桌機鍵位卡與 Title 操作說明 + 同步標示。 + +### 109.3 星暴 2.0——蓄能結晶+手動引爆 + +- 彈匣擴為 5 槽(`STAR.maxAmmo`);滿 5 槽瞬間**自動結晶**——彈匣清空、頭頂 + 生成蓄能大星(金色自轉+呼吸縮放+微光暈,頭頂 22px 軌道,`systems/chargedStar`); + 結晶後立即可繼續吸怪(anti-softlock:基礎星彈吸怪循環即時可用)。 +- 不疊加:蓄能星存在時再滿匣不再結晶(HUD 滿匣金色脈動提示;彈匣維持滿可正常 + 射擊/殼盾)。變身窗口=同系 3–4 發按 SP;滿匣即選擇星暴線(L3 hint 明示一次)。 +- 跨關持有/死亡清除/EX 進場清除:session 記憶(`systems/starburstDirector`, + 不動 save schema);首次結晶浮字「星力結晶!按 SP 鍵引爆」、首次帶星過關 toast + 「蓄能星會跟你到下一關」各一次。已知行為(設計取捨):detonating 相位過關 + (0.3s 蓄爆窄窗撞入門)不持有也不結算——引爆效果隨場景凍結靜默丟棄。 +- 引爆:SP 點按 → 0.3s 蓄爆(`STARSTORM.chargeMs`,不可取消)→ 清場全小怪+ + 魔王 12 傷+5s 無敵窗(沿 §64.2 取 max 不疊加)+既有震屏白閃星雨呈現。 +- 事件契約:新增 `STARBURST_CHANGED { phase }`(producer player;consumer + starburstDirector/e2e);`SKILL_STARSTORM` 世界結算管線不變。 +- 驗收(§108 探針改口徑;序列化單跑官方真值):引爆需顯式 SP 點按(e2e 守 B 長按 + 不觸發);引爆後零彈恢復全 15 走動關 90 樣本 pooled p95 8.85s ≤10s(T2 交付基線 + 9.5s,無回退且略優)、45s 未恢復=0;最難尾 L14 同樣本量 22.6s→12.2s 顯著改善。 +- 平衡 A/B 對照(審查收斂輪;main@977968280 vs v19 HEAD,cap 420s、序列化, + L6 mid 各 6 樣本、其餘各 3;JSON 留檔 `level-audits/ab-*`): + L2 mid 33%→100%(122.8→94.3s)、L2 high 雙 100%;L6 mid 雙 67%(通關均時 + 194→317s,見下方觀察項)、L6 high 0%→33%(基線既有困難,v19 略優); + L12 魔王 mid/high 雙 100%(TTK 11.1→10.6s/18.8→17.4s)。裁定:短 cap + (120–300s)×runs 2 的 L6 clearRate=0 量測為口徑假陽性——base 通關樣本均時 + 194s、v19 317s,短 cap 會把兩者都截成 0%;clearRate、ammoZero 峰(17.2 vs + 16.8s)與飢荒峰皆同水準,「5 槽惡化火力節奏」不成立,無回歸。 + 觀察項(非門檻):L6 mid 通關均時 +123s 偏移——bot 滿匣結晶後引爆時機非最優 + 所致,人類玩家可自主擇時;列 T4 教學矩陣觀察清單,門檻指標全數持平不調參。 diff --git a/apps/starpuff/docs/design/02-combat-star.md b/apps/starpuff/docs/design/02-combat-star.md new file mode 100644 index 000000000..28b550ee9 --- /dev/null +++ b/apps/starpuff/docs/design/02-combat-star.md @@ -0,0 +1,167 @@ +# 星噗噗 — 戰鬥數值、星彈系統與變身 + +> **職責範圍**:吸入→吞下→發射這條主循環的所有規格。基礎戰鬥數值、九系星味與混合星表、殼盾與雷鏈、星化三形態能力表與教學矩陣。 +> +> **不在本檔**:觸發這些能力的按鍵語意(見 `01-controls-input.md` §109);星暴蓄能與引爆的輸入面同樣在 §109,其 5s 無敵窗規格在 `03-enemies-bosses.md` §64.2(與 Noctra 熱修同章)。 +> +> **硬不變式**:混合星與變身**永不為破關必需**——基礎星彈恆可通關(§46/§57/§110)。 +> +> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 + +## 7. 戰鬥數值 + +- 玩家:移速 220px/s、跳躍初速 -420、漂浮升力 -260、重力 900。 +- 吸入:長按 ≥150ms 啟動、錐形範圍 140px、拉力漸增;吞下 +1 彈藥(上限 5,v19 §109)。 +- 星彈:傷害 5、速度 520、穿透 1 隻小怪、命中魔王消失。 +- 邏輯畫布:854×480(橫式,Scale.FIT;v4 改 NO_CENTER 由旋轉殼定位,見 §28);解析度採 Scale.FIT 自適應,不做 DPR cap(欄位已於修復包 B 移除)。 + +## 20. 技能系統:吞噬賦星(v2.1,PM 親撰) + +吞下的怪決定星彈屬性(最後吞下者覆蓋既有彈藥屬性),表驅動實作(config 一張表,禁止散落分支)(v6 已由 §40 擴充為五系:shelly 殼盾星、zappy 雷鏈星,取代 v4 的標準星/疾風星代位): + +| 吞下 | 星彈屬性 | 效果 | 視覺 | +| ------ | -------- | ----------------------------------- | ------------------------------- | +| jelly | 標準星 | 傷害 5、速度 520、穿透 1 | 金黃 #FFD966 | +| floaty | 疾風星 | 傷害 5、速度 650、穿透 2 | 藍紫 tint #A78BFA、拖尾加長 | +| puffy | 爆裂星 | 命中爆 60px AoE(主目標 5、波及 2) | 珊瑚 tint #FF8A80、命中小爆粒子 | + +- HUD 彈藥星星依屬性上色;發射音效 pitch 依屬性微調(標準 1.0/疾風 1.15/爆裂 0.85)。 +- 實作契約:`swallow(kind)` 記錄 flavor → `fireStar(flavor)` → `STAR_FLAVORS` 常數表(core/config.ts)。 +- KISS 底線:不做技能樹、不做冷卻、不做 UI 選單——吞什麼射什麼,一眼可懂。 + +## 23. 技能組合 v3:吞噬連鎖(表驅動,logic/skills.ts) + +- 三屬性沿用 §20;新增連鎖規則: + - 同種連吞 ×2:該槽升級為強化星(傷害 ×1.6、尺寸 ×1.4、pitch -15%、金邊 tint)。 + - 彈匣全滿長按 B 0.8s:星暴大招——清場全部小怪 + 魔王 12 傷,震屏 + 白閃 + 星雨粒子,清空彈匣。(v9.1 已由 §64.2 補訂:發動附 5s 無敵窗,與受擊 i-frame 取較大值不疊加。)(v19 已由 §109 取代:滿匣自動結晶+SP 鍵手動引爆,B 長按星暴路徑退場。) + - 空中搖桿下 + B:下衝擊(v7 已由 §44 取代:改為空中搖桿下+跳躍鍵,B 鍵回歸純吸/射語意)。 +- 彈匣槽各自帶 flavor 與強化態,後進先出發射;HUD 槽位顯示屬性色 + 強化金邊。 + +## 40. v6 新技能:殼盾與雷鏈(PM 原創,補防禦與群戰原型) + +沿用 ammo/flavor 表驅動管線(§20/§23),不加新 HUD 元件;星彈三系擴為五系: + +| 吞下 | 星彈屬性 | 效果 | 視覺 | +| ------ | -------- | ----------------------------------------------------------------------- | --------------------------- | +| shelly | 殼盾星 | 直射傷害 5、速度 480、穿透 0;頂槽時長按=舉盾(見下) | 青綠 tint #7FD8C8 | +| zappy | 雷鏈星 | 直射傷害 5、速度 585、穿透 0;命中後跳電至 160px 內最近 2 敵、各 3 電傷 | 電黃 tint #FFE28A、折線閃電 | + +- 殼盾(防禦原型):頂槽殼盾星且未滿匣時,長按 B ≥150ms 舉正面護盾(取代吸入語意;滿匣長按維持星暴優先,肌肉記憶不變)。格擋彈幕/接觸一次:不掉血不擊退、消耗頂槽、觸發反擊星爆(盾前 90px 傷害 3)+短無敵 0.8s,冷卻 4s。正面判定=傷害來源位於面向側(同 x 視為正面)。點按仍為發射。(v19 已由 §109 補訂:長按星暴退場,頂槽殼盾星即成立殼盾情境——滿匣不再讓位。) +- 雷鏈(群戰清場原型):命中主目標後由近至遠跳電(主目標排除、折線閃電演出+burstSmall);命中魔王同樣跳電波及補給小怪(v4 多平台混戰場景受益)。 +- 純邏輯 SSOT:`logic/skills.ts`(`advanceShield`/`resolveShieldBlock`/`isFrontalHit`/`pickChainTargets`)+ `STAR_FLAVORS` chain 欄位(core/config.ts),vitest 全蓋。 +- 事件契約增列:`skill:shield-block`(player 發出,GameScene 結算反擊星爆)。 +- 平衡註記:殼盾 CD 4s 防無限格擋;雷鏈單跳 3 傷不足以秒 chompy(10 HP),保持坦怪定位;§24 連吞彩蛋序列不含新屬性(zappy 現記為 zappy,不再以 floaty 代位計序)。 + +## 46. v7 雙味混合星彈(config STAR_MIXES 為 SSOT,表驅動) + +- 規則(KISS 裁決,`swallowIntoMagazine` 單一入口): + - 依序吞兩隻**不同**怪且頂槽為素槽(未強化/非金/非混)且配方存在 → 頂槽合成混合星 + (佔 1 槽);HUD 星芯顯示配方色、外圈顯示第二味屬性色(雙色可讀)。 + - 同怪疊加 = 強化單味(§23 不變);無配方對照 → 推新槽(§23 不變)。 + - 取消/覆蓋規則:混合槽為**終態**——不可再強化、不可再混(再吞任何怪推新槽); + 滿匣改吞維持覆蓋頂槽(§20),混合槽在頂被覆蓋即取消;滿匣且頂槽配方成立時優先合成。 + - **anti-softlock 硬規則:混合星永不為破關必需——基礎星彈恆可通關**(配方僅為威力加成, + 關卡配額/魔王皆可純標準星磨死;§26 飢荒保證律不變)。 + - 首遇情境提示(三席審查補修):本 session 首次取得某味/首次合成某配方時,頂部 toast + 一行文案(名稱+一句效果,SSOT `core/codex.ts` FLAVOR_HINTS/MIX_HINTS);seen 集合 + 僅存 session 記憶體,不動 save schema。 +- 混合表(六式;效果自 穿透/追蹤/散射/爆炸/凍結場/連鎖電 擇優組合): + +| 配方 | 成分 | 效果 | tint | pitch | +| ------ | --------------- | ------------------------------------------------------------------------- | ------- | ----- | +| 疾光星 | jelly + floaty | 穿透 3、彈速 780(穿透) | #FFF1C4 | 1.35 | +| 巨爆星 | jelly + puffy | 直傷 6、AoE 110px/4 傷(爆炸) | #FF9D7A | 0.70 | +| 追電星 | floaty + zappy | 飛行中追蹤最近敵(轉向 0.006rad/ms、鎖敵 320px)+雷鏈 ×2(追蹤+連鎖電) | #C9B8FF | 1.30 | +| 雷爆星 | puffy + zappy | AoE 70px/3 傷+雷鏈 ×3(爆炸+連鎖電) | #FFD24D | 0.90 | +| 碎鑽星 | shelly + drilly | 發射分裂 3 發扇形(±90vy)、各傷 6、穿透 1(散射+穿透) | #9ADFD2 | 0.80 | +| 凝光星 | drilly + glowy | 命中生成 100px 凍結光域 1.5s,域內小怪停擺冰藍(凍結場) | #FFF7D6 | 1.15 | + +## 53. v8 星彈九系與新混合三式(config 表驅動擴充) + +七系 → 九系(§20/§40/§47 擴充): + +| 吞下 | 星彈屬性 | 效果 | 視覺 | +| ----- | -------- | -------------------------------------------------------- | ----------------- | +| spora | 孢子星 | 傷害 4、命中緩速 2.2s(速度封頂 60)+輕持續傷(1/0.7s) | 孢綠 tint #A8D8A0 | +| boomy | 迴旋星 | 傷害 5、速度 520、穿透 1;去程 0.9s 勻減速折返、雙程判定 | 陶橘 tint #E8A878 | + +- StarFlavorSpec 擴欄:`slowMs`/`dotDamage`(緩速持續傷)與 `boomerang`(迴旋彈道); + 緩速/DoT 由 enemies.update 中央結算(單點),迴旋彈道由 `boomerangVelocity` 純函式 + 驅動(GameScene 逐幀轉向、壽命 2.2s 必回收)。 +- 混合三式(STAR_MIXES 六 → 九;§46 規則不變,混合彈永不為破關必需): + +| 配方 | 成分 | 效果 | tint | pitch | +| -------- | -------------- | --------------------------------------------------------- | ------- | ----- | +| 毒爆雲 | spora + puffy | AoE 90px/3 傷+波及未死者緩速 2.6s 持續傷(爆炸+緩速場) | #BCE8A0 | 0.75 | +| 電鋸迴旋 | boomy + zappy | 迴旋雙程判定+每次命中跳電 ×2(回程同樣鏈電) | #F5D878 | 1.28 | +| 迴風刃 | boomy + floaty | 速度 620、雙程各穿透 2 的長弧掃割(第三式 PM 手感裁量) | #C8DCF5 | 1.40 | + +- 「星彈七系」字樣全數改九系(codex 技能頁/README);FLAVOR_HINTS/MIX_HINTS 同步九味九式。 + +## 57. v9 星化變身系統(logic/transform.ts 純狀態機,表驅動) + +- 觸發:彈匣內同系可變身星彈合計 ≥3 發(強化槽為連吞兩發合成、計 2 發;金星/混合槽 + 破壞資格)時 HUD 彈藥列脈動亮起變身提示;**地面**長按吸入鍵 0.6s 觸發(吸入拉怪 + 進行中與空中不可起手;不新增實體按鍵)。消耗全部彈匣進入形態,持續 10s(玩家頭頂 + 倒數環),到時自動解除;再長按 0.6s 提前解除(不返彈)。 + (v19 已由 §109 取代觸發面:改 SP 鍵點按立即變身/再按提前解除,0.6s 長按門檻 + 廢除;資格條件與形態語彙不變。) +- 語意讓位(輸入矩陣,`resolveActionPress`/`resolveTransformHold`):同系 ≥3 星情境 + 長按=星化(優先於星暴與殼盾);非同系滿匣長按維持星暴;頂槽殼盾星未滿匣維持舉盾; + 點按放開(<150ms)仍發射。變身期間吸入停用(B 鍵改役),星暴/殼盾不充能。 + (v19 已由 §109 取代:長按讓位矩陣退場,SP 天然互斥裁決見 `resolveSpPress`。) +- 三形態(各改變 移動+攻擊+防禦 至少兩項;zappy→雷化、floaty/gusty 味→風化、 + shelly→殼化)(v20 已由 §110 加深:每形態補齊 攻/防/機動 三語彙,下表為 v9 基線): + +| 形態 | 移動 | 攻擊 | 防禦 | +| -------------- | ----------------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | +| 雷化 Voltform | 移速 +15% | 身體帶電接觸傷害 2;B 點按短程鏈電束(170px 內最近敵 3 傷+跳電 2×2 傷,CD 0.9s) | — | +| 風化 Galeform | 拍翅無上限+升力 -330(近自由飛行) | B 點按穿透風刃(傷害 4、速度 640、無限穿透,CD 0.35s);落地 44px 衝擊 1 傷 | — | +| 殼化 Shellform | 移速 -20% | 下砸範圍加倍(120px) | 受傷減半(0.5 傷害池累積)+反彈魔王彈幕(§58) | + +- 呈現:變身爆發(星爆+擠壓)+形態專屬 aura 粒子(三 emitter 常駐池化、僅啟用當前 + 形態、maxAlive 14)+形態立繪(hero-volt/gale/shell,素材未載退回一般姿勢)。 +- anti-softlock 硬規則:**變身永不為破關必需**——全關卡純標準星保底線不變(§26/§46 + 同律);變身資格味(zappy/floaty/shelly)非全關卡保證供給,僅為威力加成路徑。 + +## 110. v20 變身系統 2.0——三形態加深+教學矩陣(#816;T4 列車) + +### 110.1 三語彙表(機制 brief §4;表驅動 `logic/transform.ts`,每形態 ≤3 守門) + +| 形態 | 攻(保留+補齊) | 防(新增) | 機動(新增) | +| -------------- | ---------------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------- | +| 雷化 Voltpuff | 鏈電束+帶電接觸(§57 既有) | 受擊放電反擊(120px、傷 1、每形態期 2 次) | 磁力域免疫(磁彎折不作用;L8/L11 優勢解) | +| 風化 Galepuff | 穿透風刃+落地衝擊(§57 既有) | 落地滾翻(落地瞬間 0.3s 免傷,自動) | 滑翔(空中按住跳鍵=緩降帽+水平漂移 ×1.6) | +| 殼化 Shellpuff | 滾殼衝撞(B 點按,0.7s/CD 0.9s,接觸傷 2)+下砸加倍(§57 既有) | 受身入殼(受擊自動全免+0.5s 免傷,每形態期 1 次) | 衝撞躍(衝撞中按跳=低弧跳、保持衝撞態) | + +- 工程接點:`TransformFormSpec` 擴欄(`dischargeCharges`/`landingRollMs`/`tuckCharges`/ + `magnetImmune`/`glide`/`chargeDash`);`TransformState` 增 `dischargeLeft`/`tuckLeft` + 每形態期計數(`consumeDischarge`/`consumeTuck` 純函式裁決,vitest 對象)。 +- 世界結算:放電反擊走 `SKILL_TRANSFORM_STRIKE`(kind 增 `volt-discharge`,additive) + → `starCombat.resolveVoltDischarge`;滾殼衝撞接觸傷沿 overlaps 既有 contactDamage + 通道(`player.isShellCharging()` 改判);磁免疫於 `starSteering.steerMagnetizedStars` + 依 spec 短路。 +- anti-softlock 不變式(§57 硬規則):全部語彙為威力/防禦加成路徑,基礎星彈保底線 + 零改動;受身入殼/放電反擊次數隨形態期歸零,無跨期累積。 + +### 110.2 MechanicProgressionMatrix(機制 brief §6.1;`levels.ts` 資料驅動) + +- `LevelSpec` 增 `teaches[]`(本關首教機制)+`bossApplies[]`(魔王驗收機制)+ + `drillSpawns[]`(教學供給固定生成);`MechanicId` 13 機制 union。 +- 教學前置完整性由 `levels.test` 圖遍歷守門:任一關 `bossApplies` 機制必已在較早關 + `teaches`;機制唯一首教;各魔王關驗收含 `transform`。 +- L3 變身首教位點:進關前段(x 460–600)drillSpawns 保證 3 隻 floaty(同系→風化); + SP 資格徽章首次浮現時一次性教學浮字「同系星彈 ×3!按 SP 鍵立即變身」(session 慣例)。 +- 首教關對映(依 repo 資料實況錨定):L1 吸射、L2 殼盾+下砸、L3 變身+星暴、L5 氣流、 + L8 磁力域、L9 鏡性、L10 折躍、L13 噴口、L14 潮汐、L17 低重力、L18 流星讀影。 + +### 110.3 變身優勢情境模板+TTK 對照 hook(機制 brief §4/§10) + +- `TRANSFORM_ADVANTAGE`(`logic/difficulty.ts`):每王一個「優勢解但永不必需」情境; + T4 先落 Jellord(殼化反彈線,shelly)與 Noctra(雷化斷召線,zappy),其餘三王隨 + T5 魔王主題化補齊。 +- bot hook:`node scripts/level-audit.mjs --transform`——driver 以正式 + swallow 管線集齊優勢味 ×3(集星期間停火防射空資格)→ 按 SP 變身(空中裁決 none + 逐 tick 重試);報告輸出 `transformsPerRun` 與情境描述。 +- 驗收口徑:同 bot 分級、同 runs 的有/無 `--transform` 兩份報告對照,TTK 改善 + ≥15%(`AUDIT_THRESHOLDS.transformTtkGainMinPct`)且無變身仍可通關(非必需)。 diff --git a/apps/starpuff/docs/design/03-enemies-bosses.md b/apps/starpuff/docs/design/03-enemies-bosses.md new file mode 100644 index 000000000..272959e5b --- /dev/null +++ b/apps/starpuff/docs/design/03-enemies-bosses.md @@ -0,0 +1,764 @@ +# 星噗噗 — 角色、怪物與魔王 + +> **職責範圍**:場上會動的東西。主角與 18 隻小怪的設定與 FSM、精英變體系統、五座魔王(Jellord/Noctra/Prismix/Syrona/Voidra)的階段結構、加權選招與主題招式、EX 變體與 P4 第二血條,以及魔王演出與難度根修紀錄。 +> +> **不在本檔**:怪物出現在哪一關與出現比例(見 `04-levels-world.md`);魔王關前室與增益體系(見 `04-levels-world.md` §69);素材規格(見 `07-art-audio-fx.md`)。 +> +> **硬不變式**:魔王關須有多種可行破關策略;telegraph 窗 ≥600ms 為可讀性紅線,EX 差分只縮體不縮窗。 +> +> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 + +## 5. 角色設定(全部原創) + +| 角色 | 名稱 | 外型 | 行為 | 數值 | +| ---- | -------------- | -------------------------------------- | ------------------ | -------------------------------------- | +| 主角 | 噗噗 Puffpo | 薄荷奶油色圓球、頭頂星星呆毛、桃色腮紅 | 移動/跳/漂浮/吸/射 | HP 5、受擊無敵 1.5s | +| 小怪 | 果凍丁 Jelly | 草莓粉果凍方塊、瞇瞇眼 | 定期彈跳朝玩家 | HP 1、觸碰傷害 1、可吸 | +| 小怪 | 飄飄 Floaty | 薰衣草紫圓鳥、小翅膀 | 正弦飄移 | HP 1、觸碰傷害 1、可吸 | +| 小怪 | 刺刺瓜 Spiky | 萊姆綠刺球、壞笑 | 地面滾動衝刺 | HP 1、觸碰傷害 1、不可吸(吸會被彈開) | +| 魔王 | 果凍王 Jellord | 巨大葡萄紫果凍、金皇冠、跋扈眉 | 見 §6 | HP 60、身體傷害 1 | + +## 6. 魔王 AI(有限狀態機,pure TS 可測) + +(v21 已由 §111 取代:P1/P2 固定循環改 `JELLORD_MOVES` 加權表選招,招池與 telegraph 數值不變。) + +- P1(HP > 50%)循環:`idle(1.2s) → jellyRain(5 顆拋物線彈) → idle → slam(跳起落地雙向地面震波) → idle → …` +- P2(HP ≤ 50%):變紅憤怒、速度 ×1.3,新增 `dash`(白閃三拍前搖 0.6s → 水平衝刺,牆邊回彈; + #809 前搖 0.3s→0.6s 對齊 ≥600ms 衝撞可讀性紅線);jellyRain 升為 7 顆。 +- 前室反制提示(#809):一次性浮字「被逼到角落?連按跳鍵拍翅可飛越魔王」——拍翅淨高 + 211px > 全王本體需求(跳越可行性矩陣 §108),貼牆「必中」體感為知識缺口非物理問題; + 入 arena 即記憶(localStorage)不重複打擾。 +- 受擊:白閃 + 抖動 + 傷害數字;每損 10 HP 補生小怪。 +- 死亡:慢動作 0.5s → 星爆粒子 → 勝利。 + +## 16. 新怪物 ×2(多樣性;全原創) + +| 怪物 | 名稱 | 外型 | 行為 | 數值 | +| ------ | ------ | -------------------------- | ------------------------------------------------------------------- | -------------------------------------------------- | +| 氣球魨 | Puffy | 珊瑚粉圓河豚、短刺、驚訝眼 | 高空緩慢下飄,落地或受擊「啵」爆成 4 向短刺彈(220px/s、0.6s 消散) | HP 1、可吸(吸入得彈藥且不爆)、爆刺傷害 1 | +| 咬咬花 | Chompy | 鵝黃果凍花、花瓣嘴、瞇眼 | 定點紮根,玩家進 120px 前搖 0.4s 後咬合(嘴部 hitbox 0.3s) | HP 2(吃兩發星彈)、不可吸(紮根彈開)、咬合傷害 1 | + +行為實作沿用 enemies.ts 既有模式(pool + kind 分支 + wobble tween);EnemyKind 契約擴充 'puffy' | 'chompy'。 + +## 17. 魔王關演出強化(動畫品質關鍵) + +- 入場運鏡:黑幕淡入 → 相機從王座緩推近(pan+zoom 1.2s)→ Jellord 三段彈跳落座(每段落地震屏+塵埃圈)→ 吼叫(畫面漣漪 + boss-roar)→ 戰鬥開始。 +- P2 轉換震撼:時停 0.4s → 全屏紫色 vignette 脈動常駐 → 果凍地震(相機持續微震 2s)→ 皇冠迸出星火粒子 → 背景色調轉暗(tint 疊層)。 +- 擊破多段演出:時緩 0.3× → 連環小爆 ×6(隨機體表位置、間隔 150ms)→ 全屏白閃 → 大星爆 → 皇冠拋物線落地彈兩下(金屬音)→ 勝利。 +- 粒子預算:單一發射器 maxAliveParticles ≤120(勝利彩帶峰值例外),單次 burst ≤40;以實機 60fps 實測為準(QA 實測 avg 100fps);vignette 用單一半透明 rect 疊層。 + +## 30. v4 內容擴充:新技能、新怪物、魔王 P3(PM 親撰) + +- 新技能「空中疾衝 Air Dash」已於 v7 §44 整體移除(輸入、純邏輯、殘影 fx、音效、圖鑑條目與測試全數清除),規格移至 [`99-superseded.md`](99-superseded.md#30-空中疾衝-air-dash已整體移除)。 +- 新怪物 ×2(全原創): + - 殼殼 Shelly:藍綠硬殼龜果凍。第一發星彈 → 縮殼旋轉衝刺 1.5s(期間無敵、傷害 1)→ 停下暈眩 1.6s(可吸/可擊殺)。HP 2 段。不可直接吸(縮殼後暈眩時可吸)。 + #811 吞食體感修復:暈眩窗 1.0s→1.6s、暈眩期吸入引力 ×1.5+判定半徑 +20%+貼身 + ≤60px 錐形豁免(停位貼腳死角);暈眩視覺=頭頂眩星公轉+殼體閃白脈動(與可吸窗 + 同生共滅);L2 首遇浮字教學。工具實測正確時機吞食 37%→73%(門檻 ≥60%)、 + 衝刺期 0% 不變(技巧性保留)。 + - 雷雷 Zappy:薰衣草黃電氣水母。緩慢懸浮追蹤,每 3s 放電環(半徑 70px、傷害 1、前搖 0.5s 閃爍預警)。可吸(吸入得疾風星)(v6 已由 §40 取代:吸入得雷鏈星)。HP 1。 +- 魔王 P3(HP ≤ 25%):狂暴皇冠——rain 改追蹤彈 ×5(緩速跟蹤 2s 後直線)、slam 觸發全場單向平台震落效果(站立玩家強制彈起)、體色金紫閃爍;P3 進場演出:皇冠射出星環衝擊波 + 時停 0.3s。 +- 關卡怪物組合更新:S2 加 shelly 15%、S3 加 zappy 15%(權重重配,可吸佔比維持 ≥50%)。 + +## 47. v7 新怪物 ×2(全原創;素材 codex imagegen 僅此 2 張,風格與既有嚴格一致) + +- 鑽鑽鼴 Drilly(sandy-brown 鑽頭鼴鼠果凍,`minion-drilly`): + - FSM(`logic/enemyFsm.ts`):潛地 burrow 2.2s(僅露鰭——壓扁貼地 0.55×/0.3× 半透明, + 朝玩家 x 潛行 90px/s;**不可吸、不可傷、觸碰無害、吸力不彈開**)→ 前搖 windup 0.5s + (定點鰭抖動+落點預警 telegraph)→ 破土 surfaced 1.4s(躍出 -360 攻擊;**可吸可傷**)→ 回潛。 + - 吞下得**重鑽星**:傷害 7、彈速 430、穿透 2(低速高傷)。條件可吸(破土窗), + spawner 保證律保守值不計入可吸佔比。 +- 提燈水母 Glowy(warm-cream 提燈水母果凍,`minion-glowy`): + - FSM:緩慢漂近 26px/s+正弦浮動 → 週期 4s 末段 0.9s 預警圈先行(由小到滿半徑擴張 + +明暗閃爍)→ 釋放範圍脈衝(半徑 80、傷害 1,走 hazards 管線)。恆可吸。 + - 吞下得**流光星**:傷害 5、彈速 540、命中 90px 光域 AoE 2 傷。 +- 入編:L2 glowy 10%(可吸佔比 60%);L3 八種混編 drilly/glowy 各 10%(可吸佔比 55%, + drilly 保守不計)。圖鑑 5×2 網格收錄十隻;混合表(§46)與技能頁同步。 + +## 48. v7 中魔王精英系統(levels.ts elite 為 SSOT,零新美術) + +- 每走動關中段一隻精英變體(既有怪 tint+scale+血量池+FSM 參數強化): + +| 關 | 精英 | 基底 | HP | scale | 強化(speedMul) | 掉落稀有味 | +| --- | -------------- | ------ | --- | ----- | --------------------------- | ---------- | +| 1 | 粉紅暴走果凍丁 | jelly | 10 | 1.6 | 跳頻/衝量 ×1.5 | glowy | +| 2 | 鋼青重殼殼 | shelly | 14 | 1.55 | 走速 ×1.4(血量池制不縮殼) | drilly | +| 3 | 暗紫狂咬花 | chompy | 20 | 1.5 | 前搖/冷卻縮時 ×1.6 | glowy | + +- 精英房流程:玩家接近(臂距 480px)且星星門未開 → 武裝——生成精英+軟鎖門 + (半透明果凍門柱,可退不可進)+頭頂血條;擊敗 → 開門+稀有味小怪(走正式 spawn + 管線,吞下即得稀有星味)+回復食物(心形拾取 +2 HP,15s 未拾自動淡逝)。 +- 反卡關雙保險:60s 逾時自動開門(精英留場可略過);星星門已開(配額達成)後不再 + 武裝——關卡已進尾端 release 節奏,既有走查路徑不受影響。精英不可吸、擊殺計入配額; + 白閃後回套變體 tint 維持精英識別。 +- 房界箝制(三席審查補修):精英越房界(左界鏡像門距、右界門前內縮 48px)即回夾並朝 + 房內反向(`stageModel.clampEliteX` 純函式),不出房追殺,60s 開門保險恆有效。 + +## 52. v8 新怪物 ×3 與雙精英(FSM-first;素材 §55) + +全部 FSM-first 進 `logic/enemyFsm.ts`(時序純函式),呈現接 `systems/enemyUpdates.ts` +per-kind: + +- 孢子菇 Spora(鼠尾草綠 `minion-spora`):定點紮根(更新迴圈每幀清速+一般地面 + 分離;非 Arcade immovable——該旗標會使動態體與靜態地面不分離而穿地,#841), + 週期 3.6s——末段 0.7s + 預警圈擴張 → 向上噴孢子雲(頭頂 -64、半徑 66、滯留 1.6s 區域拒止,走 hazards 管線, + 觸擊即散)。恆可吸 → **孢子星**(傷害 4、命中緩速 2.2s+每 0.7s 輕持續傷 1;緩速期 + 水平速度封頂 60px/s、孢綠著色,enemies.update 中央結算)。 +- 風飄鳥 Gusty(淡天藍 `minion-gusty`):四態 drift(水平漂移+正弦浮動)→(玩家於斜下 + 觸發域 200px)→ windup 0.5s(懸停抖動預警)→ dive 0.6s(鎖定前搖結束當下玩家位置 + 340px/s 撲擊,之後不修正可預判閃避)→ recover 回升(時滿 0.9s 且回抵航高 atBaseY + 才切 drift,#832 比照 cometa——深俯衝後不得自低空直接再漂移)。drift 期近域 + (130×90px)產生側風——推離方向 60px/s positional drift(不與速度控制器對抗), + 與 L5 氣流主題呼應。恆可吸 → 歸入既有**疾風味**(避免味數爆炸)。 +- 迴力殼 Boomy(暖陶土橘 `minion-boomy`):四態 walk 2.2s(緩速巡邏 55px/s、bounce 折返) + → windup 0.5s(定身舉殼抖動)→ throw(投擲迴旋殼刃:360px/s 去程勻減速、0.8s 折返、 + 回程同判定;壽命 2.0s 必回收——**回程彈不可穿門鎖死**(§56))→ cool 1.4s。恆可吸 → + **迴旋星**(§53)。 +- 雙精英(L6):重殼迴力守衛(boomy 基底,HP 16、×1.3,掉流光味)+暗雷水母(zappy + 基底,HP 18、×1.5 追速,掉重鑽味);房址 1300/2500(房距 1200 ≥ 2×門距不重疊), + 沿 §48 全套(軟鎖門/60s 逾時/房界箝制)。L5 精英狂風飄鳥(gusty 基底 ×1.4)掉 + **迴旋味**(L6 主場怪先行體驗,沿 v7 L1 掉 glowy 慣例)。 +- 圖鑑(§36 擴充):7×2 十四格(十二小怪+果凍王+暗月蝠王);立繪縮 50px、字級同步 + 收斂(v7 5×2 十格佈局由本節取代)。 + +## 54. v8 第二魔王:暗月蝠王 Noctra(logic/noctraFsm.ts 表驅動,空中型) + +與果凍王(地面型 §6)區隔的空中型三階段;phase truth 全數收斂 noctraFsm,禁止散落 +scene。呈現層 `systems/noctra.ts` 與 boss.ts 共用 `BossHandle` 介面與 BOSS\_\* 事件契約 +(GameScene 依 `level.boss` 品種擇一建立,HUD/fx/結算零分支)。 + +- 數值:HP 70、身體傷害 1、P2 ≤60%、P3 ≤30%、狂暴節奏 ×1.25、每損 10 HP 掉補給小怪 + (§26 飢荒保證律不變——基礎星彈恆可通關)。(v9 已由 §63 難度根修取代:HP 52、 + 狂暴 ×1.15、每損 8 HP 補給;實測 0% 勝率歸因與全參數表見 §63。) +- 招式循環(表驅動 `noctraAttackCycle`;換階段循環游標重置)(v21 已由 §111 取代: + `noctraMoveTable` 加權表選招,循環游標敘述作廢;招池與 telegraph 數值不變): + - P1 `bomb(盤旋投彈 ×4,落點預警先行)→ dive(俯衝:telegraph+shake+變色前搖 +0.55s → 鎖定點撲擊 → 回升)` + - P2 `bomb ×5 → dive → dive(俯衝連擊)→ summon(召喚 floaty,場上上限 2——cap 由 +FSM 指令帶出、GameScene 依現量夾限走正式 spawn 管線)`(v9 已由 §63 取代:單 dive、 + bomb ×3) + - P3 `barrage(狂暴彈幕:全向放射彈環 ×10)→ sweep(全場俯掠:橫帶預警閃爍 0.6s 後 +貼 y=280 帶速掠全場,站立可躲)→ bomb` +- telegraph 全數必備:dive 落點標記、sweep 橫帶閃爍、bomb 落點標記、階段轉換體色循環 + (P2 白紅、P3 金紫)+白閃抖動;統一走 systems/fx 慣例。 +- 盤旋駕駛:常態沿視寬正弦盤旋(高度 168±14 呼吸浮動);dive/sweep tween 接管期間讓位 + (steering 互斥),死亡冪等(FSM defeated 單向鎖存,演出僅執行一次)。(v9.1 已由 §64 + 補訂:接管結束改速度上限逼近歸位,禁止相位座標直寫——修正返空瞬移。) +- 可達性:玩家跳躍+拍翅 ×3 可觸及盤旋帶;dive/sweep 主動進入地面帶提供輸出窗; + 補給小怪維持彈藥循環。擊破沿 §17 演出(皇冠戰利品:蝠「王」同為王權敘事)。 +- anti-softlock:入場運鏡 active 前傷害靜默忽略;退出/重整走 §35 暫停與 scene restart + 標準路徑(無門鎖、擊破制勝利);通關寫存檔沿 BOSS_DEFEATED 即記。 + +## 58. v9 魔王攻略多樣化與 EX 變體(表驅動擴充,禁止散落 scene) + +- 攻略路徑(每魔王 ≥3 條可行路徑,PoC 全數驗證): + - 果凍王 Jellord:① 標準線——吸補生小怪點射+跳閃 slam/dash 磨死;② 殼化反彈線—— + L4 補生加入 shelly(暈眩窗可吸),殼化後站定將果凍雨反彈回傷(reflect 3 傷/顆); + ③ 頭頂下砸線——下砸命中頭頂(上半身)觸發短暈 0.9s(`BOSS.slamStunMs`,表驅動 + hit window)輸出窗,命中回彈不吃體傷;④ 滿匣星暴 12 傷速攻。 + - 暗月蝠王 Noctra:① 標準線——補給點射+dive 回升窗跳打;② 雷化斷召線——L7 補生 + 加入 zappy,雷化鏈電命中召喚蓄勢中的 Noctra 立即中斷召喚(`interruptSummon`); + ③ 俯衝下砸線——俯衝落地瞬間 0.6s 窗內頭頂下砸觸發長暈 1.8s(`NOCTRA.diveStunMs`); + ④ 彈簧板線——boss 房雙彈簧板(x 190/664,過 stageModel 掃掠背擋)提供非風化到空 + 路徑貼打盤旋帶;⑤ 風化自由飛行貼身輸出。 +- EX 變體(已通關 L4/L7 節點顯示「EX 挑戰」第二入口;`EX_MODS` 兩魔王共用): + - 數值:HP ×1.5(果凍王 90/蝠王 78——蝠王基準沿 §63 難度根修後 52 再乘 EX 係數)、 + 全節奏 ×1.15;入場後緋紅呼吸循環變色演出。 + - 果凍王 EX 新 pattern:擊破時分裂 3 隻小果凍(`split` 事件表驅動、走正式 spawn 管線)。 + - Noctra EX 新 pattern:P3 循環追加「月蝕彈幕矩陣」(`eclipse`:9 列 ×2 波直落彈網、 + 每波隨機留 2 缺口通道、落點 telegraph 先行)。 + - 通關記錄 `exCleared`(save v1 additive 欄位:預設 false、僅信任明確 true、舊檔載入 + 不 crash——e2e 守門);EX 通關於地圖節點與圖鑑魔王條目掛紫星紀念章;L9 通關後地圖 + 提示 EX 入口解鎖。EX 通關不動一般 cleared/bestTime。 + +## 59. v9 新怪物 ×2(FSM-first 進 enemyFsm,均歸既有味系) + +- 磁極獸 Magno(鋼藍灰 `minion-magno`):緩行 idle 2.4s → 前搖 windup 0.7s(預警圈 + 擴張+閃爍)→ 磁場 field 1.9s(150px 磁域:**吸偏玩家飛行中星彈**(`magnetPull` + 逐幀彎折彈道)+磁殼星彈免傷(`resolveMagnoStarHit`)——鼓勵近戰/下砸/變身應對; + 下砸/波及/接觸傷害照常結算)→ 回 idle。恆可吸 → 歸**雷鏈味**(zappy)。 +- 鏡面蟲 Mirri(珍珠銀紫 `minion-mirri`):巡邏 roam 2.4s(末段 0.4s 亮銀預告閃爍 + telegraph)→ 鏡面 mirror 1.5s(定身亮銀高光:**反射玩家星彈**為朝玩家的傷害彈 + (反射彈 1 傷、壽命 1.4s 必回收),`resolveMirriStarHit`)→ 冷卻 cool 1.1s(黯淡 + 明確可打窗)→ roam。恆可吸 → 歸**迴旋味**(boomy)。 +- 圖鑑(§36/§52 擴充):8×2 十六格(十四小怪+雙魔王)。 + +## 63. v9 Noctra 難度根修(實測席稽核回寫;bot 勝率門檻收斂定案) + +**根因**(v8 出貨值,雙水準 bot 對線上 0.6.0 實測普通/熟練勝率皆 0%、傷害進度近 0%): +`HOVER_Y=168` 盤旋帶與地面水平星彈幾何錯開——有效輸出窗僅剩俯衝貼地縫,P1 bomb/dive +約 15s 殺穿玩家;「基礎星彈恆可通關」保底線名存實亡。 + +### 63.1 調參前後值(基準表;EX 沿新基準 ×1.5/×1.15) + +| 位置 | 參數 | v8 出貨 | v9 根修 | 目的 | +| --------- | ------------------------------- | --------------------: | ----------------------------: | ------------------------------------------------------------------------------------------------ | +| noctra.ts | `HOVER_Y` | 168 | **246** | 體底降入單跳星彈可打帶(含 ±14 浮動恆可命中) | +| noctra.ts | `SIDE_MARGIN_X` | 130 | **190** | 收窄掃幅,牆側留玩家喘息帶(錨點打法成立) | +| noctra.ts | 盤旋掃速 | 0.0009 | **0.0007** | 峰值橫移降至玩家走速下,保距走位可行 | +| noctra.ts | `DIVE_TELEGRAPH_MS` | 550 | **720** | 普通反應(250-400ms)可讀可躲 | +| noctra.ts | `SWEEP_TELEGRAPH_MS` | 600 | **750** | 俯掠可讀 | +| noctraFsm | `diveHoldMs` | 無 | **300** | 俯衝落地滯留=地面明確輸出窗 | +| noctraFsm | `diveDurationMs` | 1500 | **2100** | 容納前搖+滯留(EX 最高速率下不與下招重疊) | +| noctraFsm | `diveStunWindowMs` | 600 | **900** | 頭頂下砸長暈窗涵蓋滯留段 | +| noctraFsm | `idleMs` | 1100 | **1600** | 表觀 hit window ≥55% | +| noctraFsm | `bombCountP1/P2` | 4/5 | **2/3** | P1/P2 落彈鏈為主要死因 | +| noctraFsm | `barrageCount` | 10 | **7** | P3 密度 | +| noctraFsm | P2 循環 | bomb,dive,dive,summon | **bomb,dive,summon** | 去連擊 | +| noctraFsm | `enrageSpeedMultiplier` | 1.25 | **1.15** | P2/P3 節奏回讀帶 | +| noctraFsm | `maxHp` | 70 | **52** | TTK 對齊補給經濟(普通保底線 ~40-60s 擊破) | +| noctraFsm | `minionSpawnHpStep` | 10 | **8** | 輸出愈多彈藥愈順(正回饋) | +| levels L7 | `spawnIntervalMs`/`maxOnScreen` | 3200/2 | **4500/1** | 供給定位是彈藥非第二傷害源 | +| levels L7 | 補給構成 | jelly/floaty/gusty | **jelly/floaty/zappy** | 移除俯衝型騷擾;保雷化斷召素材 | +| waves.ts | 補給入場側 | 左右交替 | **玩家遠側** | 走向玩家的路程=拾取節奏 | +| homing.ts | `BOSS_AIM_ASSIST` | 無 | **range 560 / 0.0012 rad/ms** | 一般星彈對魔王微導向:地面平射自然上彎入盤旋帶(追蹤彈 1/5 轉率、須大致對向;追電/迴旋星不疊加) | +| mercyHeal | 魔王房 override | 無 | **HP≤2、12s、18s CD、60%** | boss 戰長度下保底真正可觸發(v19 已由 §62 取代 60% 擲骰:改 pity 受傷 2 次/低血 15s 保底) | + +### 63.2 驗收證據(噗頭對噗頭 bot 實測,序列執行;`scripts/noctra-bot-audit.mjs`) + +| 水準 | 反應/走位 | v8 出貨勝率 | v9 根修勝率 | 均傷害進度 | 有效 hit window | +| ---- | --------------- | ---------------: | -----------: | ---------: | --------------: | +| 普通 | 250-400ms/0.65 | 0%(進度 ~0%) | **2/5=40%** | 84% | ~100% | +| 熟練 | 150ms/0.9 | 0%(進度 ~1.4%) | **4/5=80%** | 93% | ~100% | + +- bot 紀律=普通玩家可再現行為:牆側錨點站位、telegraph 讀招(盤旋凍結=俯衝前搖)、 + 落彈側移/低彈道跳越、原地吸入補給、慈悲愛心掃拾;純標準星保底 build(不用變身/混合)。 +- hit window 口徑:體底進入單跳星彈可打帶(≥270)之時間比;另含俯衝滯留地面窗。 +- L7/L4 跳幅:L4 果凍王大參數不動(實測可磨可通關);L7 全參數回落後 P 軸(命中幾何) + 自崩壞回歸常態,級距回落合理帶(≤~1.4×)。 +- 標準星保底線與 anti-softlock 不變式全數維持;變身/混合/EX 仍為加速與挑戰線非必需。 + +## 64. v9.1 熱修:Noctra 返空連續飛行與星暴無敵窗(P0) + +### 64.1 Noctra 返空瞬移根修(logic/noctraFlight.ts,取代 §54 盤旋駕駛敘述) + +**根因**:盤旋駕駛以「凍結相位的絕對座標」逐幀直寫 sprite——俯衝/俯掠/長暈 tween 接管 +期間相位凍結,接管結束當幀位置直接跳回相位點;俯衝落點追玩家(clamp 60..W-60),與 +凍結相位點距離可達數百 px,玩家所見即「返空瞬移」。一般與 EX 共用呈現層,兩型皆中。 + +**修法**(純邏輯層 `logic/noctraFlight.ts`,vitest 對象): + +- `hoverPatternPoint(hoverMs, viewWidth)`:相位 → 目標座標(航線 SSOT 自 noctra.ts 收斂)。 +- `approachPoint(current, target, maxSpeed, dt)`:速度上限逼近——單 tick 位移 ≤ + `maxSpeed×dt`、步長內貼合目標不過衝;`maxSpeedPxPerSec=340`(×speedFactor)嚴格高於 + 最寬幅盤旋峰值橫移(~287px/s),貼軌後恆跟上、接管交還必為連續飛行。 +- 涵蓋:不同落地位置、返空中受擊/相位轉換(cap 隨 speedFactor 縮放)、pause(dt=0 不動)、 + 超大 dt(位移仍受 `maxSpeed×dt` 夾制);e2e 以 rAF 逐幀取樣魔王座標守門單幀位移。 + +### 64.2 星暴無敵窗(§23 星暴補訂) + +- 星暴發動即開 **5s 無敵窗**(`STARSTORM.invulnMs=5000`,config SSOT):與受擊 i-frame + 為獨立計時,結算時 `effectiveInvulnMs = max(受擊, 星暴)` 生效——**取較大值不疊加**、 + 期間受擊零傷害且不重啟計時;到期即恢復正常受擊(受擊判定沿 `combat.resolveHit` + 單一出口)。 +- 視覺沿用受擊 i-frame 閃爍(alpha 節流),不新增散落 tween;受傷姿勢(hero-hurt)仍 + 僅綁受擊 i-frame,星暴無敵不觸發受傷表情。 +- 定位:星暴由「清場大招」升級為「攻防轉換窗」——發動後 5s 內可貼身輸出/穿彈幕走位; + anti-softlock 不變式不受影響(無敵為加成非必需)。 + +## 68. v10 第三魔王:稜晶雙子 Prismix(logic/prismixFsm.ts 表驅動,分裂型) + +與地面型(Jellord §6)、空中型(Noctra §54)區隔的**分裂型**——核心威脅是「目標數量 +變化」迫使玩家切換單體集火與多目標處理。HP 80(階梯 60→52→80)、體傷 1、狂暴 ×1.15、 +每損 10 HP 掉補給(§26)。 + +- 三階段(phase truth 全收斂 FSM;呈現層 systems/prismix.ts 接 BossHandle) + (v22 已由 §112 取代:固定循環改 `prismixMoveTable` 加權表選招,P2 追加鏡界反射與 + 鏡像殘影;招池數值與 telegraph 不變): + - P1 單體(總血 >66%):`idle(1.5s) → 晶柱衝擊(地面尖晶 ×3,落點預警 0.95s)→ idle → +折射光束(橫掃一次,預示線 0.5s)→ …` + - 晶柱預警(#810 修復):0.6s→0.95s——500ms 反應玩家迴避率 0%→88%(工具實測); + 預警視覺為落點橢圓+尖刺實際範圍白框+裂紋豎線閃爍(形狀與明滅雙訊號,色弱不依賴 + tint);下限 SSOT=`difficulty.AUDIT_THRESHOLDS.spikeTelegraphMinMs`(900ms)。 + - P2 分裂(≤66%):剩餘 HP 均分為**雙獨立血條**(HUD 魔王條雙節顯示,BOSS_TWIN_HP + 事件);鏡像雙子同一指令左右對稱執行——`雙生夾擊(同步閃爍 0.6s → 左右對衝互換位, +跳越可躲;#809 衝撞前搖對齊 ≥600ms 可讀性紅線)→ 交錯光束(一具地面帶、一具空中帶) +→ 召喚 mirri(場上限 2,雷化鏈電可中斷 §58 慣例)`。 + - 殘核掙扎(事件驅動):單具擊破 → 另一具入 1.0s 掙扎僵直(體色轉暗 telegraph、可傷); + 窗滿 → 存活具吸收殘核合體入 P3(裂核 HP=存活具剩餘)。 + - P3 裂核:環繞碎晶盾 ×4(可擊破星彈屏障,軌道公轉)→ 全域折射彈幕(放射 ×8,蓄能 + 轉白)→ 晶雨(落點預警 0.6s ×3)→ … +- **雙子連破**(§70 彩蛋):掙扎窗內補殺第二具=總血歸零直接擊破、跳過 P3。 +- 多本體工程契約:BossHandle 增選配 `getBodies()`/`applyDamageAt(x,y)`/`getShields()`; + GameScene 星彈/觸碰/下砸/反彈逐本體接線,受擊側依命中位置歸最近存活本體;準星輔助、 + 殼化反彈、鏈電束一律取最近存活本體。 +- 變身互動(優勢解非必需):雷形態鏈電同時波及雙子與碎晶盾;殼形態格擋夾擊;風形態 + 跨場重定位。下砸命中頭頂僅回彈免體傷(分裂型無暈窗)。 +- EX 差分(`EX_MODS` ×1.5/×1.15 共用):HP 120、分裂閾值 66%→75%、掙扎窗 1.0s→0.7s、 + 碎晶盾 4→6、雙子動作去同步(相位錯 260ms,讀招難度升級)。 + +## 73. v11 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) + +| 怪物 | FSM 四態 | 可吸性 | 星味映射 | +| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ----------------------------- | +| 焦糖泡 Bubbla | submerged 潛伏 2.2s(壓扁露頂,免傷不可吸)→ ripple 漣漪前搖 0.6s(telegraph)→ leap 拋物躍出 1.4s(升 0.5+頂點滯空 0.4+落 0.5,**可吸可傷窗**)→ dive 回潛 0.5s | 條件可吸(躍出窗) | 爆裂味(puffy) | +| 熔糖投手 Splatta | patrol 緩走 2.4s → aim 舉勺瞄準 0.5s(著色 telegraph)→ lob 投擲(單幀事件態,拋物糖球 ×1)→ cool 冷卻 1.6s | 恆可吸 | 孢子味(spora,黏緩語意一致) | + +- Bubbla 幾何:定點怪(重力關閉);躍出位移由 `bubblaLeapOffsetY` 純函式導出、逐幀 + 速度逼近驅動(沿 §64 噴口逼近制慣例,禁絕對座標直寫);受擊窗 resolveBubblaHit 沿 + drilly immune/vulnerable 慣例;isPhasedOut 半潛觸碰不結算、吸力不彈開。 +- Splatta 糖球:拋物彈道(重力開)、壽命 2.4s 逾時必回收(§56);落地轉灼燙糖斑 + (滯留 1.2s 區域拒止,走既有 hazards 管線,沿孢子雲模式)。 +- 精英化:焦糖泡霸(L13,躍出節奏 ×1.5、掉雷鏈味)、糖漿投擲隊長(L14,拋射 ×1.5、 + 掉重鑽味)——沿 §48 tint+scale+倍率零新美術。 +- 圖鑑(§36)收錄:十八格(十六小怪+雙魔王),欄數由條目數推導(9×2 於 854 寬 + cellW≈89 仍可讀;分頁與地圖分區分頁同批延後評估)。 + +## 74. v11 第四魔王:Syrona 熔糖窯后(logic/syronaFsm.ts 表驅動,場控型) + +與地面型(§6)、空中型(§54)、分裂型(§68)區隔的**場控型**——本體半定點於右側 +王窯座(不追打),威脅來自「地形被改寫」:潮汐、噴泉、滴落把可站空間動態壓縮, +考驗空間規劃。HP **90**(階梯 60→52→80→90)、體傷 1、狂暴 ×1.15、每損 10 HP 掉補給。 + +- 三階段(phase truth 全收斂 FSM;呈現層 systems/syrona.ts 接 BossHandle) + (v22 已由 §112 取代:固定循環改 `syronaMoveTable` 加權表選招,糖漿波追加焦糖化; + 招池數值與 telegraph 不變): + - P1(>66%):`糖漿噴泉(地面點 ×3 順序噴發,冒泡 telegraph 0.8s)→ 散熱僵直 2.5s → +焦糖射彈(拋物 ×3,舉臂 0.5s)→ 僵直 → …` + - P2(66-33%):**潮汐入場**(phase 事件觸發 startTide,沿 §71 管線);循環 + `熔糖滴落(天花板 ×4 預警光斑 0.7s → 直墜)→ 吟唱僵直 2.0s → 召喚 Bubbla(上限 2, +雷化鏈電可中斷 §58 慣例)→ 噴泉加密 ×4 → …` + - P3(≤33%):**大沸騰**(boilTide:潮汐週期 -30%、漲頂 +24px);循環 + `全場糖漿波(邊緣起浪 0.9s → 單向橫越 250px/s,跳越可躲)→ 波後僵直 2.0s → +噴口超載 2.6s(arena 雙噴口恆噴+升托增強至 -640,開放直達皇冠的垂直路線)→ …` +- arena 場控幾何(§28 禁硬編,呈現層依動態視寬比例佈建;LevelSpec 幾何表留空): + 浮台 ×3(22%/47%/70%,y 336/304/336——低台 P2 漲頂下可站、高台 304 沸騰期保底位, + FSM 測試守門「每循環必留 ≥1 保底位」)+噴口 ×2(30%/58%,週期同 L13)——供力由 + GameScene 逐幀委派 `getVentLift`(BossHandle 選配),浮台由 `getPlatforms` 接 collider。 +- 皇冠弱點:頂帶(本體頂緣 34px 內)命中 ×2 傷(applyDamageAt 位置判定);乘噴口 + 升空為主要到頂路徑。保底線:讀潮汐節拍站浮台點射,僵直窗(散熱/吟唱/波後 ≥2s) + 為固定輸出窗,時窗佔比 0.50 保證磨死(主計畫 §3.2 保底 TTK ≈58s)。 +- 變身互動(優勢解非必需):風形態滯空渡潮直取輸出窗;殼形態硬吃一次糖漿波保節奏; + 雷形態清召喚 Bubbla。場控型免暈:下砸命中僅回彈免體傷(trySlamStun false)。 +- EX 差分(EX_MODS ×1.5/×1.15 共用 → HP 135):噴泉 ×5、Bubbla 上限 3、滴落點 6、 + 大沸騰週期再 -25%;質性差分=**噴泉順序隨機化**(每循環 Fisher-Yates 洗牌出序, + rng 注入可測;一般模式恆固定升序可背板)。 + +## 80. v12 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) + +| 怪物 | FSM 時序 | 可吸性 | 星味映射 | +| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------- | +| 星屑幽靈 Twinkla | phased 虛化 2.0s(半透明、不可吸不可傷、穿身無害)→ shimmer 星光聚攏 0.5s(telegraph)→ solid 實體 1.8s(緩慢追飄,可吸可傷窗)→ 回虛化 | 條件可吸(實體窗) | 流光味 | +| 彗尾飛魚 Cometa | glide 高處巡游 →(玩家進 230px 觸發域)→ lock 鎖定 0.55s(閃爍,鎖定後不修正)→ dash 斜向俯衝 0.6s(420px/s 沿路拖彗尾 hazards)→ recover 回升 | 恆可吸 | 疾風味 | + +- Twinkla 穿身無害=isPhasedOut(觸碰不結算、吸力不彈開)+damage 免傷雙閘; + 精英「星屑幽長」(×1.4)僅縮虛化期,telegraph 與實體窗不縮(§48 審查慣例)。 +- Cometa 彗尾段走 hazards 管線(tailIntervalMs 90/tailLifeMs 500 逾時必回收 + §56);精英「彗核疾魚」俯衝 ×1.4;鎖定後不修正=可預判閃避。 +- 圖鑑補完:雙新怪入鑑(18 小怪)+三新魔王徽記(Prismix/Syrona/Voidra,5 魔王) + ——23 格佈局沿 cols 條目數推導。 + +## 82. v12 最終魔王:蝕星魔核 Voidra(logic/voidraFsm.ts 表驅動,場控收束型) + +- HP 110(魔王階梯峰值 > Syrona 90);三段結構(主計畫 §6.3 v12 定案:P2=定點 + 轟炸生存段,追逐捲軸案落 backlog): + - **P1 王座戰(>70%)**:pull 重力牽引(漣漪 telegraph+水平 positional drift + 110px/s 恆低於玩家全速)→ ring 星屑彈環 ×6 → claw 虛空爪擊(落點紫紋 0.6s、 + 鎖定不修正);收爪僵直 2.5s 固定輸出窗。 + - **P2 生存段(70-40% 或 40s)**:核心升頂不可及(受擊體停用+FSM 免傷雙閘)、 + 40s 波次表定點轟炸——隕星波(沿 §79 meteor 管線連續投放)+晶柱崩落 ×7 波 + (落點預警 0.7s)+炮擊過熱窗 ×3(核心下沉 3.0s=唯一輸出窗);沿途空投星屑 + ×5(§83 彩蛋收集);段內固定慈悲愛心 1 顆(16s 投放)。時間驅動(40s 播完) + 與傷害驅動(過熱窗打穿 40%)雙轉換路徑入 P3。 + - **P3 核心決戰(≤40%)**:全場低重力 0.55 注入 → barrage 蝕星彈幕(放射 ×8+ + 螺旋雙層)→ crush 黑洞潮汐(水平牽引 150px/s < 玩家全速 220,交叉不變式 16; + arena 無坑洞+實牆邊界);裂核大窗 3.5s(金紋呼吸提示)。 + (v23 已由 §113 取代:P1/P3 固定循環改 `voidraMoveTable` 加權表選招並追加 + 星光虹吸;招池與 telegraph 數值不變、P2 波次表驅動不變。) +- anti-softlock(主計畫 §10.2-8):P2 零擊殺可過(純走位 40s)、無位置懲罰即死、 + 不設計時失敗;**段起點重試**——P2/P3 死亡不回滾整場(trySegmentRespawn:彈幕/ + 星屑/轟炸/殘留 delayedCall 清場+FSM resetToPhase+玩家沿 checkpoint 管線重生於 + arena 左帶);P1 死亡走一般敗北流程。defeated 單向鎖存冪等。 +- 段重試清場(審查根修):段起點重試保留同一場景——補給小怪與飛行中隕星/餘燼 + 必須隨重生全數清除(GameScene.clearFieldForSegmentRetry,比照整場重啟語義), + 且 spawnBossMinion 夾限場上 maxOnScreen+2(爆發傷害連觸掉落不得堆出接觸傷害牆; + 彈藥保證由 §26 飢荒立即補生承擔)。 +- 勝利結算窗防護(QA 根修):BOSS_DEFEATED 即授 i-frame(WIN_DELAY+2s)+ + PLAYER_DIED 於 bossDown 後直接忽略——殘餘 hazard(墜落中隕星/餘燼/潮汐)不得 + 奪走勝利(真實 e2e 抓出的競態)。 +- 呈現層(systems/voidra.ts):核心位置一律 approachPoint 逼近錨點(§64 慣例禁 + 絕對座標直寫;P1 中高懸浮/P2 升頂/過熱窗與 P3 下沉可打帶);魔王關體系沿用 + (前室 400px+星力果/疾風靴二選一;arena 增益 `arenaBuffPhase: 'p3'`——P2 為 + 生存段不投放,護盾泡延至 P3 高風險位)。 +- EX 差分:HP 沿 EX_MODS 共用 ×1.5=165(兩魔王既成慣例)、P2 轟炸密度 ×1.25、 + P3 螺旋三層;EX arena 增益不投放(§69 慣例)。 +- 補給:每損 10 HP 掉補給小怪(§26 飢荒保證律);L20 補生 jelly/floaty/glowy + 全可吸;P2 免傷帶內 waves 補給照常(彈藥為 P3 儲備)。 + +## 86. v13 EX 全魔王與星核制霸(EX 體系收尾+全制霸獎勵) + +> 20 關主線(v10-v12)完結後的 EX 收尾列車:把 v9 首發(§58 L4/L7)的 EX 變體 +> 體系補齊到全部 5 魔王,並為五王全制霸給一項有感獎勵。FSM 差分(EX_PRISMIX/ +> EX_SYRONA/EX_VOIDRA)與呈現層 ex 注入已隨 v10-v12 落地(§68/§74/§82), +> 本章收斂出貨面缺口與全制霸體系。 + +### 86.1 EX 差分總表(五王;HP 一律 EX_MODS ×1.5、節奏 ×1.15) + +| 魔王 | EX HP | 質變差分(每王一項,非純數值) | 反制語彙 | +| ----------- | ----- | --------------------------------------------------------------- | ------------------------ | +| 果凍王 L4 | 90 | 擊破分裂 3 小果凍(§58) | 保留彈藥收尾 | +| 蝠王 L7 | 78 | P3 月蝕彈幕矩陣(§58) | 讀缺口通道 | +| Prismix L12 | 120 | 雙子動作去同步(相位錯半拍 260ms;分裂 75%/掙扎窗 0.7s/盾 6) | 逐具讀招取代對稱背板 | +| Syrona L16 | 135 | 噴泉順序隨機化(每循環洗牌、seed 注入可測;潮汐再 -25%) | 讀 telegraph 取代背板 | +| Voidra L20 | 165 | P2 轟炸密度 ×1.25+P3 螺旋三層(愛心上限 1) | 走位風箏+過熱窗集中輸出 | + +(v24 取代標註:T6 EX 重設計於本表之上追加 EX 專屬 P4 第二血條——Prismix 已落地 +§114,Syrona/Voidra 於 W2/W3 落地。) + +### 86.2 出貨面收斂(本車實作) + +- **EX 徽鈕**:MapScene `addExEntrance` 自 §58 起即以 `level.boss` 通用掛載—— + L12/L16/L20 通關即出現,本車以 e2e 驗證收口(分頁地圖下三新王徽鈕全數可達)。 +- **exPending 提示**:改 `exConquestDone` 判定——L9 通關起提示,五王全制霸才消失 + (原 hardcode 只看 L4/L7)。 +- **EX 慈悲愛心上限**(主計畫 §7.4 補齊):`MERCY_HEAL.exMaxPerLife = 1`(一般 + 魔王房 2);Voidra P2 生存段固定愛心走獨立管線不計上限。 +- **EX 再戰保留**:`GameResultData.ex`——敗北結算「再戰魔王」與暫停「重新開始」 + 均保留變體模式;EX 擊破僅記 `exCleared` 星章,不動一般 cleared/bestTime(§58)。 +- **圖鑑紫星映射**:EX 星章補齊五王(原僅 L4/L7)。 + +### 86.3 星核制霸(全制霸獎勵,純呈現層 cosmetic) + +- 判定:`exConquestDone(save)`——`BOSS_LEVEL_IDS`(由 LEVELS 派生,禁第二份硬編 + 清單)全數 `exCleared === true`。 +- 獎勵(零平衡影響、零新素材): + - TitleScene:金色星噗噗換裝(金 tint)+金暈+「星核制霸」章。 + - CodexScene:圖鑑右上常設「星核制霸」金徽記(金星+金章)。 +- 裁決:Boss Rush 入口超出本車 timebox,落 backlog(主計畫 §11-7);cosmetic 案 + KISS 且與 §61 彩蛋紀律一致(不給永久成長)。 + +### 86.4 L4/L7 前室 retrofit(主計畫 §7.1 v11+ 擇機項,本車收掉) + +- 資料:L4 前室 400px+護盾/星力二選一+P2 疾風靴(沿 L12 攻壓型組合); + L7 前室 400px+護盾/疾風二選一+P2 星力果(空戰輸出窗短,沿 L16 語彙)。 +- 呈現層:stage elements 統一平移前室寬(與 decor 同語義「arena 相對座標」; + 走動關 xOffset=0 零影響)——L7 雙彈簧板資料座標不動、自動平移。 +- 全五魔王關前室體系一致性由 levels.test 資料驅動守門。 + +### 86.5 測試與保底實證 + +- vitest:exConquestDone/mercy EX 上限/L4·L7 前室一致性/EX 公平性下限 + (掙扎窗 ≥600ms、desync ≥200ms 且 < 最短 telegraph)四案新增。 +- e2e(v13.spec 七案):L12 EX 徽鈕全流程(HP 120 磨破寫 exCleared 不動 + bestTime)、L16/L20 EX smoke(HP 135/165)、星核制霸存檔三場景零錯誤、 + L4/L7 前室相機回歸網(入場運鏡後 scrollX 貼齊 anteroomPx、玩家恆在視窗內)、 + EX 中途退出防鎖、EX 敗北再戰(Result 保留變體重入 HP 120)、v9 世代舊存檔 + 相容(EX 紀錄保留)。 +- 保底實證(1200 寬 trace,`scripts/ex-bot-driver.mjs` 瀏覽器內 80ms tick + driver;EX 屬再戰內容、入場自願、可退出、不鎖主線進度): + - L16 EX 純標準星 **won 73.6s**(整場重試 1);L20 EX 純標準星 **won 129.8s** + (段重試 3 零卡關)——trace 存 `screenshots/starpuff-v13/`。 + - L12 EX 採**二段論**:輸出鏈 assist(受控 i-frame 隔離迴避軸)**won 30.8s** + 三階段擊破鏈完整無 DPS 死鎖;迴避軸由公平性下限單測(各招 telegraph + ≥500ms 不受 desync 侵蝕、掙扎窗 700ms)+純模式十輪 trace(最佳壓血 + 25/120、單輪最長 36.5s——輸出與存活各自成立)分別背書。規則 bot 的一維 + 決策(同 tick 僅一行為)在鏡像雙子去同步下組合不出全程,屬 bot 決策上限 + 而非已證實的設計軟鎖;人類具備並行操作與前室增益/變身資源(bot 自我設限 + 純標準星且不拾前室台座)。 +- 觀測點:`__sp.bossHazards()`(shockwave 型危害)+`__sp.enemyPositions()`+ + Prismix `getDebugState` 補齊(bot 讀招取樣);`__sp.gotoLevel(id, ex)` 支援 + EX 直達。 +- B1 修復(審查收斂):L4/L7 retrofit 初版漏掉 boss.ts/noctra.ts 呈現層的 + 世界座標平移(相機 pan/攻擊落點/投射物回收界皆以 0 為基準),入場運鏡把 + 相機拉回世界原點致玩家離屏——補 `arenaLeft` hook 注入(沿 prismix/syrona + 既有 pattern),全座標計算平移 arena 左緣;缺省 0 行為零變。 + +## 111. v21 魔王主題化 W1——加權選招+Jellord/Noctra 主題招式(#813;T5 列車) + +取代標註:§6 P1/P2 固定循環與 §54 `noctraAttackCycle` 循環游標敘述由本節加權表驅動取代 +(招池與數值不變,僅選招機制升級);telegraph 窗全部維持現值不降(可讀性紅線)。 + +### 111.1 FSM 加權選招基礎設施(logic/moveTable.ts,SSOT) + +- 招式序由固定循環改**加權表驅動**:`weight`(權重欄)+`condition`(條件欄,宣告式 + HP 帶 `minHpRatio`/`maxHpRatio` 與玩家距離帶 `band: near|far`,門檻 300px、未知視 far)。 +- rng 注入可測(`createSeededRng` mulberry32,同 seed 完整重放);缺省 `Math.random`。 +- 連續同招上限 2(防隨機劣化體感);條件全剔除時回退整表(anti-softlock 永不空手)。 +- 兩王 FSM 增 `setTargetDistance`(呈現層逐幀餵送);`JELLORD_MOVES` 與 `noctraMoveTable` + 為招池 SSOT——Jellord dash 限遠距帶(貼身衝撞不可讀),其餘權重對齊原循環頻率。 + +### 111.2 Jellord 主題招式「果凍回彈」(logic/jellyPatch.ts) + +- P2 起 slam 指令帶 `jelly` 旗標:踩踏落點地面果凍化 3s(粉色地塊,壽命內淡出)。 +- 玩家踩上被彈起(非傷害):初速 -560(高於跳躍 -420、低於彈簧 -640),可接漂浮控高 + ——果凍地形=免費跳台;經既有 `getVentLift` 管線結算(GameScene 零接線變更), + 彈起 200ms 冷卻防連觸。既有下砸暈窗反制(§58 slamStun)不變。 + +### 111.3 Noctra 主題招式「蝕月斗篷」(logic/eclipseCloak.ts) + +- P2 起低頻(權重 1,全表最低)新招 `cloak`:隱形 1.2s 固定不隨狂暴速率縮放, + 僅月牙軌跡粒子可見;進出各 180ms fade 無跳變。 +- 反制(吸入第二用途):按住吸入產生氣流擾動使輪廓顯形(alpha 0.06 → 0.5); + hooks `isPlayerInhaling` 由 bossFactory 接線 player.isInhaling()。 + +## 112. v22 魔王主題化 W2——Prismix/Syrona 加權選招與主題招式(#813;T5 列車) + +取代標註:§68 P1-P3 固定循環由 `prismixMoveTable` 加權表取代、§74 三階段循環由 +`syronaMoveTable` 加權表取代(既有招池數值不變,僅選招機制升級+主題招式擴池); +telegraph 窗全部維持現值不降(可讀性紅線)。基礎設施沿 §111.1 moveTable SSOT。 + +### 112.1 加權選招接入(沿 §111.1,兩王 FSM 增 rng/setTargetDistance) + +- Prismix:P1 晶柱 3/光束 3;P2 夾擊 3/交錯光束 3/召喚 2/鏡界反射 2/鏡像殘影 1 + (條件欄 `maxHpRatio: 0.5`——總血 ≤50% 深段才入池,HP 帶條件示例);P3 彈幕 3/晶雨 3。 +- Syrona:P1 噴泉 3/射彈 3(條件欄 `band: 'far'`——貼身拋物不可讀,沿 Jellord dash + 遠距帶理據);P2 滴落 3/噴泉 3/召喚 2;P3 糖漿波 3/超載 3。 +- 換階段清空同招記錄;rng 注入同 seed 可重放(Syrona 與噴泉洗牌共用同一 rng)。 +- 條件熵驗收(#818 口徑,seed 13 × 60 招):Prismix P1 0.90/P2 1.47(≤50% 深段 1.93)、 + Syrona P1 0.90/P2 1.38/P3 0.90 bits,全數 ≥ `AUDIT_THRESHOLDS.moveEntropyMinBits`(0.5)。 + +### 112.2 Prismix 主題招式「鏡界反射」(FSM 態內建) + +- P2 新招 `mirror`:單具開鏡 0.8s(銀白鏡光面板 telegraph,固定不隨狂暴縮放); + 開鏡側受擊零傷、FSM 回 `reflect` 事件,呈現層自該具生成折返彈射向玩家。 +- 反制(可學習):開鏡窗內打另一具照常結算;折返彈帶 `inhalable` 標記——吸入中接觸 + 即回收為彈藥(免費彈藥=獎勵理解,L9 mirri 已預教鏡性);不吸則照常 1 傷。 +- 開鏡側由 rng 抽選(同 seed 可重放);單側殘存防呆歸存活具。 + +### 112.3 Prismix 主題招式「鏡像殘影」(logic/mirrorShadow.ts) + +- P2 深段(總血 ≤50%)低頻新招 `shadow`:玩家鏡影自 arena 中線鏡射位現身—— + 水平反向移動(玩家逐幀位移取負向套用)、垂直速度上限跟隨、觸傷 1、6s 壽命、 + 1 發星彈即破;單具重生刷新(不疊加)。 +- 反制(mirri 鏡性課):反向移動特性=向遠離殘影方向移動即以雙倍速率分離; + 一發基礎星彈即可拆除(anti-softlock:基礎星彈恆可清)。 +- 工程接點:殘影 sprite 雙掛既有 `shields`(星彈可破)+`shockwaves`(觸傷)群組, + BossHandle 零新選配;碎晶盾軌道迴圈以 `shadow` data 旗標跳過。 + +### 112.4 Syrona 主題招式「焦糖化」(logic/caramel.ts + systems/caramelStatus.ts) + +- P3 糖漿波帶 `caramel` 旗標:沾身減速 30%/3s(琥珀色腳部沾糖粒子),重複沾波刷新 + 不疊加;狀態真值收斂 logic/caramel.ts,呈現編排收斂 systems/caramelStatus.ts + (守 GameScene 1200 行閘),移速與 buff 倍率單點合成注入 player(防互相覆寫)。 +- 反制(可學習):乘噴口氣流吹乾即解除(`getVentLift` 供力當幀清除);雷化放電瞬除 + (volt 形態既免疫沾身也瞬除既有沾身——變身優勢解);首次沾身浮字教學(session 一次)。 +- overlaps 接點:shockwave 命中玩家時讀 `caramel` data 旗標經 `applyCaramel` hook 結算, + 傷害照常走 `damagePlayer` 單一入口。 + +## 113. v23 魔王主題化 W3——Voidra 加權選招與星光虹吸(#813;T5 列車) + +取代標註:§82 P1/P3 固定循環由 `voidraMoveTable` 加權表取代(既有招池數值不變, +僅選招機制升級+主題招式擴池);P2 生存段仍為波次表驅動(§82 不變); +telegraph 窗全部維持現值不降(可讀性紅線)。基礎設施沿 §111.1 moveTable SSOT。 + +### 113.1 加權選招接入(沿 §111.1,FSM 增 rng/setTargetDistance) + +- P1 牽引 3/彈環 3/爪擊 3/虹吸 2;P3 彈幕 3/潮汐 3/虹吸 2(虹吸為低頻主題招, + 權重全表最低);P2 波次表驅動不變(`voidraMoveTable('p2')` 僅供對表)。 +- 換階段清空同招記錄;rng 注入同 seed 可重放;連續同招上限 2;死碼 + `voidraAttackCycle` 移除。 +- 條件熵驗收(#818 口徑,seed 13 × 60 招):P1 1.76、P3 1.38 bits,均 ≥ + `AUDIT_THRESHOLDS.moveEntropyMinBits`(0.5)。 + +### 113.2 Voidra 主題招式「星光虹吸」(logic/starSiphon.ts) + +- P1/P3 新招 `siphon`:紫色吸流 0.8s 窗(固定不隨狂暴速率縮放,≥600ms 可讀性紅線) + ——吸流粒子沿玩家→核心路徑收斂+核心紫染 telegraph;窗滿抽走彈匣頂槽 1 發化為 + 自身護盾 1 層(環繞核心紫星軌道,上限 2 層,每層抵銷 1 次受擊零傷、不掉補給)。 +- 反制(高技巧獎勵):窗內朝吸流發射=星彈逆流爆盾——護盾全清+回傷 4(與來彈 + 傷害取較大值,不懲罰重彈)+取消本次抽取;把損失變輸出窗。 +- 空匣防呆(anti-softlock):窗滿無彈可抽=僅演出不獲盾;護盾僅來自實際抽取, + 基礎星彈恆可於窗內爆盾(§10.2 不變式維持)。 +- 工程接點:窗長/上限/回傷 SSOT `logic/starSiphon.ts`;FSM 窗滿發 `siphonDrain` + 指令,呈現層經 hooks `drainTopStar()`(bossFactory 接 `player.stealTopStar()`, + 彈匣單一真值、HUD ammo 事件自動同步)回餵 `absorbSiphonStar()` 夾限化盾; + 段起點重試清空護盾層(§82 清場語義);save 零改動、BossHandle 零新選配。 + +## 114. v24 EX 全面重設計 W1——Prismix P4 裂核殘響(#814;T6 列車) + +> EX 挑戰全面升級:每王 EX 追加專屬第四型態(P4)=第二血條,總有效 HP 相對一般 +> 約 ×2.25(難度翻倍);技巧破關、非 RNG 死牆。W1 落地 Prismix;Syrona/Voidra +> P4 於 W2/W3 落地(差分定稿見 `.claude/epics/starpuff-t6/updates/stream-main.md`)。 +> 取代標註:§86.1 Prismix EX 差分列由本章擴充(原差分保留,追加 P4)。 + +### 114.1 型別基建:BossPhase 擴為四段 + +- `BossPhase` 聯集加 `'p4'`(EX 專屬型態);五 FSM 的 `Record` + 補 p4 鍵、moveTable switch 補 p4 分支——Jellord/Noctra 執行期不可達(沿 p3 值), + Syrona/Voidra 暫沿 p3 待 W2/W3 落真 P4;Voidra 段起點重試明確限 p2/p3。 +- HUD `BOSS_PHASE` p4 → 血條金緋換色(0xe8b45a)+滿灌重灌=第二血條視覺。 + +### 114.2 Prismix EX P4「裂核殘響」(prismixFsm SSOT) + +- 觸發:EX 限定,P3 裂核歸零不死——`enterRebirth`:phase p4、第二血池 + `rebirthHpRatio 0.5`(EX 120 → 60)、`maxHp` getter 換刻度供 HUD 重灌; + 僅可重生一次(p4 歸零才 `defeated`)。 +- EX 雙子連破:掙扎窗補殺彩蛋保留(twinFinish 照發),改跳過 P3 直入 P4 + (跳段不跳王——技巧獎勵仍成立且 EX 專屬型態不可跳過)。 +- P4 招池:稜光行牆 3/彈幕 3/晶雨 2;P4 speedFactor 沿狂暴帶 1.15(疊 EX + 1.15 ≈ 1.32——W1.6 合規修正:初版 1.25 終段加壓違反 §8.1 面板紅線已收回)。 +- 新招「稜光行牆」(sweep):起掃側 rng 抽側(同 seed 可重放)、側緣豎線閃爍 + telegraph 700ms(固定不縮放)後,全高 120px 光牆以 180px/s 橫掃全場,出界回收。 + 跳越窗=跳+拍翅時機(`maxJumpClearancePx≈210` vs 牆高 120,vitest 錨定 + `sweepWallHeightPx ≤ maxJumpClearancePx()-60` 裕度)。 +- anti-softlock:供彈保證律(每 10 傷 minionDrop)跨 P4 延續;telegraph 紅線 + ≥600ms 全數維持;碎晶盾於重生時全數碎裂(P4 無盾環,輸出路徑純淨)。 +- 呈現層:重生演出(閃屏+震動+核體金緋重構 Back.easeOut);EX 緋紅呼吸循環 + 於 P4 讓位金緋定色;受擊白閃 restore 對 p4 回金緋。 + +### 114.3 驗收探針(#818 level-audit) + +- `node scripts/level-audit.mjs 12 --ex --bot low|high --runs N`:低階 clearRate + <20%、高階 ≥60%(門檻 SSOT `AUDIT_THRESHOLDS.exLowPassMaxRate/exHighPassMinRate`)。 + +### 114.4 W1.6 調參(PM 裁決落地:段檢查點+滑近週期化) + +W1.5 分級 bot 死因取證(高階 0%:p2 死 41/51、機制全解、輸出可用但 180 有效血 +無檢查點=90s 單命耐力牆)後 PM 裁決: + +- **EX 段檢查點 P3/P4**(裁決①,後經裁決 A 修訂為進度保留): + `prismixFsm.resetToPhase('p3'|'p4')`——EX 限定,P3/P4 死亡不回滾整場, + 沿 voidra `trySegmentRespawn` 清場管線(投射物/排程/鏡界全清+HUD 同步); + P1/P2 與非 EX 走一般敗北流程。難度語意自「單命耐力」轉「分段技巧驗收」。 +- **進度保留語意(PM 裁決 A,取代初版段門檻回灌)**:死亡僅重置玩家、 + boss 血不回灌——量測實證回灌語意在 P3/P4 形成「段命磨量 vs 段血回灌」 + 臨界輪迴(段內死牆:五測 p4 死 110/162、通關 1);voidra 回灌慣例的 + 存在理由(P2 波次表重播 anti-softlock)於 P3/P4 不適用。技巧性不降 + (每招仍需應對)、面板紅線不動;碎晶盾亦不隨段重試重生(同語意)。 +- **P1 滑近週期化**(裁決③輕量版):EX 限定 `glidePursuing`(追 3.2s/歇 1.4s, + 追擊窗佔主導守「不站樁」紅線)——消恆時追擊的強制跨越稅、給明確輸出窗; + 非 EX 與 P3/P4 恆時滑近不動。 +- **觀察項(PM 裁決④記錄)**:非 EX L12 高階 bot 通過率 50%(其他王 100%)—— + Prismix 主線難度曲線相對同儕右移,主線調參另議、本輪不動。 + +## 115. v24 EX 全面重設計 W2——Syrona 窯心暴走+Voidra 內核裸奔(#814;T6 列車) + +依 §8.2 表落地後二王 EX 專屬型態(phase+1),HUD 雙血條沿 BOSS_PHASE/ +BOSS_DAMAGED 既有管線泛化(barTint 覆寫欄,零新 HUD 系統)。 + +### 115.1 Syrona EX P4「窯心暴走」(syronaFsm SSOT) + +- 觸發:EX 限定,P3 血量跌破 `EX_SYRONA.rampageHpRatio`(15%)入 P4。 +- 皇冠唯一可傷點:`takeDamage(amount, crown)` P4 期體傷歸零(可傷性裁決收斂 + FSM);皇冠 ×2 倍傷沿 §74 呈現層結算——登頂技巧強制驗收(單跳頂帶窗/ + 噴口升托皆可達,anti-softlock 基礎星彈恆可通關)。 +- 全場沸騰:週期 ×`rampageBoilPeriodMul`(0.45)、漲頂 `rampageBoilMaxYDeltaPx` + (-40 → 312)——恆低於最高浮台(304),保底立足位不變式;退潮窗照常 + (無計時失敗紅線)。 +- 血條結構:單條+暴走段深紅(`barTint` 覆寫;與 p2 常規紅區隔);本體紅化。 +- 招池沿 p3(wave/overload)——overload 升托即登頂輸出窗。 + +### 115.2 Voidra EX P4「內核裸奔」(voidraFsm SSOT) + +- 觸發:EX 限定,外核(既有三段全池 165)歸零不死——內核獨立血池滿灌。 +- 雙血條:外核 60%/內核 40%(`innerHpRatio` 2/3 推導:165:110);HUD 血條 + 重灌換刻度+亮紫換色(沿 Prismix P4 慣例)。 +- 裸奔差分:體積 ×0.6、移速 ×1.4(呈現層 EX_VOIDRA SSOT)、招式間隔 ×0.8 + (SPEED_FACTORS.p4 分母化;僵直窗/吸流窗固定值不縮,hit window 紅線保留)。 +- 段重試擴 P4(進度保留語意,沿 Prismix PM 裁決 A:無波次表重播需求, + 死亡僅重置玩家、內核血不回灌;p2/p3 沿既有回灌慣例不動)。 +- 招池沿 p3(barrage/crush/siphon)——語彙不變、節奏與幾何差分。 + +### 115.3 T6 終局驗收(#818 分級 bot,各 6 runs,2026-07-24) + +| 王 | EX high(≥60%) | EX low(<20%) | 非 EX high 對照 | +| ----------- | ----------------------- | -------------- | ------------------------ | +| L4 Jellord | 83% ✓(TTK 27s) | 0% ✓ | 100%(0 死) | +| L7 Noctra | 67% ✓(TTK 29s) | 17% ✓ | 100%(0.17 死) | +| L12 Prismix | **100%** ✓(TTK 74.5s) | 0% ✓ | 50%(右移觀察項 §114.4) | +| L16 Syrona | 67% ✓(TTK 32s) | 17% ✓ | 100%(0 死) | +| L20 Voidra | 67% ✓(TTK 236s) | 0% ✓ | 100%(2.17 死) | + +- 十門檻全 PASS(#814 驗收標準達成)。量測口徑:EX high 一律 cap 540s + (checkpoint 架構通關期望 200-400s;歷史 artifact 中 L20 曾以 360s 量得 + 67%——W3 已按 540 口徑重跑回填,見 §115.4)、bot 分級 SSOT + `difficulty.BOT_TIERS`(low 恆基礎策略——bossForage/crown 節拍等完整 + 策略均 tier gate)。 +- L12 決定性因素=段重試進度保留(回灌語意 0-17% → 保留語意 100%); + L16 low 首測 33% 為 crown 節拍漏 tier gate 的量測污染,gate 後 17%。 + +## 116. v24 EX 全面重設計 W3——Jellord 果凍狂潮+Noctra 月相雙血條+皇冠共鳴(#814;T6 收斂) + +W3 合議收斂:補齊 §8.2 表前二王真 P4(stub 落地)+Syrona 暴走段 incidental +可傷面收斂+段重試雙語意局內提示。 + +### 116.1 Jellord EX P4「果凍狂潮」(bossFsm SSOT) + +- 觸發:EX 限定,主條(90)歸零不死——狂潮小條滿灌(`EX_JELLORD.frenzyHp` + 15,§8.2 表定值),phase 單向鎖存(`phaseForHp` 由 hp 推導不回落)。 +- 全地板果凍化:週期全場重鋪果凍地塊(壽命 3s/重鋪 2.2s 覆蓋連續)—— + 強制彈跳中作戰沿 §5 果凍回彈既有機制(零新系統)。 +- 分裂小果凍(§58 EX 彩蛋)改隨狂潮入場(演出+場上補給),真擊破不重發。 +- 血條:單條+狂潮段果凍粉(barTint 泛化);招池/節奏沿 p3(§8.1 面板紅線)。 +- P4 段重試(W3 終局,沿裁決 A 同構):狂潮死亡進度保留(小條不回灌、 + 地塊/彈幕清場重鋪)——取證:high bot 每命抵達 P4 殘血 1-2、無檢查點 17% + 結構死牆(與 L12/L16 同簽名);P1-P3 維持整場重打。 + +### 116.2 Noctra EX P4「月相雙血條」(noctraFsm SSOT) + +- 觸發:EX 限定,亮月條(主池 78)破而不死——暗月條滿灌 + (`EX_NOCTRA.darkMoonHpRatio` 0.5 → 39;「各 50%」=暗月為亮月半值, + 沿 Prismix rebirthHpRatio 同構),HUD 重灌換色(銀紫)。 +- 暗月差分:隱形頻率 ×2(p4 招池 cloak 權重 1→2)+月牙軌跡變細 + (`darkSweepScaleMul` 0.65:掠行判定帶與本體縱向縮細;telegraph 時長 + 不縮——可讀性紅線只縮體不縮窗);月蝕矩陣(EX 質性差分)續存。 +- P4 段重試(W3 終局,沿裁決 A 同構):暗月死亡進度保留(暗月條不回灌、 + 彈幕清場+隱形/俯衝態復位回盤旋)——取證:high bot 每命抵達 P4 殘血 0-2、 + 無檢查點 0% 結構死牆;P1-P3 維持整場重打。 + +### 116.3 Syrona 皇冠共鳴連擊(W3 Blocking 收斂) + +- 問題:crown tier gate 後 low 仍 33%(>20%)——overload 升托/高台誤射的 + incidental 皇冠命中 ×2 倍傷可 2 發偶中秒掉暴走池(20 血)。 +- 修法(v2 共鳴解鎖制;v1 單發節拍窗 900ms 實測誤傷 high——體傷命中不入 + 節拍、跨跳輪 crown 命中間隔 ~950-1600ms 致 25/26 全 glance):窗內 + (`crownComboWindowMs` 1600)累積 `crownResonanceHits`(3)中解鎖全額、 + 斷窗重計;解鎖前皆 `crownGlanceDamage`(1 點,anti-softlock 恆可磨)。 + 低階 overload 單簇(2-4 發)解鎖後至多 1 發全額(≤13 < 暴走池 20) + 不秒池、簇間 8-12s 必斷窗。 +- 技巧語意:「登頂後維持命中流」=主動技巧驗收升級,偶中簇不再成立。 + +### 116.4 段重試雙語意局內提示(W3) + +- 同王雙語意(Voidra p2/p3 回灌 vs p4 進度保留;Syrona p4 進度保留見 + §116.5)以 `BOSS_SEGMENT_RETRY` 事件(producer:boss systems + trySegmentRespawn)→ systems/toasts 浮字區分「段首重試——魔王傷勢保留 + /魔王氣力回復」;每語意每局一次。 +- 受擊白閃 restore-tint(voidra/syrona 同構修復):P4 段位相色(裸奔亮紫 + /暴走紅化)白閃回落復原而非 clearTint 洗掉。 +- EX 緋紅呼吸循環 P4 讓位(W3 收斂):呼吸 onUpdate 每幀 setTint 會覆寫 + 段位相色——voidra/syrona 補 `fsm.phase === 'p4'` 早退 guard(鏡 prismix + W1 既有慣例),P4 定色不再被洗掉。 + +### 116.5 Syrona EX P4 段重試(W3 v2 收斂) + +- 取證:共鳴 v2+登頂窄窗(airMs 380-560、節流 90ms)後 L16 EX high 仍 + 0%(寬窄窗兩測 6-run 全 timeout、15.17 死/次)——高階 bot 每命例行抵達 + P4 並磨池至 11-12,但 Syrona 無段重試:死亡=135 整場重打、暴走池 + (135×0.15≈20)隨之重灌,單命皇冠輸出上限 ~9 < 20 ⇒ P4 結構性不可完成 + (與 L12 W1.6 六輪 0-17% 死牆同簽名)。 +- 修法(沿 Prismix/Voidra PM 裁決 A 同構):P4 死亡段內重試「進度保留」—— + hp/供彈累計不回灌、共鳴窗歸零(新命重啟命中流,不繼承解鎖態)、殘留 + 彈藥/衝擊波/延時全清(死亡前排程不得於新命憑空觸發)、全場沸騰以同 + spec 自新週期起漲(重生喘息窗);P1-P3 維持整場重打(抵達暴走的耐力 + 驗收保留)。`BOSS_SEGMENT_RETRY` kept 語意浮字沿 §116.4 管線。 +- anti-softlock:進度單調不退+供彈保證律延續——基礎星彈恆可磨死暴走池; + 面板紅線不動(EX_MODS/暴走池比率均未調)。 + +### 116.6 Syrona P4 噴口氣流登頂(W3 終局,PM 裁決) + +- 取證(真值探針,兩層幾何互鎖):跳打 apex 僅入皇冠帶 3px 的根因—— + (a)皇冠帶錨定 sprite 視覺框頂,但可命中物理箱頂緣低數十 px,帶內幾乎 + 無可重疊面;(b)§54 魔王準星輔助把長程星彈導向本體中心,主動拉出皇冠帶 + (懸停帶內 800 發零傷實測)。近距跳射僅因飛行短、彎不下去而偶中。 +- 皇冠帶錨點修正:`isCrownHit` 錨點自視覺頂收斂至「物理箱頂緣」單一真值 + (帶寬 `CROWN_BAND_PX` 34 不變,精準度保留;`__sp.bossPos().top` 供 bot + 取樣)。 +- 乘流登頂:P4 暴走段噴口窯壓恆噴(不看週期,柱色紅金訊號)+皇冠帶氣墊 + `crownHoverLift`(位置伺服懸停於物理箱頂+22,≥600ms 級穩定滯空輸出窗) + ——「像素級擦帶跳」升級為可學習的乘流登頂技巧;水平離柱即交還重力, + 無滯留軟鎖。 +- 準星輔助讓位:`BossHandle.aimAssistMode`——Syrona P4 回 `'off'`,星彈平飛 + 保留「乘流懸停高度=皇冠命中」的精準語意;其餘魔王/相位維持 center 既有 + 行為(低階保底線不動)。 +- 持鍵乘流(低門檻洩漏修正 v2):氣墊懸停僅跳躍鍵持按時供力 + (`getVentLift` rideHeld 參數,GameScene 餵 `controls.state.jumpHeld`)—— + 首版被動抬升使誤入噴口的低階 bot 假性通關(12-run 58% 取證);低階只點跳 + 不持鍵,天然被擋。 +- 窯風共振(低門檻洩漏修正 v2):P4 皇冠命中必須乘流中(`targetRidingVent`) + 才有效——未乘流命中一律體傷語意(0 傷金屬聲),關閉中台站射免技巧 chip + 通道;P1-P3 皇冠 ×2 維持純幾何。技巧門檻=「會用噴口」(PM 裁決語意 + 機械化);乘流中節拍仍由 §116.3 共鳴解鎖制收斂。 +- anti-softlock 複核:噴口恆噴保證可乘、持鍵=基礎輸入、彈盡可落地吃補給怪 + 再返場——基礎星彈恆可通關不變式成立;無計時失敗、沸騰不淹保底高台照舊。 diff --git a/apps/starpuff/docs/design/04-levels-world.md b/apps/starpuff/docs/design/04-levels-world.md new file mode 100644 index 000000000..b5f34e050 --- /dev/null +++ b/apps/starpuff/docs/design/04-levels-world.md @@ -0,0 +1,467 @@ +# 星噗噗 — 關卡設計、世界地圖與環境機制 + +> **職責範圍**:20 關的資料與節奏。關卡資料契約與各關配置、五區分頁世界地圖與解鎖鏈、彩蛋、平台與環境機制(單向平台/氣流/噴口/潮汐/折躍/低重力/流星雨)、卡點重生、魔王關前室與增益體系、每關攻略 PoC 與命名層級。 +> +> **不在本檔**:怪物與魔王本身的行為規格(見 `03-enemies-bosses.md`);反卡死保證律與供給救援律(見 `08-safety-nets.md`)。 +> +> **關卡表沿革**:L1-L4(§15)→ L5-L7(§50)→ L8-L9(§60)→ L10-L12(§65)→ L13-L16(§76)→ L17-L20(§84)。各章的**關卡列仍為該批關卡的現行規格**;被取代的只有當時的「總關數/世界地圖節點數」宣告(詳見 [`99-superseded.md`](99-superseded.md))。 +> +> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md)。 + +## 15. 關卡系統(levels.ts 為 SSOT,pure TS 可測) + +流程改為:Title → Stage 1 → 2 → 3 → 4(魔王)→ Result。死亡重試當前關;通關進下一關(轉場卡全屏 1.2s:關卡編號+名稱+緩動)(v6 已由 §39 取代:通關 → 世界地圖揭霧 → 自節點進下一關,轉場卡廢除)。 + +L1-L4 的 v2 直向世界寬配置表已全數失效(v3 §21 改橫式尺寸、後續各版重配怪物組合), +移至 [`99-superseded.md`](99-superseded.md#151-l1-l4-v2-直向配置表已失效);**現行值以 +`logic/levels.ts` 為 SSOT**。 + +- 走動:關卡 1-3 為側向卷軸(v3 定案:`camera.startFollow(player, false, 1, 1)` 剛性跟隨 + `roundPixels: false` + `setBounds(0,0,worldW,480)`;world 物理邊界同步;緣由見 §25 抖動修復定案)。 +- 通關條件:擊殺配額達成後右端出現「星星門」(fx-star 放大 + 光暈脈動 + 浮動 tween,graphics 組合,不新增美術),走入即過關。 +- 關卡資料契約(levels.ts):`{ id, nameZh, bgKey, worldWidth, killQuota, spawnIntervalMs, maxOnScreen, safeZoneTailPx, enemyMix: {kind,weight}[], platforms: {x,y,w}[] }`——GameScene 依資料驅動,禁止每關寫死邏輯分支。 +- 尾端 release:每關末 `safeZoneTailPx: 480` 禁 spawn(星星門前喘息區,鋸齒 tension-release)。`maxOnScreen`:S1 3、S2 4、S3 5。 +- HUD 增列:左上 `STAGE N 關卡名` + 配額 `⭐ n/quota`。 + +### 15.1 觸控寬容度硬規則(調研回寫,全關卡生效) + +- Coyote time 150ms、jump buffer 160ms(離台仍可跳、提前按跳落地即跳)。 +- 玩家 hurtbox = 視覺 75% 寬 × 80% 高;敵人 contact hitbox = 視覺 90%(spiky 85%)。 +- 受擊 i-frame 1.5s + 擊退期控制鎖 250ms;死亡重開載入 ≤400ms。 + +## 24. 關卡彩蛋(data-driven:levels.ts easterEggs[]) + +| 關 | 觸發 | 獎勵 | 演出 | +| --- | --------------------------- | ----------------------------------------------- | ------------------------------- | +| 1 | 開局反向走到世界最左緣 | 彩虹果凍 +1 HP | 金光 popIn + 專屬 jingle + 浮字 | +| 2 | 最高雲朵平台連續站上 3 次 | 星星雨(瞬間滿彈匣;v19 §109 無蓄能星時即結晶) | 星雨粒子 + jingle | +| 3 | 依序連吞 jelly→floaty→puffy | 金星彈一發(傷害 20) | 金彈入匣特寫 + jingle | +| 4 | 開場 5 秒內命中皇冠 | +1 HP | 皇冠火花 + jingle | + +- 觸發器型別化:`'reach-x' | 'stand-count' | 'eat-sequence' | 'crown-early-hit'`;每關至多觸發一次;純邏輯可測。 + +## 29. v4 平台玩法元素包(調研回寫後定案數值) + +Arcade Physics 相容優先(斜坡不做——Arcade 無原生支援,違反 KISS): + +| 元素 | 行為 | 關卡配置 | +| -------- | -------------------------------------------------------------------------------------------- | ---------------- | +| 單向平台 | 下方可穿上方可站(checkCollision.down only);搖桿下+跳可下落穿透(§71.1:地形粉紅平台同權) | S1 起每關 2-4 個 | +| 移動平台 | 水平/垂直往返(tween 驅動 + 玩家載運) | S2 起 1-2 個 | +| 彈簧墊 | 踩上彈跳 -640(超級跳)、squash 動畫 + 專屬音 | S2 起 1-2 個 | +| 可破壞磚 | 星彈或下衝擊破壞、碎裂粒子、內藏獎勵(彈藥/HP 小回復) | S3 起 2-3 個 | + +- 全部元素 data-driven 進 levels.ts platforms/elements 資料;純邏輯可測。 +- 反卡死約束:元素佈局不得製造不可達區域;可破壞磚不得阻擋唯一路徑(破壞前繞行可過)。 + +## 39. 迷霧世界地圖(MapScene,data-driven 自 LEVELS) + +- 入口:Title 主選單「世界地圖」+通關後自動進入(取代 §15 轉場卡直達下一關);Result 勝利鈕改「世界地圖」。Title「開始遊戲」=接續當前可挑戰關,全通關後改開地圖。 +- 橫向節點路徑:四節點(各關+魔王節點)沿虛線路徑排布,節點主題色鏡像關卡 bg 主色;禁自由漫遊式大地圖(KISS)。 +- 節點三態(解鎖規則:第 1 關恆開、第 N 關需第 N-1 關通關): + - locked:迷霧雲團遮罩+問號、關名降透明。 + - open(當前可挑戰):節點脈動 tween。 + - cleared:金星徽記+「最佳 N.Ns」;點擊重入該關(關卡選擇=重玩入口,重玩不回退解鎖態)。 +- 揭霧動畫:通關進場帶 `reveal` 節點——霧散(alpha/scale tween)+節點 Back.easeOut 彈出+zzfx reveal sting;視寬重排 restart 不重播。 +- 彩蛋計數:標題下方 `彩蛋 found/total`,total 由 LEVELS easterEggs 推導。 +- 命中一律 DOM 鈕(`data-menu="node-N"`,旋轉殼 hit-test 天然正確);鎖定節點無入口。鍵盤備援:ENTER 進當前挑戰關、ESC 回 Title。 +- 計時語義變更:hub 模型下各關獨立計時入存檔 bestTime;Result 顯示該關用時(v5 四關累計總時語義廢除)。 + +## 43. 每關攻略 PoC 與反卡關驗證 + +v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精英房均已改制),移至 +[`99-superseded.md`](99-superseded.md#43-v6-l1-l4-攻略-poc-表已失效);**現行逐關攻略以 +§49/§56 與 [`../WALKTHROUGH.md`](../WALKTHROUGH.md) 為準**。本節其餘內容(反卡關驗證 +與掃掠背擋歸因)為現行有效規則。 + +- 反卡關驗證(e2e 沿用 `__sp` 鉤子):L1「全程僅用基礎動作通關」全流程案;L2/L3 `gotoLevel` 走查——飢荒必補可吸怪斷言+地面路徑(含磚前繞跳)必達星星門;存檔重載、地圖解鎖、關卡重玩、殼盾格擋、雷鏈跳電各自獨立案。 +- 靜態 overlap 必達背擋(§26 擴充,歸因定稿):實測 Phaser 4.2.1 Arcade overlap 存在間歇漏檢(v5 基準亦可重現:彈簧 walk-over 6 次 3 失敗、星星門走入間歇不觸發),修復分兩軌、因果不可混淆—— + - `useTree: false`(main.ts):只服務 sprite vs **Group** 配對(吸入區/星彈/觸碰 vs enemies group 走 `collideSpriteVsGroup` 的動態 RTree broadphase),關閉後改直接枚舉,根治該類漏檢; + - 門/彈簧為 **direct pair**(`collideSpriteVsSprite` 直呼 `separate`、從不查 RTree)——`useTree:false` 對它們無效,真正有效且必要的是幾何掃掠背擋:星星門 `crossedGate`(跨門心/站門心右側/AABB 交疊三重判定,含 spawnGate 時已越門直判)與彈簧 `springSweepHit`(前後幀掃掠 x 區間,補高速穿越),純函式落 `logic/stageModel.ts` 供 vitest 守門,與原 overlap 共用單一觸發出口(transitioning/lockedUntil 閘去重)。**明文禁止未來把掃掠背擋當冗餘刪除。** + +## 49. v7 每關攻略 PoC 與節奏補訂(引入→練習→考驗→獎勵) + +| 關 | 引入(0-25%) | 練習(25-45%) | 考驗(45-65% 精英房) | 獎勵(65-100%) | 怪物密度(interval/maxOnScreen) | +| --- | ---------------------- | -------------------- | --------------------------- | -------------------------------- | -------------------------------- | +| 1 | 教學浮字+jelly/floaty | 單向平台+反向彩蛋 | 粉紅暴走果凍丁(跳頻 1.5×) | glowy 稀有味+回復→混合初體驗→門 | 2600ms / 3(低壓) | +| 2 | spiky/殼殼威脅初登場 | 移動平台+彈簧+雲台 | 鋼青重殼殼(血量池 14) | drilly 稀有味→碎鑽星可解鎖→門 | 1800ms / 4(中壓) | +| 3 | 八種混編暖場 | 破磚支線+吞序彩蛋 | 暗紫狂咬花(攻速 1.6×) | glowy 稀有味+雷爆/凝光清場→門 | 1300ms / 5(高壓) | +| 4 | 魔王入場運鏡 | P1 讀招(rain/slam) | P2 dash+P3 狂暴皇冠 | 皇冠彩蛋+星暴終結 | 補生 3500ms / 2 | + +- 攻略 PoC(v7 增補,§43 表仍有效): + - L1 最佳線:反向拿 +1 HP → 中段殺精英拿 glowy+回復 → 吞 jelly+floaty 合成疾光星速清尾段。 + - L2 最佳線:雲台三連站拿滿匣 → 精英房前吞 shelly 備殼盾 → 擊敗重殼殼拿 drilly → + shelly+drilly 碎鑽星掃平台群怪。 + - L3 最佳線:吞 zappy+puffy 合成雷爆星清簇 → 精英房 drilly+glowy 凝光星凍場安全輸出 + → 金星彈留給 chompy。 + - 主線恆不依賴精英/混合星(§46 anti-softlock);精英房 60s 逾時門自動開。 +- e2e 通關 bot(`__sp` hooks 驅動):L1 精英線全程通關案、L3 開門走查案(八種混編在場)、 + 精英軟鎖門阻擋/開門案、混合星彈案、drilly 免傷窗案、走動 bob 行為斷言案(v7.spec.ts)。 + +## 50. v8 關卡 4→7 與雙魔王總覽(levels.ts 資料驅動擴充) + +流程擴為:L1-L3 → L4 果凍王 → L5-L6 → L7 暗月蝠王(第二魔王收尾)(v9 已由 §60 擴為 +九關;v10 已由 §65 取代:十二關三魔王)。解鎖鏈沿 §39 +(第 N 關需 N-1 通關);世界地圖擴為七節點鋸齒路徑(節點半徑收斂 30),新節點沿用 +迷霧鎖定態。save schema v1 不變——舊存檔(≤4 關條目)原樣載入,L5 依解鎖規則自然 +開放、L6/L7 鎖定(相容契約見 save.test「v8 存檔相容」與 e2e「舊存檔相容」案)。 + +| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | +| --- | -------- | ---------- | ------ | ---- | ------ | ------------------------------ | ---------------- | +| 5 | 翔風峽谷 | bg-canyon | 3300 | 10 | 1500ms | 上升氣流柱(§51)、Gusty 主場 | 狂風飄鳥 ×1 | +| 6 | 迴聲石廊 | bg-gallery | 3600 | 12 | 1200ms | Boomy 迴旋彈道、複合陣、全混編 | 雙精英(§52) | +| 7 | 蝕月王座 | bg-eclipse | 854 | — | 3200ms | 第二魔王 Noctra(§54) | —(Boss 即高潮) | + +- LevelSpec 契約變更:`elite: EliteSpec | null` → `elites: readonly EliteSpec[]`(L6 雙精英); + `boss: boolean` → `boss: 'jellord' | 'noctra' | null`(truthy 語意與舊 boolean 相容)。 +- L6 混編為全十二種怪高密度(interval 1200 / maxOnScreen 5),可吸佔比 0.72 + (shelly/drilly 條件可吸保守不計)。 +- bg 貼圖策略(§55):L5/L7 新 biome 各生成 1 張;L6 重用 `bg-arena-l`(TEXTURE_ALIAS) + +深紫 grade 與回聲光塵 ambience 辨識;三關道具條沿用既有主題(heights/arena/throne)。 + +## 51. v8 上升氣流機制(logic/updraft.ts,pure TS 可測) + +- zone 型非碰撞元素(`{ kind: 'updraft', x, topY, w }` 入 levels elements 表): + 柱域=柱寬內、柱頂 topY 與地面頂(400)之間。 +- 升力:柱域內逐幀向上加速 1600px/s²、升速夾限 -330(低於跳躍初速 420,柱內可控); + 柱頂以上不供力自然拋出(無「黏頂」)。 +- anti-softlock(§56):頭頂受阻(blocked.up)即不供力交還重力;柱頂距世界頂 ≥100px + (資料驅動測試守門);主線恆走地面雙層——208 高台為氣流專屬支線(彩蛋/探索), + 資料不變式:y < 272 的平台必須被氣流柱涵蓋(levels.test 守門)。 +- 呈現:柱體淡色矩形(alpha 0.12)+上飄粒子(池化、單柱同活 ≤10),854/1200 皆 60fps。 + +## 56. v8 每關攻略 PoC 與 anti-softlock 不變式 + +| 關 | 引入(0-25%) | 練習(25-45%) | 考驗(45-70% 精英) | 獎勵(70-100%) | 密度 | +| --- | ---------------------- | ----------------------- | --------------------------- | ---------------------------- | ----------- | +| 5 | gusty/spora 亮相+首柱 | 氣流高台+彩蛋(×2 站) | 狂風飄鳥(俯衝 1.4×) | 迴旋味先行體驗→毒爆雲可解→門 | 1500ms / 5 | +| 6 | 全混編暖場+破磚支線 | 移動平台×2+彈簧×2 | 雙精英逐房(迴力守衛/暗雷) | 稀有味雙掉落+吞序彩蛋→門 | 1200ms / 5 | +| 7 | Noctra 入場運鏡 | P1 讀招(bomb/dive) | P2 俯衝連擊+召喚 | P3 彈幕俯掠+星暴終結 | 補生 3200ms | + +- 攻略 PoC: + - L5 最佳線:地面雙層推進 → 乘柱上 208 高台連站 ×2 拿 +1 HP → 精英房前吞 spora 備 + 緩速 → 擊敗狂風飄鳥拿 boomy → spora+puffy 毒爆雲清尾段 → 門。 + 保底線:全程地面層,吸 jelly/floaty/spora 點射,氣流柱可完全不碰(§26 保證律)。 + - L6 最佳線:破磚補彈 → 吞 boomy+zappy 電鋸迴旋清簇 → 第一房擊破拿 glowy → 移動平台 + 帶推進 → 第二房擊破拿 drilly → drilly+glowy 凝光星凍場安全輸出 → 吞序彩蛋金星彈 + 留給 chompy → 門。保底線:逐隻吸射、雙精英 60s 逾時門自動開,可全略過。 + - L7 最佳線:開場 5s 內命中拿彩蛋 → 補給小怪憋滿匣星暴(12 傷)→ P1/P2 於 dive 回升 + 窗跳打 → P3 貼地躲 sweep、拍翅穿彈幕縫。保底線:純標準星點射+跳閃 bomb 落點, + 飢荒立即補生保證彈藥(§26)。 +- anti-softlock 不變式(全部 MUST,測試守門): + - 氣流柱不可卡頂/卡牆:柱頂 ≥100(levels.test)+blocked.up 斷供(updraft.test); + 升力止於柱頂自然拋出。 + - Boomy 回程彈不可穿門鎖死:殼刃壽命 2.0s ≥ 2×折返時(enemyFsm.test),逾時必回收。 + - Noctra 退出/重整/離線恢復不鎖門:boss 關無門、擊破制;BOSS_DEFEATED 即寫存檔。 + - 精英沿 v7 §48 全規則(房間箝制+60s 逾時開門);L6 雙房房距 ≥600(levels.test)。 + - 混合星永不為破關必需(§46 硬規則不變);L5/L6 可吸佔比 ≥50%(levels.test)。 +- e2e 通關 bot(v8.spec.ts):舊存檔相容七節點案、L5 氣流升空案、L5 精英線通關案、 + L6 雙精英逐房通關案、Noctra 三階段擊破入結算案、新混合三式案、spora/boomy 行為案。 + +## 60. v9 關卡 7→9 與世界地圖(levels.ts 資料驅動擴充)(v10 已由 §65 取代:十二關與十二節點) + +| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | +| --- | -------- | --------- | ------ | ---- | ------ | ----------------------------------- | ------------- | +| 8 | 磁極洞窟 | bg-cavern | 3400 | 11 | 1400ms | Magno 磁場干擾+drilly 地下突襲組合 | 磁暴磁極獸 ×1 | +| 9 | 鏡影迴廊 | bg-mirror | 3700 | 12 | 1150ms | Mirri 反射+移動平台複合陣 | 雙精英 | + +- 新組合情境:L8 磁場(彈道不可靠)×drilly(地下突襲)→ 近戰/下砸/星化應對; + L9 鏡面反射 × 雙移動平台/雙彈簧 → 反射窗躲位靠垂直機動;magno/mirri 雙新怪同場。 +- L8 開場 hint 浮字(LevelSpec.hint 資料驅動,沿教學浮字機制):首次星化教學 + 「同系星彈集滿 3 發,地面長按吸入鍵 0.6 秒星化變身」;起手區前 500px 無精英 + 無破磚(安全教學帶)。 +- L9 雙精英:銀鏡鏡面蟲(mirri 基底 HP 17 ×1.4,掉孢子味)+暗磁磁極獸(magno 基底 + HP 19 ×1.3,掉迴旋味);房址 1250/2550(房距 1300 ≥ 2×門距)。 +- 世界地圖九節點鋸齒路徑;解鎖鏈沿 §39;save schema v1 不變——v8 舊檔(≤7 關)載入 + L8 自然開放、L9 迷霧鎖定(save.test/e2e 守門)。 +- 背景重用(§55 慣例,不生成新背景):`bg-cavern`→`bg-eclipse` 貼圖(鋼藍 grade+ + 磁塵 ambience)、`bg-mirror`→`bg-arena` 貼圖(銀鏡 grade+鏡光塵 ambience); + 道具條沿用 arena 主題(晶洞/鏡晶質感)。 +- 攻略 PoC: + - L8 最佳線:起手吞 zappy×3 存雷化 → 磁場期近戰/下砸清 magno → 精英房前星化雷化 + 貼身鏈電 → 擊敗磁暴磁極獸拿 drilly → 破磚補彈 → 門。 + 保底線:全程等 field 週期空檔(idle/windup 5.1s 窗)純標準星點射,磁場可完全 + 不進域(§26 保證律,可吸佔比 0.74)。 + - L9 最佳線:吞 mirri/boomy 湊迴旋味彩蛋滿匣 → 鏡面 cool 窗集火 → 第一房銀鏡蟲 + 擊破拿 spora → 移動平台帶推進 → 第二房暗磁獸擊破拿 boomy → 門。 + 保底線:mirror 1.5s 定身期繞行或等 cool 窗(黯淡明確可打),雙精英 60s 逾時門 + 自動開,可全略過。 + - EX 果凍王最佳線:殼化反彈 P1/P2 彈幕回傷 → P3 頭頂下砸短暈接星暴;EX Noctra + 最佳線:雷化斷召+eclipse 走缺口通道、dive 窗下砸長暈輸出。 +- anti-softlock 不變式(測試守門):mirri 反射彈壽命 1.4s 必回收;magno 磁場僅影響 + 星彈(近戰路徑恆存);L8/L9 可吸佔比 ≥50%(levels.test);雙精英房距 ≥600; + EX 為選配挑戰(不阻主線、無新解鎖依賴)。 + +## 65. v10 關卡 9→12 與世界地圖(levels.ts 資料驅動擴充)(v11 已由 §76 取代:十六關與十六節點) + +| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | +| --- | -------- | ----------- | ------------ | ---- | ------ | ------------------------------------------ | ------------- | +| 10 | 幽光晶湖 | bg-lumen | 3400 | 12 | 1150ms | 星門折躍首發(§66)×鏡蟲潛行混編 | 鏡光燈長老 ×1 | +| 11 | 磁晶險徑 | bg-magnetic | 3700 | 13 | 1100ms | 磁力域×折躍複合(卡點一,checkpoint §67) | 雙精英 | +| 12 | 稜晶王殿 | bg-prism | 854+前室400 | — | 3000ms | 第三魔王稜晶雙子(§68)+魔王關體系(§69) | — | + +- 世界地圖十二節點:佈局由關卡數推導(三階鋸齒、節點半徑 24、魔王節點恆最高階——EX + 徽鈕上方淨空恆成立);雙位數關號縮字級 20px。分區分頁延期(最遲 v12,主計畫 §2.2)。 +- save schema v1 不變:`LEVEL_IDS` 擴至 12;v9 舊檔(≤9 關)載入 L10 自然開放、L11/L12 + 迷霧鎖定(save.test/e2e 守門)。 +- 背景重用(§55 慣例,零新背景):`bg-lumen`→`bg-arena`(幽青 grade+冰青湖光塵)、 + `bg-magnetic`→`bg-eclipse`(磁紫 grade+磁紫晶塵)、`bg-prism`→`bg-arena`(稜晶薰衣草 + grade+虹彩稜塵);道具條沿用 arena 主題。 +- 攻略 PoC: + - L10 最佳線:吞 mirri+glowy 湊凝光系推進 → 星門捷徑跳過中段密集帶 → 精英拿 boomy + 味湊電鋸迴旋。保底線:全程地面吸射,星門可完全不用(折躍僅為捷徑與秘密,§26 保證律)。 + - L11 最佳線:吞 boomy+zappy 電鋸迴旋清簇 → 折躍跳過首精英房帶 → 雙精英拿 glowy/boomy + 補配方。保底線:貼地逐隻吸射,雙精英 60s 逾時可全略過;死亡自中點 checkpoint 重生。 + - L12 最佳線:前室拿星力果+滿匣 → P1 光束間隙輸出 → P2 集火單具入掙扎窗 → 窗內補殺 + 雙子連破(跳過 P3)。保底線:標準星逐具磨死,夾擊跳越、晶雨看預警走位。 + +## 66. v10 星門折躍(logic/warp.ts,pure TS 可測) + +- 新 stage element:`{ kind: 'warp', x, y, pairId }`——同 pairId 成對傳送(三區新機制 2/2)。 +- 傳送規則:觸發半徑 40px、進門保留速度向量(body.reset 後回寫)、出門 500ms 全域冷卻 + 防彈跳循環;相機硬切+白閃 0.2s+星塵演出。 +- 跳入制(anti-softlock 幾何設計):門心固定高於就地站立中心 80px——站立/走動不觸發、 + 單跳即入、出門落地即脫離觸發半徑(冷卻期內必然脫離,杜絕回彈循環)。 +- 資料不變式(levels.test 守門):warp 必成對;僅 L10/L11 配置;門心高度帶(站立中心 + -56~-138px);不落於精英房界(±300+觸發半徑)內側(主計畫交叉不變式 15);主線不依賴 + warp——地面路徑恆達星星門(§26 保證律不變)。 +- 呈現(systems/stage.ts):星環按 pairId 輪色(脈動外環+淡填內圈+自旋星芯+上飄星塵, + maxAlive 4/門);傳送後重置彈簧掃掠與星星門掃掠基準(onWarp hook),防前後幀大位移 + 誤觸背擋。 + +## 67. v10 卡點關中點重生(LevelSpec.checkpointX,§4 主計畫卡點緩解) + +- L11 首發:`checkpointX: 1850`(世界中點、落於雙精英房界外)。 +- 語義:本命最遠推進 x 越過 checkpoint 後死亡——就地自 checkpoint 重生(場景不重啟); + killCount/彩蛋進度/計時全數保留(bestTime 語義不變);血量回滿基礎 5、慈悲補血每命 + 狀態重置;死亡 i-frame(1.5s)覆蓋落地瞬間防秒殺。 +- 未越過 checkpoint 或非卡點關:維持既有整關重試。`forceLose` e2e 鉤子與真實死亡同分岔。 +- 純邏輯 `checkpointRespawnX(level, farthestX)` 供 vitest;資料不變式:僅 L11 配置、 + ≈worldWidth×0.5、遠離精英房界 300px(levels.test 守門)。 +- 主計畫 §4 兩案(checkpoint vs 密度降載)v10 以 checkpoint 定版首發;bot 實測死亡率 + 回填後若翻案再議(其後卡點關 L15/L19 統一採用)。 + +## 69. v10 魔王關特殊體系(前室/短期增益/L12 首發;L4/L7 回補延 v11+) + +- **補給前室**(systems/bossRoom.ts prefab;`LevelSpec.anteroomPx` 資料驅動): + - arena 前 400px 廊道:runtime 世界寬=前室+動態視寬(854–1200);玩家自廊道起點入場。 + - 固定配置:慈悲愛心 ×1(tier-2 回 2 HP,禁止門口全滿血 P-65)+可吸補給怪 ×3(進場 + 即可滿匣)+增益二選一台座(`anteroomBuffs`,取一消一)。 + - 單向門:越過前室右緣即鎖閉(果凍門柱),重試自前室起;相機三段——廊道剛性跟隨 → + 入門停跟隨對齊 arena → 魔王入場運鏡。 + - 補給/慈悲錨點 arena 化:魔王補給與召喚自 arena 左右緣入場;慈悲愛心錨點下界改 + arena 左緣(防落於門後不可達)。 +- **短期增益表**(logic/buffs.ts `BUFF_SPECS`,純邏輯可測): + +| id | 名稱 | 效果 | 時效 | HUD | +| ------ | ------ | --------------------------------------- | ---------- | ----------------- | +| shield | 護盾泡 | 吸收 1 次任意傷害(彈幕/接觸/hazard) | 15s 或破盾 | 單一 icon+倒數環 | +| power | 星力果 | 星彈傷害 ×1.5(含混合星與變身射擊) | 10s | 同上(後拾覆蓋) | +| swift | 疾風靴 | 移速 ×1.3、加減速 ×1.4(movement 注入) | 12s | 同上 | + +- 規則(全部 MUST):同時僅存一個、後拾覆蓋;增益永不為破關必需(有界加成非無敵); + 走動關不投放;arena 內僅 P2 高風險位刷 1 顆(`arenaBuff`,10s 未拾淡逝)、EX 刷新減半 + =不投放;護盾格擋走 `damagePlayer` 單一受擊入口。 +- movement 契約更新:`approachVelocity` 增選配 `rateMul`(缺省 1 零回歸);速帽尊重提速 + 後目標值(同時修正 §57 雷化 +15% 被常速帽逐幀鉗回的既有缺陷)。 +- L12 配置:前室二選一=護盾泡/星力果;P2 稜晶柱頂刷疾風靴 ×1(高風險位 P-41)。 + +## 70. v10 魔王關專屬彩蛋與每關驗證 + +- 新觸發器 `twin-finish`(eggs.ts 第五型):時窗真值由 prismixFsm 持有(單一真值), + GameScene 收到 twinFinish 事件餵入觸發器——鎖存、gold-star 獎勵+全屏稜光演出; + `vent-hit-count` 已於 v11 落地(§75)、`survive-collect` 隨 v12(主計畫 §7.3)。 +- 慈悲補血:L12 沿用 §62 魔王房 override(HP≤2、12s 起評、18s 冷卻、上限 2;v19 已由 + §62 取代 60% 擲骰:改 pity 受傷 2 次/低血 15s 保底)——`bossRoom` 判定隨 `level.boss` + 泛化,零新碼。 +- anti-softlock 不變式(測試守門):warp 四不變式(§66);checkpoint 落點房界外(§67); + L12 補生全可吸且恆可吸佔比 ≥0.6;碎晶盾可全數擊破(星彈屏障非無敵殼);前室單向門 + 重試自前室起、arena 無門鎖擊破制(§10.2-10);增益永不必需(§69)。 +- e2e 通關 bot(v10.spec.ts):L10 不用星門全地面通關案(floorbot-no-warp-clear)、星門 + 折躍傳送案、L11 checkpoint 重生案、L12 前室→門鎖→三階段→雙子連破案、舊存檔十二節點 + 相容案、雙節血條案(HUD 直接觀測 `__sp.twinHud` 於 v11 補齊,見 v11.spec)。 + +## 71. v11 糖漿潮汐(logic/tide.ts,pure TS 可測) + +- 四區主機制 2/2(主計畫 §5 L14):關卡級配置 `LevelSpec.tide?: { maxY, periodMs, dutyPct }` + ——非 stage element;底部糖漿帶週期漲落,漲潮時強制走平台層。 +- 水位時間軸(tideWaterY):乾潮(收納世界底 y=600 等效無水)→ 漲坡 0.9s(地面頂→漲頂 + 線性)→ 滿潮持平 → 退坡 0.9s 回地面頂;漲潮前 1s 河面冒泡 telegraph(tidePhase)。 +- 浸水結算(GameScene.advanceTide 單點):接觸傷害 1 走 damagePlayer 單一入口(i-frame/ + 護盾泡自然生效)+強緩速(水平封頂 60px/s)+垂直鎖上推 -240(**永不吸底**, + anti-softlock §10.2-4)。 +- dry-window 不變式(levels.test 守門):主地面每週期露出 ≥40%(dutyPct ≤0.6)、平台層 + 頂恆高於漲頂 24px、僅 L14/L15 配置;等窗推進為合法保底行為(主計畫 §0.1 定義 6)。 +- 交叉不變式(主計畫 §10.2-13/-17,systems/tide 接線):漲潮期 Magno 生成替換為 jelly + (磁場不覆蓋漲潮期可站位)+補生落點上收至水面上方淨空帶(tideSpawnY,48px 淨空)—— + 均走 waves.adjustSpawn hook,缺省直通零回歸。 +- L16 場控沿用(§74):Syrona P2 潮汐入場、P3 大沸騰——同一 createTide 管線由魔王 hooks + 控制(startTide/boilTide),浸水與生成過濾自然生效。 + +## 72. v11 熱泉噴口(updraft 週期參數化,零新 element kind) + +- 四區主機制 1/2(主計畫 §5 L13):既有 `updraft` 增 `periodMs?/dutyPct?` 選配——缺省= + 恆常供力(**L5 氣流柱行為零回歸**,levels.test 斷言 L5 恆缺省);有值=週期噴發。 +- 相位(ventPhase):週期頭 idle(不供力、柱體幾近隱形)→ 末段 0.5s telegraph(蒸汽 + 微亮預警)→ 尾段 duty 比例噴發(erupt 供力,沿 §51 升力管線:加速 1600、升速夾限、 + blocked.up 斷供全數重用)。L13/L15 取 periodMs 2600/3200、dutyPct 0.31(≈0.8-1.0s)。 +- 資料不變式(levels.test 守門):週期噴口僅 L13/L15;periodMs ≥1500、dutyPct ∈(0, 0.6]; + 柱頂上方 160px 拋出弧淨空(防無限拋接)+柱頂 ≥100 沿 §51。 +- 呈現(systems/stage.ts):柱體/粒子隨相位開闔(idle α0.03 → telegraph α0.10 → + erupt α0.20+滿量粒子);`__spStage.vents()` 觀測點回報各柱 [x, 噴發中]。 +- 保底線(floorbot-vent-ground-pass,v11.spec):視噴口為普通地磚全程地面推進, + 升托僅為捷徑非必需。 + +## 75. v11 魔王關專屬彩蛋與每關驗證 + +- 新觸發器 `vent-hit-count`(eggs.ts 第六型):**窯風三連**——乘噴口升空期間命中 + Syrona 累計 3 次 → heal+窯火謝幕演出。命中計數真值由 syrona 呈現層持有(沿 + twin-finish 單一真值模式):命中當下玩家位於任一噴口柱域內即計數,滿 3 發 + onVentEgg 餵入 GameScene 觸發器鎖存。 +- L16 魔王關體系(§69 直接複用):前室 400px+護盾泡/疾風靴二選一+P2 噴口上方刷 + 星力果(`anteroomBuffs: ['shield','swift']`、`arenaBuff: 'power'`);補生 jelly 0.3/ + bubbla 0.4/floaty 0.3(恆可吸 0.6 保飢荒保證律)。 +- anti-softlock 不變式(測試守門):潮汐 dry-window 與永不吸底(§71);週期噴口 + 非噴發期不供力、L5 缺省零回歸(§72);Bubbla 躍出窗恆現(週期驅動非條件觸發)、 + 糖球/糖斑壽命有界(§73);Syrona 每循環必留 ≥1 保底位、僵直窗 ≥2s(§74); + L15 等窗推進合法(floorbot-tide-wait-window)。 +- e2e 通關 bot(v11.spec.ts 六案):舊存檔十六節點相容、L13 噴口週期翻轉+地面保底 + 通關、L14 潮汐浸水永不吸底+等窗通關、L15 checkpoint 重生、L16 Syrona 三階段 + (前室→P2 潮汐入場→P3 大沸騰→擊破寫檔)、L12 雙節 HUD 直接觀測(§70 收尾)。 + +## 76. v11 關卡 12→16 與世界地圖(levels.ts 資料驅動擴充) + +| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | +| --- | -------- | ----------- | ------------ | ---- | ------ | ------------------------------------------------- | --------------- | +| 13 | 焙糖丘陵 | bg-kiln | 3300 | 11 | 1400ms | 熱泉噴口首發(§72)×Bubbla/Splatta 亮相 | 焦糖泡霸 ×1 | +| 14 | 熔糖河谷 | bg-valley | 3600 | 12 | 1250ms | 糖漿潮汐首發(§71) | 糖漿投擲隊長 ×1 | +| 15 | 沸糖窯道 | bg-kilnway | 3800 | 14 | 1100ms | 潮汐×噴口複合 gauntlet(卡點二,checkpoint 1900) | 雙精英 | +| 16 | 熔糖王窯 | bg-kilnhall | 854+前室400 | — | 3000ms | 第四魔王 Syrona(§74)+魔王關體系(§69) | — | + +- 世界地圖十六節點:節點半徑再收斂 24→20(854 寬間距 ≈51px 單頁可容納);三階鋸齒 + 12 項循環下四魔王節點(L4/L7/L12/L16)恰全落最高階,EX 徽鈕淨空恆成立; + 雙位數關號字級 17px。**分區分頁為 v12 硬項**(主計畫 §2.2,20 節點單頁確定放不下)。 +- save schema v1 不變:`LEVEL_IDS` 擴至 16;v10 舊檔(≤12 關)載入 L13 自然開放、 + L14-L16 迷霧鎖定(save.test/e2e 守門)。 +- 美術(§9 主計畫 v11 批 5 張):`bg-kiln-l`(1536×512 無縫,四關共用 grade 區分)、 + `props-kiln` 道具條 4 件、`minion-bubbla`/`minion-splatta`/`boss-syrona`; + 缺件期間烘焙保底不阻開發。 +- 攻略 PoC: + - L13 最佳線:乘噴口越丘陵直取精英拿 zappy 味。保底線:地面吸射推進,噴口僅捷徑。 + - L14 最佳線:讀潮汐節拍退潮衝刺漲潮上台、風形態飛渡長浪段。保底線:主地面退潮窗 + 恆可通行,逐段等潮推進,全程可不碰平台層。 + - L15 最佳線:雷爆星清簇→乘噴口鏈跨大漲潮段→雙精英補味。保底線:**等窗推進**—— + 漲潮期安全帶原地等退潮、退潮窗地面逐段推進;雙精英 60s 略過;死亡自 1900 重生。 + - L16 最佳線:風形態滯空躲潮→噴口升空打皇冠 ×2。保底線:讀潮汐站浮台點射, + 僵直窗磨死。 + +## 78. v12 分區分頁世界地圖(logic/zones.ts+MapScene,主計畫 §2.2 硬項落地) + +- 二十節點單頁確定放不下(v11 十六節點半徑 20 已是單頁極限):改「分區分頁」—— + 每區一頁 ≤5 節點(半徑回復 24 可讀性回升)、頁籤列直達任一已解鎖區(等效快速 + 旅行,零新系統)。 +- 五區資料 SSOT:`ZONES`(果凍平原 L1-L4/天風峽域 L5-L7/幻晶深域 L8-L12/ + 焙糖火山 L13-L16/星核聖域 L17-L20);頁內節點由 `LEVELS` 區間過濾推導—— + 列車過渡期末區未滿編自然收斂,關卡擴充分頁零改動。 +- 區解鎖=區首關解鎖(前區魔王擊破,引用 P-03 分頁即區域錨點);未解鎖區頁籤 + 灰顯無入口。頁標頭顯示該區彩蛋 found/total(P-11 分項透明化)。 +- 預設頁=當前可挑戰關所屬區;揭霧跨區自動開對應頁(reveal 帶入);頁籤切換以 + `scene.restart({ page })` 實作(DOM 鈕由 shutdown 自清,零洩漏);視寬變更重排 + 保留當前分頁。魔王節點固定最高階 y=224(EX 徽鈕淨空恆成立),走動關 300/262 交錯。 +- 存檔相容:schema v1 不變、`LEVEL_IDS` 擴至 20——v11 舊存檔(≤16 關條目)原樣 + 載入,L17 依解鎖鏈自然開放、L18-L20 迷霧鎖定(save.test/e2e 守門)。 + +## 79. v12 流星雨(logic/meteor.ts+systems/meteor.ts,pure TS 可測) + +- 關卡級環境彈幕(`LevelSpec.meteor?: { intervalMs, waveSize }`):波次節拍 → + 落點抽選 → 預警圈 0.8s(滿張即著地)→ 隕星恆速直墜 → 著地餘燼 0.4s 淡出。 +- anti-softlock 不變式(主計畫 §10.2-7):預警 ≥0.7s、同屏隕星 ≤3(效能預算)、 + 開門後門前 ±120px 禁投、玩家縱帶 ±48px 恆排除(滯空無水平逃逸速度與腳下連投 + 取聯集,交叉不變式 14 一併覆蓋)。 +- 交叉不變式 14(低重力×流星):隕星不掛重力、恆速 520px/s 直墜——低重力關落地 + 時刻不延後,生成高度由墜速×預警時長自著地點反推。 +- 落點抽選純函式 `pickMeteorX`:可投範圍挖除排除帶後 rand01 沿剩餘總長線性映射; + 無合法段回 null 棄投(永不強投排除帶)。 +- 隕星可被星彈擊碎(碎裂粒子、星彈吸收);隕星/餘燼命中玩家走 damagePlayer 單一 + 入口(i-frame/護盾泡自然生效)、隕星命中即碎。程序化貼圖零新美術。 +- Voidra P2 轟炸沿單一 meteor 管線:`setActive/setSpec` 開關與調參(§82)。 + +## 81. v12 低重力(LevelSpec.gravityScale,零新 element kind) + +- 關卡級重力係數(缺省 1.0=既有全關卡零回歸):GameScene create 以 + `GRAVITY_Y × gravityScale` 顯式重設世界重力(單點注入,movement/player 純函式 + 簽名不變;每次 create 必重設防前關/Voidra P3 注入殘留)。 +- L17/L18 取 0.55(浮月感)、L19 取 0.85(輕低重力);跳躍初速/拍翅次數/升力不變。 +- 值域 [0.5, 1.0] levels.test 守門(主計畫 §10.2-6);gravityScale ≤0.7 視為 + 208 高台的升降服務(低重力大跳+拍翅可達,levels.test 高台服務判定第三路)。 +- Voidra P3 runtime 注入 0.55(§82):hook 直寫世界重力、擊破/銷毀/段重試復原。 + +## 83. v12 魔王關專屬彩蛋與每關驗證 + +- **星核共鳴**(第七型觸發器 `survive-collect`):P2 生存段星屑 5 枚全收 → + full-magazine+星光謝幕演出(全屏金閃+星爆)。計數單一真值由 voidraFsm + `collectShard` 持有(沿 twin-finish/vent-hit-count 模式),滿 5 僅回報一次; + 段重試歸零重收。星屑收集判定沿 pickups 幾何慣例(AABB+水平掃掠,緩降至地面 + 帶後定點浮動可補收)。 +- 每關驗證(e2e v12.spec):v11 舊存檔載入五區分頁(L17 開放/L18·L20 迷霧)、 + L17 低重力全程地面通關(floorbot-lowgrav-landing 契約)、L18 預警圈→隕星→餘燼 + 可觀測+全程地面通關、L19 四機制終試全程地面通關(不用星門/噴口)、L20 三段 + 全流程(P2 免傷帶/過熱窗輸出/段起點重試/擊破→謝幕→Result→寫檔)。 + +## 84. v12 關卡 16→20 與全線收尾(levels.ts 資料驅動擴充) + +| # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | +| --- | -------- | -------------- | ------------ | ---- | ------ | ------------------------------------------------------------------------------------------ | ---------------- | +| 17 | 星屑浮橋 | bg-astral | 3400 | 11 | 1350ms | 低重力 0.55 首發(§81)×Twinkla 亮相 | 星屑幽長 ×1 | +| 18 | 流星原野 | bg-meteorfield | 3700 | 13 | 1200ms | 流星雨首發(§79,4.5s×2)×低重力 0.55 | 彗核疾魚 ×1 | +| 19 | 星核前庭 | bg-starcourt | 4000 | 15 | 1000ms | 全機制終試(折躍+週期噴口+低重力 0.85+流星 5.2s×2);唯一六同屏;卡點三 checkpoint 2000 | 雙生鏡衛 ×2 同房 | +| 20 | 蝕星之心 | bg-voidcore | 854+前室400 | — | 2800ms | 最終魔王 Voidra(§82)+魔王關體系(§69) | — | + +- 曲線收束(主計畫 §4 CV-4):L17 緩衝 → L18 → L19 卡點三 → L20 全遊戲峰值; + 魔王 DPS 檢查點 Voidra 110 > Syrona 90。 +- L19 同房雙精英「雙生鏡衛」=20 關唯一變式:mirri ×2 同房近距(60px)雙門疊放 + ——兩具皆破才開門、60s 逾時保險各自有效(§48 全規則沿用);掉 glowy+zappy + 補凝光/追電配方。levels.test 豁免帶限定 L19。 +- 美術(主計畫 §9 v12 批 4 張,codex imagegen):`minion-twinkla`/`minion-cometa` + /`boss-voidra`(裁切球體佔比+q78 控預算)/`bg-astral-l`(1536×512 無縫, + 四關共用 grade 遞紫遞深:astral 淡紫 → meteorfield → starcourt → voidcore 深紫)。 +- **星光復甦謝幕**(CreditsScene):最終魔王關勝利(關卡鏈末端+魔王關資料驅動 + 判定,禁硬編關號)先播謝幕再進結算——星核金光脈動+星光上升粒子+製作名單 + 六段浮現(IP 安全全原創文案);任意點擊/ENTER 跳過、收尾冪等;播畢接 Result + 延續戰績資料。 +- 攻略 PoC: + - L17 最佳線:低重力大跳直上最高星橋速通+彩蛋。保底線:地面層恆連通,twinkla + 只在實體窗吸射。 + - L18 最佳線:星彈擊碎隕星保持節奏、追電星自動鎖 cometa。保底線:預警圈 0.8s + 純走位可躲(玩家縱帶恆排除),逐隻吸射推進。 + - L19 最佳線:凝光凍場過噴口鏈 → 折躍跳過流星走廊 → 雷形態鏈電雙殺鏡衛。 + 保底線:四機制段全有地面慢速路(各沿原區保底規則),死亡自 checkpoint 2000。 + - L20 最佳線:P2 風形態機動全收星屑 → P3 雷形態裂核大窗爆發。保底線:P2 零擊殺 + 純走位、P1/P3 讀 telegraph 打僵直/裂核窗,補給循環+段起點重試保障磨死。 + +## 97. v16 區/關命名層級標示(F-01 裁決) + +- 三席批評(Composer 席):地圖同屏「果凍平原」(區頁籤/標頭)與「果凍草原」 + (L1 節點)近義並列,讀感如命名漂移。 +- PM 裁決維持層級差:區=地域(果凍平原/天風峽域/…)、關=景點(果凍草原/ + 翔風峽谷/…),全五區皆同構,統一反而使 L1 與區 1 撞名。 +- 消除認知分裂:地圖標頭前綴「第 N 區」(`第 1 區 果凍平原・彩蛋 x/y`)、 + 區頁籤 aria「前往第 N 區 ○○」、節點 aria「進入第 N 關 ○○」——視覺與讀屏 + 同義:頁籤/標頭=區域、節點=關卡。 +- 資料面守門(zones.test.ts):區名不得與任何在編關名撞名。 + +## 105. v16 前期節奏保守調參(D5+F-05,補充 §15 教學關與 §48 精英房) + +- 三席批評:L1 教學配額與死亡懲罰偏挫折(Grok -3)、L2 精英軟鎖門「卡住感」 + (Grok/Composer)——門柱無任何文字說明,60s 保險存在但玩家不知情。 +- 保守裁決(禁大改平衡): + - 教學關死亡配額結轉:僅 tutorial 關(L1)死亡重試保留一半擊殺數 + (floor(kills/2)、夾限至配額-1 不可能帶開門態重生);其餘關卡維持全重置, + 卡點關 checkpoint 路徑(§67)本就不重啟不受影響。實作: + `carryKillsOnDeath`(logic/levels.ts 純函式)+ waves runner initialKills + 種子+重生即補發 LEVEL_QUOTA 現值(既有事件,無契約變更)。 + - 精英門提示:門柱旁世界座標浮字「擊敗精英開門/60 秒後自動開啟」—— + 明示破關條件與保險,等待也是合法出路;開門隨門柱淡出。零平衡影響。 + - 不做項:L1 配額量/生成節奏調整(教學關幾乎不死的原設計仍成立,動供給 + 曲線風險大於收益);L2 精英數值調整(60s 保險+提示已消解卡住感)。 +- 驗證:levels 單測(結轉夾限/非教學歸零/種子推進);v16 e2e 真實戰鬥管線 + 擊殺 4 隻→死亡→重生 2/6;v7 精英房回歸全綠。 diff --git a/apps/starpuff/docs/design/05-save-settings.md b/apps/starpuff/docs/design/05-save-settings.md new file mode 100644 index 000000000..390a91424 --- /dev/null +++ b/apps/starpuff/docs/design/05-save-settings.md @@ -0,0 +1,136 @@ +# 星噗噗 — 存檔、使用者設定與成就 + +> **職責範圍**:所有跨場次持久化的東西。存檔 schema 與容錯/備援、重置進度語意、成就系統與補發、使用者偏好單鍵 SSOT(`sp-settings`)與統一設定頁、PWA 更新套用時機閘。 +> +> **不在本檔**:偏好所控制的行為本身——虛擬鍵布局規格見 `01-controls-input.md` §34/§89/§95;震屏與演出見 `07-art-audio-fx.md`;PWA 安裝指引見 `06-ui-shell-pwa.md` §90。 +> +> **現行儲存鍵**:`sp-save`(存檔,schema v2)/`sp-save-backup`(備援)/`sp-settings`(全部偏好,schema v1)。`sp-muted`、`sp-rotation`、`sp-key-layout` 已於 §118.1 收斂,僅作一次性 migration 來源。 +> +> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 + +## 38. 存檔系統(core/save.ts 為 SSOT,pure TS 可測) + +- localStorage `sp-save` schema v1:`{ schemaVersion, highestClearedLevel, levels: { [id]: { cleared, bestTimeMs, eggsFound: string[] } }, lastPlayedAt }`。(v15 已由 §94.2 升 v2 增 `achievements`;v19 已由 §118.3 補訂 checksum 欄與 `sp-save-backup` 備援。) +- 寫入時機:通關(星星門吸入當下即寫,演出中斷不掉進度)、魔王擊破、彩蛋觸發(`trigger` 型別字串為關內唯一 id)。 +- 容錯(沿用 §34 鍵位布局 parse/fallback 模式):schema 版本不符、形狀損毀、隱私模式拋錯——一律回退預設值;`highestClearedLevel` 由關卡條目重新推導,不信任持久化值。 +- `bestTimeMs`=該關單次成功嘗試的最短用時(死亡重試重計);`eggsFound` 去重持久化,跨局累計。 +- 重置進度:世界地圖左下「重置進度」兩步確認(武裝態 3s 未確認自動退回),僅清存檔(偏好不動)。全新存檔不顯示入口。(v19 已由 §118.3 補訂清除範圍:同時清 `sp-save` 與備援 `sp-save-backup`;偏好鍵自 `sp-key-layout`/`sp-muted` 收斂為 `sp-settings`。) +- 偏離備註:任務原文「設定頁加重置進度」——v6 當時本遊戲無設定頁(按鈕配置為鍵位編輯器,語義不符),重置入口落於世界地圖(進度顯示與進度管理同場景,KISS)。(v19 已由 §118.2 取代前提:Title 已有「設定」入口,但重置進度**維持在世界地圖**——進度顯示與進度管理同場景的 KISS 裁決不變。) + +## 94. v15 成就系統(logic/achievements.ts,純呈現層聚合) + +### 94.1 設計原則 + +- 成就 SSOT=`logic/achievements.ts` 單一資料表(id/名稱/描述/分類/隱藏與否/ + 判定函式),共 21 條;全部由既有 save 資料派生判定(`cleared`/`bestTimeMs`/ + `eggsFound`/`exCleared`),**禁止侵入式遊戲邏輯鉤子**——evaluator 讀 save 即得 + 已解鎖集合,遊戲熱路徑零新增寫入點。 +- 魔王條目(五王首勝+五王 EX)由 `LEVELS` 派生(沿 §86 `BOSS_LEVEL_IDS` 慣例, + 禁第二份硬編清單);命名表以 `Record` 鍵定,加王時型別強制補名。 + 隱藏成就對應關卡由彩蛋觸發器反查 LEVELS,彩蛋總數同樣派生。 +- 分類五種:進度(首關/全 20 關)、魔王(各王首勝/EX 各王/星核制霸——與 §86 + `exConquestDone` 同源判定)、收集(彩蛋 1/10/全收)、技巧(任一魔王關 + 120s/60s 內通關,門檻依 v13 bot trace 證據校準)、隱藏(三個魔王專屬彩蛋: + 雙子連破/窯風三連/星核共鳴,未解鎖顯示「???」)。 +- 玩法類(九系星彈全用過/星化三形態)裁決不做:save 無 flavor/form 使用紀錄, + 為此擴 save 需熱路徑攔截非極低成本,違反本章零侵入原則。 + +### 94.2 存檔 schema v2 與補發(versioned migration) + +- `SaveData.achievements: string[]`=已頒發成就 id——**toast 去重基準**,頒發紀錄 + 不可逆(資料回退不移除);解鎖「顯示」恆由 save 即時派生,stored 只管去重。 +- `SAVE_SCHEMA_VERSION` 升 2:`parseSave` 接受 v1(v9–v14 世代)與 v2——v1 缺 + achievements 補空集後照常收斂條目,**禁 discard**;寫出恆為 v2。 +- 補發單點=main.ts 開機:`awardAchievements(loadSave())` 依既有資料靜默補發 + 歷史成就(無 toast 轟炸),有增量才落盤(全新玩家不預建存檔);版本更新新增 + 成就同走此路自動補發。 + +### 94.3 呈現三層(解鎖不漏看) + +- 遊戲內 toast:GameScene `persistAndAward` 單點(彩蛋/通關/EX 三個存檔寫入點 + 寫後評估增量)→ **同批多解鎖合併單張橫幅**(頓號串接,勝利轉場 2.8s 窗口內必可 + 播完整批)、跨批序列佇列不重疊(約 2.1s/張);金色橫幅帶深色底襯(勝利白閃下 + 仍可讀),禁全屏遮罩;e2e 觀測點 `__sp.achievementToast()`(canvas 文字不可由 + DOM 查詢)。轉場即隨場景銷毀,由下兩層兜底。 +- 結算名單:`GameResultData.unlocked`(additive optional)帶本局勝利瞬間新頒發 + id 進 Result 金底列示(Credits 轉接保留)——魔王擊破多重解鎖不因 WIN_DELAY + 轉場漏看;敗北局內解鎖的彩蛋成就同樣如實列出。 +- 成就頁:CodexScene 第三分頁(`CodexTab` 加 'achievements',分頁鈕等距展開); + 6 欄徽章網格(fx-star tint+圓底程序繪製,零新圖)、已解鎖亮金微轉動/未解鎖 + 灰、隱藏未解鎖名稱「???」描述「隱藏成就」、右上「解鎖 n/21」計數; + 網格與計數依 §93 净 inset 收縮(854/1200/直持 390×844 三視口驗證)。 + +### 94.4 驗證 + +- 單測 achievements.test.ts:資料表不變式(id 唯一/21 條/boss 覆蓋派生守門)、 + 全類別邊界(19/20、4/5 EX、彩蛋 9/10、速通 120000/120001 與 0 不計)、 + awardAchievements 冪等與增量、v9–v14 各世代舊存檔載入補發精確集合。 +- 實測 scripts/v15-verify.mjs 五幕:v1 滿進度開機補發 21 條+schema 升 v2、 + 真實擊破管線多重解鎖(toast+Result 名單)、854/1200/直持成就頁、 + console error 全程 0。 + +## 118. 使用者設定 SSOT、存檔備援與 PWA 更新閘(#819;T7-A 列車) + +現行偏好與持久化 SSOT。取代散落 localStorage 鍵敘述:§9 靜音鍵、§34/§89/§95.2 鍵位 +布局鍵、§87.1 旋轉方向鍵,以及 §38 的「本遊戲無設定頁」偏離備註與重置範圍描述。 + +### 118.1 UserSettings 單鍵 SSOT(core/settings.ts) + +- 儲存鍵 `sp-settings`(`SETTINGS_SCHEMA_VERSION = 1`)為**唯一偏好真相**,欄位: + `audioMuted`/`hapticsEnabled`/`wakeLockEnabled`/`reducedMotion`/`screenShake` + (`off|low|full`)/`shellRotation`(`cw|ccw|null`,null=從未選擇供 §87.2 一次性 + 告知判定)/`keyLayout`(§89 v2 子樹,null=預設態不落盤,§95.2 語意不變)。 +- `reducedMotion` 預設尊重系統 `prefers-reduced-motion`(WCAG 2.3.3);非瀏覽器環境 false。 +- **一次性 migration**:首次讀取時吸收 legacy 散鍵 `sp-muted`/`sp-rotation`/ + `sp-key-layout` 為初始值(值損毀逐項回預設),**落盤成功即刪除三個 legacy 鍵** + (單真相;PWA 部署單向前進,回滾非支援路徑,殘留舊值會在主鍵遺失時被吸回過期偏好)。 + 例外語意:`persist` 失敗(隱私模式/配額滿)**保留 legacy 作下次開機來源**。 +- 主鍵損毀(JSON 壞損/版本不符/形狀損毀):回退 legacy 吸收並回寫修復,不以預設 + 靜默覆蓋;置 `wasSettingsRecoveredFromCorruption` 旗標,main.ts 於 Title 安靜時刻 + 以殼卡(§92)明確告知。 +- 一次性記憶鍵(`sp-rotation-notice`/`sp-install-dismissed`/`sp-desktop-keys`/ + `sp-orientation-hint` 等)非偏好,**不入本 schema**。 +- 已知限制:偏好經記憶體快取、無 storage event 跨分頁同步——多分頁併發寫入為 + last-writer-wins(單分頁互動情境,接受此限制)。 + +### 118.2 統一設定頁(systems/settingsPage.ts,取代 §38「無設定頁」備註) + +- Title 次選單第四鈕「設定」(`data-menu="settings"`)開啟純 DOM overlay(沿 + keyConfig/shellCards 慣例,不進 Phaser Scene);容器沿用 `.install-overlay` + class,`isShellBusy` 天然視為忙碌(與 PWA 套用/殼卡排隊互斥)。 +- 內容:音效/震動回饋/遊戲中螢幕常亮/減少動態效果四開關+震屏強度三段 + (關/弱/全)+「按鈕配置(鍵位與持向)」轉入口(§34 keyConfig 專頁由此轉入, + 不再是 Title 獨立鈕)+「完成」。ESC 關閉。 +- **即改即存**,無草稿語意(草稿/取消回滾僅存在於按鈕配置頁,§87.2/§95.2 不變); + 音效切換同步 mute 系統,震動開啟時輕震一次即時回饋。 +- 震屏/閃光偏好落地(`systems/cameraFxGate.ts`):一次性包裝 main camera 的 + `shake`/`flash`,全部 boss/fx 呼叫端零改動即受管——`reducedMotion` 或 + `screenShake:'off'` 時震屏強度 ×0(直接不震)、`low` ×0.5、`full` ×1; + `reducedMotion` 另將 flash 時長 ×0.3(未帶參呼叫以 Phaser 預設 250ms 為基準)。 + 偏好每次呼叫重讀,設定頁改動即時生效。 + +### 118.3 存檔備援與 checksum(core/save.ts,補訂 §38) + +- schema 現值 v2(§94.2 已升版;§38 的 v1 敘述為 v6 歷史值)。寫入時附 + `checksum` 欄;解析時 checksum 不符/JSON 壞損/未知版本一律判**損毀**。 + legacy 存檔(無 checksum 欄)視為合法,不誤殺舊玩家。 +- 備援鍵 `sp-save-backup`:每次寫入前把**上一份合法主檔**輪替至備援(損毀資料不 + 污染備援);主檔損毀時自備援恢復並回寫自癒,備援亦不可用才回退預設——兩路徑 + 皆 `console.warn` 留痕,不再默默歸零。備援輪替失敗(配額不足/隱私模式)不得 + 阻斷主檔寫入。 +- **重置進度範圍修正**(取代 §38 的「僅清 `sp-save`」):`resetSave` 同時清除 + `sp-save` 與 `sp-save-backup`(否則重置後會自備援恢復出舊進度);偏好 + (`sp-settings`:靜音/鍵位/持向等)不動。入口與兩步確認語意沿 §38 不變。 + +### 118.4 PWA 更新套用時機閘(pwaUpdateGate.ts) + +- 新版 SW ready 只標記 pending,**遊戲進行中絕不 reload**;僅在殼層安靜 + (非 GameScene/非配置中/無殼卡=Title/Map/Result 選單面,忙碌訊號沿 + `shellCards.isShellBusy` 單一 SSOT)才自動套用。 +- 套用寬限 1500ms:條件成立後再等寬限期並重驗,期間殼層轉忙(再入遊戲)即放棄 + 本次套用交還重試管線——避免場景切換瞬間 reload 吃掉使用者正要按下的點擊 + (Result「下一關」CTA 競態,§100)。 +- 邊界事件漏接保險:pending 期間每 5s 低頻重試;`#controls` class 變化 + (MutationObserver)=遊戲進出場邊界,離開 GameScene 當下即嘗試套用。 +- 取代 §35 的已知邊界敘述「autoUpdate 完成後的 reload 會蓋過暫停選單」——該競態 + 已由本閘根治(暫停選單期間 `#controls.is-active` 仍為真=殼層忙碌,不會套用)。 diff --git a/apps/starpuff/docs/design/06-ui-shell-pwa.md b/apps/starpuff/docs/design/06-ui-shell-pwa.md new file mode 100644 index 000000000..4416dc2be --- /dev/null +++ b/apps/starpuff/docs/design/06-ui-shell-pwa.md @@ -0,0 +1,163 @@ +# 星噗噗 — 選單、場景 UI、殼層與 PWA + +> **職責範圍**:canvas 上與 DOM 殼層上看得到、點得到的介面。主選單與圖鑑/技能/成就分頁、暫停系統、HUD 命中層、有界網格與 DOM 鈕命中保底、結算動線、殼層卡片基建、safe-area 量測、PWA 安裝指引、觸覺與螢幕常亮。 +> +> **不在本檔**:虛擬鍵與按鈕配置頁(見 `01-controls-input.md`);偏好持久化與更新套用閘(見 `05-save-settings.md` §118)。 +> +> **命中紀律**:選單與 HUD 一律以 DOM 鈕承接命中(旋轉殼下 hit-test 天然正確),canvas 圖示僅保留視覺;命中短邊 48px 保底(§98)。全遊戲禁 emoji 與文字鍵帽。 +> +> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 + +## 33. v5 iOS PWA UX 調研回寫(2026-07-15 定稿) + +調研結論與對應實作(出處:MDN `BaseAudioContext.state`、MDN CSS env()、Polypane safe-area 指南、iOS PWA 安全區實測筆記 gist/fozzedout、Steven Hoober thumb-zone 研究、Smashing Magazine 拇指觸控統計): + +| # | 結論 | 實作 | +| --- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| 1 | `viewport-fit=cover` 缺失時 `env(safe-area-inset-*)` 全為 0,Safari 以黑邊 letterbox | 既有 meta 已含 cover(複查通過,未重工) | +| 2 | standalone 邊到邊需 `apple-mobile-web-app-status-bar-style: black-translucent` | v5 補上該 meta | +| 3 | 橫持瀏海機頂緣存在 phantom 觸控死區(inset 回報 0 仍吃事件),建議頂緣 ≥20px 緩衝 | `#keys-layer` top 取 `max(20px, env(top))`;joy-zone 既有 20px 緩衝維持 | +| 4 | `env()` 值冷啟動/轉向可能為 0 或 stale,須設 `max(Npx, env(...))` 地板 | keys-layer 四向皆 `max()` 地板(20/12px) | +| 5 | iOS standalone 冷啟動 `100dvh` 不可靠 | 維持 v4 `100vh` 決策(複查,未重工) | +| 6 | iOS 切 app/背景後 AudioContext 進非標準 `interrupted` 態,`resume()` 須於手勢堆疊內呼叫 | sfx.ts `resumeAudio()`(`state !== 'running'` 即 resume)+全域 pointerdown 復聲保險+暫停選單「繼續」手勢內恢復 | +| 7 | 觸控目標 ≥44pt(Apple HIG);拇指自然熱區在底部/下側緣,食指可達區在裝置上緣(雙手橫持) | 全按鍵 ≥44px(A 76 / B 72 / 暫停與靜音 hit 48 / 選單鈕 ≥52);布局見 §34 | +| 8 | 長按 loupe/選字/callout/雙擊縮放攔截 | v3/v4 已滅(touch-callout/user-select/touch-action/gesturestart 全鏈,複查通過,未重工) | +| 9 | `position: fixed` 根元素於 iOS 26 鍵盤場景會裁切 app shell | 本遊戲無文字輸入,維持 fixed 殼;記錄為已知邊界 | + +## 35. v5 暫停系統與離頁自動暫停 + +- HUD 暫停鍵:頂列右上(靜音鈕左側 48px,top-right 硬熱區遠離戰鬥區),雙豎條圖形紋理、48px 觸控目標;配額顯示左移讓位。桌機備援:ESC / P。 +- 暫停選單(`systems/pause.ts`,DOM 覆層——旋轉殼下 hit-test 天然正確、覆蓋虛擬鍵防誤觸):繼續/重新開始/回主選單。 +- 全停語義:`scene.pause(Game)`(物理/計時/tween/輸入輪詢全停)+ `AudioContext.suspend()`(BGM 與 SFX 全停)。 +- 重新開始=重置當前關卡全狀態(血量/彈藥/擊殺數/計時/實體經 scene.restart 重生),保留已完成關卡累計用時與本輪死亡數。 +- 離頁自動暫停:`visibilitychange`(hidden)與 `pagehide`(同走 hidden 檢查防雙觸發)即開暫停選單;回前景停在選單、玩家點「繼續」才接續(取代 §26 的自動恢復,杜絕回前景瞬間被偷襲)。音訊恢復一律走手勢堆疊內 `resume()`(§33 條目 6),刻意暫停期間全域復聲保險不生效。 +- 與 PWA 週期更新 hooks(main.ts `import './pwa'`)共存:兩者互不依賴,同檔並列。已知邊界:回前景恰逢新版部署時,autoUpdate 完成後的 reload 會重新載入頁面蓋過暫停選單,屬可接受權衡,不特別攔截。(v19 已由 §118.4 取代此已知邊界:更新套用改經殼層安靜閘,遊戲進行中與暫停選單期間絕不 reload。) + +## 36. v5 開場主選單與圖鑑/技能介紹 + +- Title 開場動畫:主標縮放彈出(Back.easeOut)、副標延遲淡入、主角自天而降 Bounce 落定+光暈淡入;維持既有美術風格與 zzfx 音效(選單按壓 pop)。 +- 主選單:開始遊戲(主鈕)+次選單列 圖鑑/技能介紹/按鈕配置(DOM 鈕承接命中,data-menu 標識)。(v6 §39 增「世界地圖」;v19 已由 §118.2 取代次選單構成:世界地圖/圖鑑/技能介紹/設定四鈕,按鈕配置移入設定頁轉入口;桌機另增常駐「操作說明」,見 §87.4。) +- 圖鑑/技能介紹(`CodexScene` 單場景雙分頁,資料 SSOT `core/codex.ts`,立繪一律取既有 sprite 資產、禁止新美術): + - 圖鑑分頁:全 8 角色(jelly/floaty/spiky/puffy/chompy/shelly/zappy/boss)4×2 網格——立繪+名稱+行為一句話+可吸/不可吸圓點標記。(v7 擴 5×2 十格;v8 擴 7×2 十四格;v9 已由 §59 取代:8×2 十六格。) + - 技能分頁:吸入/星彈三系(含來源怪物對應)(v6 已由 §40 擴充為五系+殼盾/雷鏈條目;v7 §44/§46 移除空中疾衝、增混合星彈與七系敘述)/強化星/星暴/下衝擊/漂浮,雙欄列表(名稱+操作+效果)。 + - 分頁切換以 scene.restart 重建(選單輕量無局內狀態);ESC 或返回鈕回 Title。 + +## 37. v5 全元素位置稽核 + +- 稽核腳本:`scripts/capture-audit.mjs`——Title/Game/Boss/Result(+v5 新頁)於 390×844(直握旋轉殼)與 926×428(寬幅橫持)截圖至 `screenshots/starpuff-v5-audit/{before,after}/`。 +- 檢查項:HUD(血條/彈藥/擊殺進度/計時/boss 條)、虛擬鍵、彩蛋提示、教學文字——重疊/出界/safe-area 裁切/離熱區過遠。 +- v5 修正:暫停鍵擠入頂列後配額右錨左移(width-112/126)避免熱區重疊;B 鍵離開 A 鍵斜上緊鄰位,垂直間距 ≥80px。 +- Boss 條頂中置於兩檔寬皆不與左上心心、右上配額/暫停/靜音重疊(854 與 1200 邏輯寬實測)。 +- v6 增列:版本號頁腳(§42)置於 Title 底緣中央(height-6、12px 小字),不與次選單列(height×0.85)重疊。 + +## 90. v14 PWA 安裝偵測與分平台指引 + +- 偵測矩陣(installGuide.ts,移植 RateWise 模式):platform + (ios/android/desktop/unknown,含 iPadOS 桌面模式 maxTouchPoints 辨識)、 + in-app browser(Threads/Barcelona、Messenger 先於 Facebook、Instagram、 + LINE、TikTok/musical_ly/trill、X)、已安裝雙訊號 + (display-mode standalone+navigator.standalone)。 +- 指引卡(§92 殼層卡片):iOS 分享→加入主畫面步驟;Android + beforeinstallprompt 一鍵安裝+選單步驟 fallback;in-app 引導外部瀏覽器開啟。 +- 出現邏輯:已安裝/已忽略(localStorage `sp-install-dismissed`,不進 save + schema)/桌面不打擾;首次到站延遲 2.5s 且僅 Title 安靜時刻顯示; + appinstalled 自動收卡並記憶。 + +## 91. v14 觸覺回饋與螢幕常亮(調研加碼,ROI 閘通過二項) + +- 觸覺(haptics.ts):查表跟隨 playSfx 觸發點——僅重擊/里程碑 + (hurt/slam-down/boss-slam/boss-roar/starstorm/win/lose)配短震(單段 + ≤100ms、總長 ≤200ms 守門單測);高頻一般音效不震防疲勞;靜音早退即同步 + 不震;iOS 無 Vibration API 靜默降級。 +- 螢幕常亮(wakeLock.ts):Screen Wake Lock 生命週期跟隨 `#controls.is-active` + (遊戲進行中取得、離場釋放、回前景重取);不支援或被拒(省電模式)靜默降級。 +- 落選(backlog):安裝後首啟引導(感知低)、豎屏提示動畫(與免轉向定位矛盾)、 + fullscreen API(iOS 不支援且與 standalone 重疊)。 + +## 92. v14 殼層卡片基建(shellCards.ts) + +- 安裝指引與方向告知共用:`whenShellIdle`(1s 輪詢)僅在 Title + (data-menu="start" 存在)且殼層安靜(無 controls is-active/is-configuring/ + pause-overlay/既有卡)時顯示——杜絕戰鬥中彈窗攔截操作。 +- 非模態頂緣左卡:overlay `pointer-events:none`、卡本體 `min(300px, 34%)` 寬、 + `max-height 72%`——不遮罩、不擋開始鈕與底部選單(320–844 五視口 AABB 零重疊 + 矩陣驗證);`aria-modal` 對話框語意+Escape 關閉。 +- 開玩自動收卡:MutationObserver 監聽 `#controls.is-active`,進遊戲即收 + (不記憶忽略,下次回 Title 再顯示)。 + +## 93. v14 殼局部 safe-area 量測(canvas 內 HUD 避讓預備) + +- `core/safeArea.ts`:讀 `#keys-layer` computed inset(CSS 已依 cw/ccw 換軸、 + 含地板值)→ 扣除地板取净 inset → 依邏輯寬/canvas CSS 寬換算邏輯 px; + 供 canvas 內 HUD(暫停/靜音鍵)避讓瀏海與 home indicator 接線。 + +## 96. v16 圖鑑分頁有界網格(P1-01,取代 §36 技能雙欄與 §94.3 成就網格常數) + +- 根因(Sonnet 席數學實證):技能分頁雙欄 5 列(y=122+⌊i/2⌋×84)第 9 項 + y=458、說明底緣 486 超出邏輯畫布 480;內容卡背景亦僅至 457。 +- 修法:`core/gridLayout.ts` 有界網格純函式——可容列數由縱向預算推導 + (floor((maxY−itemH−startY)/rowH)+1,至少 1)、欄隨量增(仿 §76 固定列 + 策略);分頁參數收斂 `core/codex.ts` CODEX_TAB_GRIDS 單點(技能 + 122/100/90、成就 112/90/84,maxY 一律 470)。 +- 技能分頁 3 欄 3 列:操作方式緊隨名稱動態排列(非固定 96px 偏移,最窄格 + 不越格)、詳述 12px 逐字換行;成就分頁接同一工具(21 條維持 6 欄 4 列 + 零視覺變化),條目成長自動擴欄不溢出。 +- 守門單測 gridLayout.test.ts:任何分頁內容不得超出 y=470(含技能 12 項/ + 成就 30 條成長情境)、技能文案長度上限(詳述 ≤72 字)、CodexScene 引用 + SSOT 跨檔守門(禁第二份網格常數)。 + +## 98. v16 選單 DOM 鈕命中短邊保底(D2,補充 §33 條目 7) + +- 根因(Grok 席):DOM 鈕以邏輯尺寸 × canvas 縮放直出 CSS 尺寸;直持 390×844 + 殼縮放 ×0.812 把次選單 56 邏輯高壓到 45.5 CSS px(低於 HIG 44pt 帶餘裕的 + 48px 基準),主 CTA 72→58.5 尚可但無守門。 +- 修法:`core/domButton.ts` `menuHitCssRect` 純函式——命中短邊 48px 保底、 + 對稱擴張(中心不漂移、視覺不變);`hud.ts addDomButton` relayout 一律經此 + 換算(Title/Map/Codex/Result 全場景 DOM 鈕自動受益)。 +- 驗證:domButton.test.ts 量測單測(直持縮放矩陣全鈕 ≥48、已達標邊不放大、 + 中心對稱、未縮放殼同樣吃下限);portrait e2e 於 Title 實測五顆選單鈕 + AABB 短邊 ≥48。 + +## 100. v16 勝利結算「下一關」主 CTA(D3,取代 §39 勝利回地圖單一動線) + +- 根因(Grok 席):魔王關擊破後結算僅「世界地圖」,接續遊玩需地圖折返一次, + 斷了闖關節奏。 +- 修法:一般勝利雙鈕——主 CTA「下一關」(nextLevelId 資料驅動,直入下一區 + 首關)+「世界地圖」降次選;ENTER 對應主 CTA。Result 勝利僅魔王關觸發 + (走動關經星星門直進地圖揭霧),L20 全破走謝幕不經 Result,故一般勝利必有 + 下一關(資料防禦仍回退地圖)。EX 勝利與敗北動線不變(再戰 EX/再戰魔王)。 +- 驗證:v16 e2e——L4 擊破後 next-level 直入 L5、map 次選並存;smoke 勝利案 + 改走 map 次選鈕。 + +## 101. v16 HUD 暫停/靜音 DOM 化(F-06+D4,取代 §35 暫停鍵與修復包 B 靜音鈕的命中層) + +- 根因(Composer/Grok/Sonnet 三席交集):局內暫停/靜音為 canvas 熱區—— + 自動化不可達、讀屏不可見,旋轉殼下依賴 transformPointer 補償。 +- 修法:命中改由同位 DOM 鈕承接(`addDomButton` 支援 rect getter 隨視寬/inset + 動態錨定,data-menu=pause/mute+aria-label;靜音帶 aria-pressed 狀態), + canvas 圖示保留純視覺、移除 interactive(沿 recon-v4 A.3 單一命中路徑); + `pause.ts addButton` 補 aria-label。 +- 命中尺寸:邏輯 44×44 經 §98 短邊 48px 保底,直橫持皆達標。 +- 驗證:v16 e2e(暫停開選單真凍結→繼續、靜音 aria-pressed 與靜音偏好同步 + 翻轉——v19 §118.1 後偏好真值為 `sp-settings.audioMuted`);portrait e2e + 真觸控點暫停即凍結、pause/mute AABB 短邊 ≥48。 + +## 103. v16 標題字形品牌化(D6,補充 §36) + +- 根因(Grok 席):主標 system-ui 純白字+單層描邊,讀感是「預設字體」而非 + 品牌 logo。 +- 修法(零新字型檔):雙層字形——底層深紫厚描邊(stroke 12)下沉 5px 造 + 糖果貼紙立體感;頂層白字帶垂直粉漸層 tint(四角 tint 上白下粉)+柔影 + (blur 6)+細紫描邊;副標 StarPuff 加粗+白描邊。禁重依賴(不引字型檔)。 + +## 104. v16 怪物圖鑑分頁(F-03,取代 §76 單頁定案) + +- 根因(Composer 席):23 隻 × 12 欄 2 列——854 最窄殼 cellW 67px、行為敘述 + 4-5 字/行,直持過密難讀(§76 當年以 18 格評估的 cellW≈89 已被 v12 圖鑑 + 補完擠破)。(v17 訂正:CODEX_MONSTERS 實為 23 隻(12+11),原文 24 為 + 敘述失準;ceil 分頁斷言不受影響。) +- 修法:接 §96 有界網格——每頁 12 格 6×2(MONSTER_PAGE_SIZE,cellW 回到 + 134+),底緣「上一頁/第 n/N 頁/下一頁」翻頁列(restart 帶 monsterPage, + 沿分頁切換慣例;單頁不顯示);頁序沿 CODEX_MONSTERS,未來新增怪自動增頁。 +- 驗證:gridLayout 守門(每頁 6×2 ≤470、23 隻恰兩頁);v16 e2e 翻頁雙向; + 854/1200/直持截圖對照。 diff --git a/apps/starpuff/docs/design/07-art-audio-fx.md b/apps/starpuff/docs/design/07-art-audio-fx.md new file mode 100644 index 000000000..c61e2fe63 --- /dev/null +++ b/apps/starpuff/docs/design/07-art-audio-fx.md @@ -0,0 +1,118 @@ +# 星噗噗 — 美術資產、音效與演出 + +> **職責範圍**:看起來與聽起來的規格。統一風格關鍵詞與各批 codex imagegen 資產清單、背景平鋪與視差、場景裝飾密度、Juice 清單與動畫打磨、zzfx 音效表。 +> +> **不在本檔**:物理/視覺縮放解耦通道(架構契約,見 `00-foundations.md` §117);震屏強度偏好(見 `05-save-settings.md` §118.2)。 +> +> **紀律**:codex imagegen 僅用於本檔列出的資產批次;走路/跳躍等動作一律程式 tween,不生成逐幀序列。 +> +> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 + +## 8. Juice 清單(品質關鍵,全數必做) + +hit-stop 60ms、震屏 4px、受擊白閃、squash & stretch(跳躍/落地/吸入鼓脹)、吸入漩渦粒子、星彈拖尾、傷害數字浮動、魔王死亡星爆、HP 心心受擊跳動、按鈕按壓回饋、入場/退場 tween。 + +## 9. 音效(zzfx,零音檔資產) + +jump、flap、inhale(迴圈)、swallow、shoot、hit、hurt、metal(皇冠落地)、pop(puffy 爆裂)、chomp(咬咬花咬合)、boss-roar、boss-slam、win、lose;BGM 用 zzfx 合成短循環(手刻序列混音,零依賴)。首次觸控後 resume AudioContext(iOS 必須)。靜音偏好存 localStorage(sp-muted)(v19 已由 §118.1 取代:收斂為 `sp-settings.audioMuted`,`sp-muted` 僅作一次性 migration 來源,落盤後刪除)。 + +## 10. 美術資產規格(codex imagegen 專用;除此之外嚴禁動用 codex) + +統一風格關鍵詞(每次生成必附): +`kawaii chibi jelly creature, soft pastel palette, thick rounded soft outline, glossy jelly highlight, flat cel shading, clean high-quality mobile game sprite, centered, full body` + +透明需求資產以 flat #00ff00 背景生成後去背。生成尺寸 2048×2048(bg 為 1024×1536),交付至 `apps/starpuff/src/assets/sprites/`。表列 `.png` 為生成源檔名;實際入庫交付為同名 `.webp`(q82 壓縮,透明保留)。 + +| 檔名 | 內容 | 備註 | +| ----------------- | ------------------------------------------- | ---------------------------------------------------- | +| hero-idle.png | 噗噗待機:圓潤微笑、星星呆毛 | 薄荷奶油 #BFF3E0、腮紅 #FFB7A0 | +| hero-inhale.png | 噗噗張大嘴吸入 | 嘴佔臉 40% | +| hero-puffed.png | 噗噗雙頰鼓滿 | 含住星星微光 | +| hero-hurt.png | 噗噗受傷 >\_< | 淚珠 | +| minion-jelly.png | 果凍丁 | 草莓粉 #FFB3C7 | +| minion-floaty.png | 飄飄鳥 | 薰衣草 #CBB7F0、小翅 | +| minion-spiky.png | 刺刺瓜 | 萊姆 #D9F29B、短刺 | +| boss-idle.png | 果凍王+金皇冠 | 葡萄紫 #9B7BD8、跋扈眉 | +| boss-enraged.png | 果凍王憤怒紅化 | 紅暈 #FF6B6B、怒目 | +| fx-star.png | 五角星彈+光暈 | 金黃 #FFD966 | +| bg-arena.png | 直向粉彩天空果凍島戰場(1024×1536,不去背) | 底部 1/3 乾淨平台區、上 2/3 雲朵漸層 #FDEFF6→#D6ECFF | + +走路/跳躍動畫一律用程式 tween(squash/stretch/bob/rotate)實現,不生成逐幀序列。PWA icon 由 hero-idle 裁切導出。 + +## 18. 動畫流暢度打磨清單(全實體) + +走路彈跳(玩家移動時 y 微幅 bob + 輕微傾斜)、落地塵埃圈(著地速度 >300 觸發)、所有敵人生成 popIn(scale 0→1 back.out)、死亡 squash 消失、星星門吸入過關演出(玩家縮小旋轉飛入)、轉場卡緩動(slide+fade)、鏡頭剛性跟隨 lerp(1,1)(v3 定案;lerp×roundPixels 逐幀往返跳動的根因修復見 §25 抖動修復定案)。 + +## 19. v2 美術資產增補(codex 專用;生成尺寸同 §10 規範) + +| 檔名 | 內容 | 備註 | +| ----------------- | ------------------------------------------------------------------------ | ---------------------------------- | +| bg-meadow.png | 直向果凍草原:粉綠草丘、果凍花、奶油雲(1024×1536 不透明) | 底 1/3 乾淨地面 | +| bg-heights.png | 直向雲朵高台:高空粉藍雲海、遠景漂浮果凍島(1024×1536 不透明) | 底 1/3 乾淨、中段留平台視覺空間 | +| bg-throne.png | 直向魔王城王座廳:葡萄紫果凍城、金冠紋飾、戲劇但可愛(1024×1536 不透明) | 底 1/3 乾淨、頂部王座剪影 | +| minion-puffy.png | 氣球魨(2048 透明) | 珊瑚粉 #FFA8A0、短圓刺、驚訝圓眼 | +| minion-chompy.png | 咬咬花(2048 透明) | 鵝黃 #F5E6A8、花瓣嘴微張、莖葉底座 | + +## 25. 背景連續感與視覺升級 + +- 每關背景改「橫向無縫平鋪」新資產(§27),tileSprite 雙層視差:遠景 scrollFactor 0.25、近景 0.6;接縫若可見改鏡像平鋪。 +- 共用漂浮雲層(透明平鋪帶)恆速漂移;每關主題 ambience 粒子(草原花瓣/高台雲絮/回廊星塵/王座金塵,密度低於 8 顆同屏)。 +- 色彩分級:每關極輕 tint overlay(alpha 0.06)統一色調。 +- 動作抖動修復定案(US-022 調查結論):根因為 camera lerp 次像素捲動 × roundPixels 量化的逐幀往返跳動——修法為剛性跟隨 `lerp(1,1)` + `roundPixels: false`(非 pixel-art 美術);walk bob 改 PRE/POST_UPDATE 視覺偏移掛鉤不污染物理;全實體動作平滑化(tween ease 統一 Sine 系)。 + +## 27. v3 美術資產(codex 專用;橫向平鋪) + +| 檔名 | 內容 | 規格 | +| ---------------- | ------------ | --------------------------------------- | +| bg-meadow-l.png | 果凍草原橫景 | 1536×512、水平無縫平鋪、底 1/4 乾淨地帶 | +| bg-heights-l.png | 雲朵高台橫景 | 同上、中段留平台空間 | +| bg-arena-l.png | 星空回廊橫景 | 同上、星塵粉紫調 | +| bg-throne-l.png | 魔王城橫景 | 同上、紫金王座廳 | +| fx-clouds.png | 共用漂浮雲層 | 1024×256、透明、水平無縫平鋪 | + +## 31. v4 美術資產(codex 專用) + +| 檔名 | 內容 | 規格 | +| ----------------- | ------------------------------------------------ | ------------- | +| minion-shelly.png | 殼殼:藍綠 #7FD8C8 硬殼龜果凍、圓殼紋、憨笑 | 2048 透明 | +| minion-zappy.png | 雷雷:薰衣草黃 #E8D88A 電氣水母、火花觸鬚、瞇眼 | 2048 透明 | +| props-meadow.png | 草原道具條:果凍蘑菇/花叢/小石/木牌 4 件橫排等距 | 2048×512 透明 | +| props-heights.png | 高台道具條:氣球/雲絮/風向旗/星星燈 4 件 | 2048×512 透明 | +| props-arena.png | 回廊道具條:水晶簇/星柱/光苔/浮石 4 件 | 2048×512 透明 | +| props-throne.png | 王座道具條:旗幟/燭台/王冠雕像/寶箱 4 件 | 2048×512 透明 | + +道具條以固定 4 等分切割(512×512/件),佈景密度規範見 §32。表列 `.png` 為生成源檔名(§10 慣例);實際入庫交付為切割後之 `prop-{meadow,heights,arena,throne}-1..4.webp` 與 `minion-*.webp`(q82、透明保留),資產鍵與檔名對齊 `core/assets.ts` 註冊表。 + +## 32. 場景裝飾密度規範 + +- 每關地面帶每 400-600px 佈置 1-2 件主題道具(levels.ts decor 資料驅動、隨機微縮放 0.9-1.1 與 y 抖動);深度在玩家後、平台前。 +- 道具純裝飾無碰撞(KISS);可破壞磚除外(§29)。 +- 同屏道具上限 6 件防雜訊;與 ambience 粒子總量合併預算(同屏繪製物 ≤14)。 + +## 55. v8 美術資產(codex imagegen 專用;配額 6/6 用滿) + +| 檔名 | 內容 | 規格 | +| ---------------- | ------------------------------------------- | ------------------- | +| minion-spora.png | 孢子菇:鼠尾草綠 #A8D8A0 圓菇、奶油斑點 | 2048 透明 → 512webp | +| minion-gusty.png | 風飄鳥:淡天藍 #A8CBF0 圓鳥、後掠翼、風渦 | 2048 透明 → 512webp | +| minion-boomy.png | 迴力殼:暖陶土橘 #E8A878 犰狳、舉新月殼刃 | 2048 透明 → 512webp | +| boss-noctra.png | 暗月蝠王:暮光紫 #7A6FD8 蝙蝠、銀月冠、星翼 | 2048 透明 → 512webp | +| bg-canyon-l.png | 翔風峽谷橫景:暖杏糖霜峽谷、風痕絲帶 | 1536×512 無縫平鋪 | +| bg-eclipse-l.png | 蝕月王座橫景:薰衣草夜空、金月、紫塔剪影 | 1536×512 無縫平鋪 | + +重用評估結論:L6 迴聲石廊重用 `bg-arena-l`(同族星空回廊)+grade/ambience 變化;三關 +道具條全數重用既有主題(heights/arena/throne),不另生成。素材 ticket 與生成腳本存 +epic 資料夾(art-v8-ticket.md / run-art-v8.sh)。 + +## 61. v9 美術資產(codex imagegen 專用;配額 5/5) + +| 檔名 | 內容 | 規格 | +| ---------------- | -------------------------------------------- | ------------------- | +| hero-volt.png | 噗噗雷化:電黃電弧環身、閃電呆毛、自信笑 | 2048 透明 → 512webp | +| hero-gale.png | 噗噗風化:風藍渦紋、氣流小翼、飄浮姿 | 2048 透明 → 512webp | +| hero-shell.png | 噗噗殼化:青綠圓甲殼片、殼紋高光、壯站姿 | 2048 透明 → 512webp | +| minion-magno.png | 磁極獸:鋼藍灰圓胖獸、馬蹄磁鐵角(紅藍極點) | 2048 透明 → 512webp | +| minion-mirri.png | 鏡面蟲:珍珠銀紫圓甲蟲、拋光鏡面背甲高光帶 | 2048 透明 → 512webp | + +背景不生成:L8/L9 重用既有橫景+grade/ambience 變化(§60)。素材 ticket 與生成腳本 +存 epic 資料夾(art-v9-ticket.md / run-art-v9.sh)。 diff --git a/apps/starpuff/docs/design/08-safety-nets.md b/apps/starpuff/docs/design/08-safety-nets.md new file mode 100644 index 000000000..9e4ce22bb --- /dev/null +++ b/apps/starpuff/docs/design/08-safety-nets.md @@ -0,0 +1,235 @@ +# 星噗噗 — 反卡死保證、保底機制與難度量測 + +> **職責範圍**:確保玩家永遠不會卡死、以及量化難度的工具。反卡死保證律(spawner/星星門/飢荒救援)、慈悲補血愛心 pity 保底、走動關供給可及性、難度量化 CLI 與分級 bot 口徑。 +> +> **不在本檔**:各機制自身的 anti-softlock 資料不變式,隨機制寫在 `04-levels-world.md`(氣流柱頂淨空、潮汐 dry-window、流星排除帶等)。 +> +> **硬不變式(使用者明令,全部 MUST)**:基礎星彈恆可通關;魔王關須有多種可行破關策略;難度循序漸進,永不無限卡關。關卡難度以分級 bot 勝率量化驗收(普通 ≥40%、熟練 ≥80%)。 +> +> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 + +## 26. 反卡死保證(softlock 防護,全部 MUST) + +- Spawner 保證律:玩家彈藥 0 且場上無可吸怪時,下一隻生成強制可吸(覆蓋權重);boss 期同律且立即補生(不等間隔)。 +- 星星門必達:配額達成即於可達地面生成,overlap 高度涵蓋跳躍弧線。 +- 場景無坑洞設計維持(無墜落死);世界邊界實牆。 +- visibilitychange:切背景暫停物理與計時(v5 已由 §35 取代:回前景停在暫停選單、點繼續才接續,不自動恢復)。 +- 深度探索 QA 劇本:邊緣紮營 5 分鐘、只殺不可吸怪、彈藥歸零僵持、暫停/恢復循環、快速連死——全數不得卡關。 + +## 62. v9 慈悲補血愛心(logic/mercyHeal.ts 純決策,保底機制非資源農場) + +- 機制參數表(`MERCY_HEAL`,**確定性 pity 決策**;時鐘由呼叫端注入供測試,RNG 僅決定 + 生成位置不參與生成與否——v19 #819 卡 9 去 RNG,取代原 35%/60% 擲骰): + +| 參數 | 一般關 | 魔王房(含 EX)override | 說明 | +| ------------- | --------------- | ----------------------- | ---------------------------------------------- | +| 評估間隔 | 5000ms | 同左 | 每 5s 評估一次(未過門檻僅重置評估計時) | +| 血量門檻 | HP ≤ 總血量 1/3 | HP ≤ 2(絕對值) | 5 血制一般關即 HP ≤1 | +| 久戰門檻 | ≥60s | ≥12s | 本關(本命)經過時間;boss 戰典型 20–60s | +| 生成冷卻 | ≥45s | ≥18s | 距上次愛心生成 | +| pity 受傷門檻 | ≥2 次 | ≥2 次 | `pityHurts`/`bossPityHurts`,自上次生成起累計 | +| pity 低血門檻 | ≥30s | ≥15s | `pityLowHpMs`/`bossPityLowHpMs`,低血累計時間 | +| 每命上限 | 2 次 | 2 次(EX 1 次) | `exMaxPerLife=1`;死亡重試/重開關卡即重置 | +| 回復量 | +1 HP | 同左 | 走既有回復管線 | + +- pity 決策語意(`advanceMercyHeal`):**首顆固定生成**(`spawned === 0`);第二顆起需 + 自上次生成後累積「受傷次數 ≥ pity 受傷門檻」**或**「低血狀態累計 ≥ pity 低血門檻」 + 任一成立才保底放行。受傷偵測=HP 較上一 tick 下降即計 1(單次多傷計 1,回血僅更新 + 基準);低血累計僅於存活且過血量門檻時推進。生成當下 pity 計量歸零。 +- 計量與評估分離:pity 計量逐幀累積,評估間隔到期才做生成決策;任一門檻不過只重置 + 評估計時,**保底計量不消耗**(低血久撐不會白費)。 + +- 生成呈現(重用共用愛心拾取管線 systems/pickups.ts,勿新造 pickup 系統):隨機擇一 + ——空中緩降型(y=150 起以 26px/s 緩慢飄落至地面錨點,降落中可接住)或地面定點型 + (地面錨點浮動);位置=玩家 ±120-240px、夾限世界內(下界 50 保玩家貼牆可達); + 生成時輕微閃光(burstSmall 粉)+zzfx reveal 提示音。 +- 適用範圍:一般關與魔王關(含 EX)皆啟用;HUD 無新元素。 +- 判定:拾取走逐幀 AABB+水平掃掠幾何判定(§43 direct pair 漏檢慣例修法), + 高速走過必中;15s 未拾取自動淡逝。 +- 平衡定位:上限與冷卻硬性,非資源農場;不影響 §26 反卡死保證律(彈藥飢荒補生 + 獨立運作)。 + +## 107. 走動關供給保證與滿潮平衡(issue #804/#805/#806) + +> 出處:全 20 關實測攻略工(PR #802)回報三缺陷;量測工具 `scripts/v18-level-bot.mjs` +> (play/idle/stall/forage 四模式,真實鍵盤事件、不用受控賦星),前後數據 +> `screenshots/starpuff-v18/*.json`。 + +### 107.1 走動關飢荒救援律(#804,P1;擴充 §26) + +- 根因:「飢荒立即補生」保證律只在 `level.boss` 分支生效;走動關同屏上限(5)被 + 紮根/不可吸個體(chompy、spora、精英本體)佔滿時生成器停轉,玩家零彈陷入 + 「無彈、無可吸怪、無新生成」軟僵局——唯一自救是下砸,違反 anti-softlock + 「基礎星彈恆可通關」精神。 +- 修法(`logic/levels.ts`):`STARVATION_RESCUE_MS = 4000`——零彈且同屏無可吸怪 + 持續 4s → 強制補生可吸怪(**無視同屏上限**;品種沿 §26 `pickSpawnKind` 飢荒 + 覆蓋,僅自恆可吸子集抽選)。飢荒中斷歸零重計;開門後不救援;魔王關維持 + 立即補生分支(bossFactory 契約零漂移)。 +- 閾值設計:4000ms 長於全部走動關 `spawnIntervalMs`(1000–2600)——一般節流仍是 + 主要供給路徑,救援僅在停轉時兜底;同屏可短暫超編 +1,可吸怪被消化即回落。 +- bot 實證(stall 模式:官方 spawn 鉤子填滿 5 隻 chompy+零彈掛機 90s): + - 修復前:L3 停轉 87.8s、L5 停轉 89.9s(全窗凍結,重現軟僵局)。 + - 修復後:L3 最長停轉 3.4s(複測 3.9s)、L5 4.2s(救援閾值內必出可吸怪)。 + - 有機重現(L3 play 420s):修復前最長飢荒 293.4s(bot 卡死)→ 修復後 2.7s、 + 配額 210.8s 開門(複測 3.5s,全部走動關 play 複測飢荒窗 ≤3.5s); + L3/L5 idle 掛機 300s 最長飢荒 1.2s/1.4s。 + +### 107.1.1 救援可及性保證(#812,T2;擴充 §107.1) + +- 根因:§107.1 只保證「生成」不保證「可及」——救援自視野外側入場(~1 屏外)、 + 名義可吸但不可及個體(高空 gusty/遠端威脅型)阻斷飢荒計時,星暴誤放後 + 恢復 p50 5.5s/p95 19.9s、45s 未恢復 16 次(T1 基線)。 +- 修法(waves.ts+levels.ts 最小增量,不動 §107.1 觸發閾值): + - 生成位:玩家前方 100–150px 吸入錐內(`rescueSpawnX`,站定面向即可吸、漂移型 + 品種不逃錐;越界/尾端安全區改後方等距);懸浮定高品種降至站立錐可及帶 + y=300;潮汐上收沿 adjustSpawn(同層可達)。 + - 品種:恆可吸 ∩ 低威脅(safe)優先(`pickRescueKind`);滿潮排除位移壓迫型 + (gusty 側風);無 safe 候選回落恆可吸全集(anti-softlock 優先)。 + - 單席+逾時重定位:場上救援個體上限 1;5s 未取得重定位到玩家身旁 + (恢復機構上限=觸發 4s+窗 5s+取得 ≈ p95 門檻對齊)。 + - 飢荒判定改可及性口徑:走動關僅計「近域 400px 內、可及頂線 y≥280、非 ranged + 威脅型」可吸個體——視野外、高空定飄(需跳拍追擊)或遠端威脅型(零彈追擊 + 高成本)均不阻斷救援計時;魔王關單屏維持全域計數。 + - 救援個體近域豁免律(審查收斂):無 safe 候選關(L14 全 ranged mix)的救援怪 + 會被 ranged 過濾排除——救援存活且近域即視為供給恢復候補、解除飢荒計時, + 否則「生成→不計→4s 再觸發」重定位循環自我否定;被消化後追蹤釋放、計時恢復。 +- 工具實測(starburst 探針、mid bot、全 15 走動關 × 6 樣本=90):45s 未恢復 + 16→0(爆炸輪根除)、全域 p95 19.9→9.5s(≤10s 門檻達成)、p50 4.6s。殘餘 >10s + 樣本 4/90:L10 ×2(10.2/10.5s)、L15 ×1(11.5s)、L14 ×1(21.3s,滿潮相位 + 避難+bot 受擊循環窗)——原始 JSON 全數留檔 `.claude/product-intel/level-audits/ +t2b-812-sb-l*.json`。 + +### 107.1.2 L14 星暴恢復重尾根除(#841,T7;擴充 §107.1.1) + +- 逐幀驗屍(兩輪共 7 個 >10s 樣本、100ms 全敵座標+潮汐相位遙測)鎖定三機制: + 1. 紮根怪穿地:immovable 動態體與靜態地面不做分離——spora/chompy 生成即沉至 + 世界底(y≈462,全關卡皆然);L14 救援 spora 因此埋地不可及,§107.1.1 的 + rescueNear 豁免律又抑制新救援、5s 重定位再埋,為重尾主因。修法:解除 + setImmovable(紮根語意由更新迴圈不賦速維持;敵人唯一 collider 即 vs 地面, + 該旗標無保護對象)。 + 2. 滿潮救援沉水:不變式 17 上收僅保護無重力品種——重力型救援滿潮期必落回 + 水下主地面,平台層避難玩家構不到、等退潮即成殘尾。修法(機制級泛化): + 所有「潮汐關+有平台」的滿潮救援一律錨定最近平台頂(固定紮根 spora+ + 關重力,比照 bubbla「生成 y 即錨點」慣例;救援路徑本就覆寫品種,不依賴 + 關卡表含 spora——L14/L15 同享);退潮/無平台關維持既有路徑。 + 3. 貼身錐形死角軌道:追擊過衝站上 splatta/spora(dx≈0)時 45° 錐形必敗、 + 不拉不吞,反覆繞軌 3-8s。修法:§107.1.1 殼殼貼身豁免泛化為全可吸品種 + (INHALE_NEAR_PX=60 近域圈 face-agnostic;#844 候選 zone 反向帶已對齊)。 +- 工具實測(starburst 探針、mid bot):L14 基線 p95 18.9s(3/10 超標)→ 修後 + 官方 ×10 p95 5.0s、驗屍 ×14 p95 4.6s、逐關批 ×6 p95 5.2s;全域 15 走動關 + ×6=90 樣本 p95 9.3s(§107.1.1 基線 9.5s 不回退)、45s 未恢復 0。原始 JSON + 留檔 `841-fix-l14.json`/`841-global-l*.json`。 + +### 107.2 L5 供給節奏調參(#805,P2;補充 §52) + +- 根因:L5 缺「主動接近玩家」的供給怪——gusty 於生成點高空盤旋(drift 錨定 + y≈220,玩家不入 200px 觸發域即永不俯衝)、spora 遠處紮根,兩者名義可吸但 + 不可及(合計 50%),佔滿同屏後地面帶供給真空;唯一追蹤型供給 jelly 僅 15%。 + 掛機探針實錄:兩隻 gusty 停在 x≈1160–1290 全程 120s 不移動。 +- 修法(資料單點,`levels.ts` L5 enemyMix):gusty 30→25%、spora 20→15%, + 讓渡地面帶 jelly/floaty 各 +5%——駐留型假供給 50%→40%、可及供給 30%→40%; + 可吸佔比 0.8 不變、gusty 主場(≥25%)契約維持、spiky 威脅面 20% 不變。 +- 巡航高度 lever 否決記錄:收割微測(gusty 單體,走近+跳躍吸入 ×6)y=220 與 + y=240 平均收割耗時同為 1.1s——高度動全域五關(L5/L6/L9/L14/L18)卻無主動 + 收割收益,選 level-scoped mix 調參。 +- bot 前後(forage 錨定量測:x=1400 定點吃怪換血、滿匣傾瀉、精英隔離,300s; + 指標=最長彈藥斷檔,>60s 計爆炸輪)——三批次全樣本 provenance,量測 JSON + 全數留存 `screenshots/starpuff-v18/`: + + | 批次(時序) | 組態歸屬 | 各輪(s) | 中位 | 平均 | 最大 | 爆炸輪 | + | ------------------- | ------------------------------------------------------------------------------------------- | -------------------------- | ---- | ---- | ----- | ------ | + | oldmix ×2+base2 ×3 | 舊 mix(base2 為回到 HEAD 重測基準) | 9.0/10.1/5.4/1.0/229.5 | 9.0 | 51.0 | 229.5 | 1/5 | + | newmix ×4 | 不可考——量測期間工作樹來回切換、未逐一 commit,JSON 無組態指紋欄;時序上為第一候選 mix 量測 | 16.7/1.2/5.4/236.7 | 11.1 | 65.0 | 236.7 | 1/4 | + | fix2 ×3 | 新 mix(09410c71 版 levels.ts) | 193.6/2.9/3.4 | 3.4 | 66.6 | 193.6 | 1/3 | + +- 誠實結論(全樣本口徑,取代早期僅列基準+fix2 的選擇性敘述): + - 基準側 base2-r3=229.5s 證明爆炸輪為舊 mix 既有尾部行為,非新 mix 引入。 + - 最對抗性合併口徑(newmix+fix2 全 7 輪)中位 5.4s,仍優於 L6 鄰關對照 + 29.9s——#805「回落至鄰關水準」驗收以中位數口徑成立。 + - 爆炸輪率未改善(基準 1/5 vs 合併 2/7):尾部凍結組態與 mix 調參無關, + 收斂歸 issue #812。 + - idle 中場站定複測 reach 真空最長 1.8s(<30s 門檻)。 +- 已知缺口(#812,誠實聲明):爆炸輪=同屏 5 席被「名義可吸但不可及」個體 + (高空 gusty/遠端 spora)佔滿且 bot 不跳吸、不下砸、不死亡的凍結組態。 + gusty/spora 屬 `canInhale` 真值集,佔滿時 `aliveInhalableCount > 0`—— + §107.1 救援律僅在「同屏零可吸」成立時觸發,此凍結組態**不在其涵蓋範圍**, + 無系統面兜底;可及性保證歸 issue #812(T2 修復列車:救援供給改可及性口徑)。 + 真人玩家走近 gusty 觸發域即誘導俯衝、走向 spora 即可吸,bot 固定策略不做 + 此補償。mix 內合法調參空間已用盡(gusty 主場 ≥25% 契約),若需再收斂需 + PM 裁決放寬主場契約或引入駐留型個體同屏壽命機制。 +- 三軸不倒掛:D 軸威脅面不變(spiky 0.2、gusty 俯衝機制不動,僅密度 -5pt)、 + M/P 軸不動——L5 3.2 分持平或微降,CV-1(L5 < L6 4.4)與 CV-3(L5 < L4 3.6) + 均成立。 + +### 107.3 L14 滿潮死亡螺旋雙修(#806,P2;補充 §71) + +- 根因:滿潮期主地面淹沒(漲頂 352 < 地面頂 400),被擊退落水後「浸水扣血 + (每 1.5s i-frame 到期即再扣)+水平強緩速 60px/s 掙扎」;同時漲潮期生成上收 + (交叉不變式 17)把新怪全堆到平台層,避難點擁擠、splatta 拋物壓制。 + 死因取樣:修復前 L14 bot 死亡 56% 發生於 flood 相位窗。 +- 修法一(浸水甦醒無敵,`logic/tide.ts`):浸水受擊「實際掉血」→ 授予 + 基礎受擊 i-frame(1500ms)+甦醒追加窗 `soakWakeInvulnMs = 1000`(沿 + `grantInvulnerability` 取 max 語意)——總保護 2.5s 涵蓋「浮出水面+跳回平台層」 + 重站位;未掉血(i-frame 期/護盾格擋)不追加,杜絕無成本刷無敵。 + enemy 接觸傷不變;Syrona P2/P3 潮汐同規則受益。 +- 修法二(滿潮生成降載,`floodHold`):滿潮(flood 相位)暫停走動關一般補生 + ——計時照走、凍在滿格,退潮首 tick 即刻補回,總供給節奏近似不變、只是 + 錯開滿潮窗;**飢荒救援(§107.1)與魔王關供給不受閘**(anti-softlock 優先, + Syrona 供彈節奏零漂移,契約測試守門)。 +- 修法一單獨實測:平均死亡循環 37.2s → 44.8/43.6s(存活 +20%)但總死亡未顯著 + 回落(25/28 → 24/24)——螺旋另一半是滿潮平台層擁擠,故加修法二成組合拳。 +- bot 前後(play 420s,基準 5 輪 vs 組合拳 4 輪):總死亡 27.0 均(25/28/28/ + 27/27)→ 21.3 均(20/22/22/20),-21%(區間無重疊);平均死亡間隔 + 15.2s → 19.6s,+28.8%(≥25% 門檻);L6 對照 play 死亡 21.5 均 → 19.5 均、 + L13 對照 0-1 死且 76.7s 開門(基準 4 死未開門),對照組零惡化。 +- 退潮生成尖峰驗證:idle 乾淨儀器(不推進、不跨精英線、授長無敵)300s 33 次 + flood 結束轉換,滿潮內生成 0、轉換後 1s 窗增量 >1 者 0——floodHold 釋放 + 無 burst(退潮首 tick 恰 +1)。play 口徑偶見同窗 +2 樣本,經驗屍為 + 「held 釋放 +1 疊加跨精英觸發線生成 +1」巧合,非生成器 burst。 +- 獨立核實欄(審查收斂補測):bot idle 輸出新增 `floodSpawns`(flood 相位內 + alive 總數逐 tick 上升量);複測 `post2-l14-idle.json` 300s 32 次 flood + 結束轉換、`floodSpawns: 0`——「滿潮內生成 0」可由 JSON 單欄直接核實, + 不再依賴 samples 逐秒推導。 + +### 107.4 量測方法備註 + +- `v18-level-bot.mjs` 四模式:play(推進通關)/idle(掛機觀察生成器,授長無敵 + 隔離存活軸)/stall(#804 定向重現)/forage(#805 供給可及性——錨定覓食、 + 滿匣傾瀉、`slayElite` 隔離精英噪音)。 +- bot 為固定策略非人類水準:跨修復前後同構可比,絕對值不代表玩家體感; + play 模式死亡重試會重置關卡,指標僅取開門前窗。 +- 指標層次口徑(引用時必須標明):`fullStall` 量測「生成飢荒」(零彈+同屏 + 零可吸+滿席,§107.1 對象);`longestAmmoZeroSec`/`reachVacuum` 量測 + 「可及/推進」層(含 bot 策略盲區與地形卡位)——兩層各自成立、不可互相 + 換算,同輪 fullStall 3.5s 與 quotaStall 326.8s 並存(post-l03-play)即 + 正常樣貌,非數據矛盾。 + +## 108. 難度量化工具(#818,T1 量測基礎設施) + +常備 CLI 單指令輸出任一關(走動/魔王/EX)難度報告;所有列車(#809–#814) +的驗收探針收斂於此,遊戲行為零改變。 + +- 入口:`node scripts/level-audit.mjs [--ex] [--bot low|mid|high] +[--runs N] [--cap 秒] [--probe jump|telegraph|swallow|starburst] [--all]`; + 報告(JSON+Markdown)寫入 `.claude/product-intel/level-audits/`(gitignored)。 +- SSOT 分層:三軸公式、驗收門檻(機制 brief §10)、分級 bot 參數、跳越運動學 + 全數住 `src/game/logic/difficulty.ts`(vitest 錨定行守門);CLI 經 Node 24 + type stripping 直接 import(`scripts/lib/ts-bridge.mjs` 補副檔名解析), + 禁止在腳本內維護第二份公式或門檻。 +- 三軸自動計算:主計畫 §3.1 錨定關卡(走動 D 取 L1/L3/L6/L19、M 取 L1/L5/L19、 + P 取 L1/L2/L18;魔王取 L4/L20 全軸)經 raw 公式反推錨點後分段線性校準—— + 錨行精確重現、其餘關卡由靜態資料插值,實測修正(死亡/重試)折入 P 軸封頂 + +1.5。人工評分自此退役,主計畫 §4 折線由 `--all` 重生成。 +- 分級 bot:單一策略引擎+感知延遲快照環(決策一律讀 reactionMs 前的世界), + 低 500ms 基礎策略/中 350ms+dodge/高 250ms 完整策略(讀招/風箏), + 對齊機制 brief §10 EX 驗收口徑(#814)。 +- 四專項探針:jump(#809 解析矩陣+強制 P2 貼牆逃脫實證)、telegraph(#810 + 30ms 細粒度入態→實體化量測+250/350/500ms 反應注入迴避率,幾何重疊判定+ + 無敵隔離存活軸)、swallow(#811 chompy 滿席凍結生成後以可吸計數轉移標定 + 暈眩窗,正確時機/衝刺期雙臂)、starburst(#812;v19 §109 改注入:混味連授 + 5 槽滿匣自動結晶+SP 鍵引爆,量測引爆後零彈恢復時間分佈 p50/p95——B 長按 + 誤放路徑已消滅,探針改守恢復保證不回退)。 +- 量測方法沿 §107.4 口徑:bot 為固定策略非人類水準,跨版本同構可比; + 走動關指標僅取開門前窗;魔王招式序列以條件熵(bits)量化可背板度(#813 + 去固定基線)。`v18-level-bot.mjs` 保留為 #804–#806 修復證據的凍結重現腳本, + 新量測一律走 `level-audit.mjs`。 diff --git a/apps/starpuff/docs/design/99-superseded.md b/apps/starpuff/docs/design/99-superseded.md new file mode 100644 index 000000000..9b8528567 --- /dev/null +++ b/apps/starpuff/docs/design/99-superseded.md @@ -0,0 +1,146 @@ +# 星噗噗 — 已取代規格與歷史沿革 + +> **職責範圍**:回答「這段還算不算數」。本檔是全設計文件的**取代對照 SSOT**—— +> 逐條列出被後續版本取代/廢除的敘述、取代者,以及現行規則落在哪一檔;另收容 +> 已完全失效、留在現行章節只會干擾閱讀的整塊內容。 +> +> **不在本檔**:任何現行有效規格。所有現行規格都在 `00`–`08` 各主題檔內。 +> +> **為什麼多數取代標註仍留在原章節**:星噗噗的取代多半是「某章內的一條 bullet +> 被改掉」而非整章作廢(例如 §23 的星暴長按行退場,但同章的連鎖規則仍有效)。 +> 把這些單行搬離會切斷上下文、讓原章讀不懂,因此原章保留 inline 取代標註, +> 由下方 §取代對照表 作為權威索引。只有**整塊完全失效**的內容才實體搬到本檔。 + +## 章號紀律 + +章號 §N 是全專案穩定識別碼——`src/**` 程式註解、測試 describe 名稱與 issue 都直接 +引用(例:`// 慈悲補血愛心決策(GAME_DESIGN §62…)`)。因此 T7-C 主題拆檔 +**不重新編號、不回收號碼**;新章一律接續遞增。查號碼落在哪一檔請看 +[`../GAME_DESIGN.md`](../GAME_DESIGN.md) 的章號對照表。 + +## 版本列車沿革(拆檔前的章節分組) + +拆檔前 `GAME_DESIGN.md` 以「版本列車」時序分組,主題拆檔後這層敘事不再保留。 +原分組如下,供追溯某章屬於哪一批交付: + +| 列車分隔(原一級標題) | 涵蓋章節起點 | +| ----------------------------------------------------------------- | ------------ | +| (無標題:v1 基礎設計) | §1 | +| v2 擴充:層層關卡(PM 親撰) | §15 | +| v6 擴充:存檔與世界地圖(PM 親撰) | §38 | +| v8 擴充:世界擴張(PM 親撰) | §50 | +| v9 擴充:星化與挑戰(PM 親撰) | §57 | +| v10 擴充:三區完結(主計畫 SSOT=starpuff-20-levels-master-plan) | §65 | +| v11.1 熱修:站台下跳穿落回歸與吸入接觸豁免(P0) | §77 | +| v14 UX/PWA 列車:直持方向翻轉、控制自訂強化與安裝體驗(PM 派工) | §87 | +| v16 產品缺陷修復列車:三席批評收斂(PM 派工) | §95 | +| v17 債務列車:行為零改變維護性收斂(PM 派工) | §106 | +| v18 修復列車:全 20 關實測回饋三修(PM 派工) | §107 | + +其餘列車(v3–v5、v7、v12–v13、v15、v19–v24、T7)未在原檔設一級標題,以章號區間 +連續編排;各章標題本身已帶版本前綴(例:`## 79. v12 流星雨`)。 + +## 取代對照表 + +「現行規則位置」欄指出讀者應該去看哪一節;未列出的章節即為現行有效。 + +### 玩法與輸入 + +| 被取代的敘述 | 原章 | 取代者 | 現行規則位置 | +| ------------------------------------ | ----- | -------- | ---------------------------------------- | +| A/B 鍵斜排布局(B 在 A 左上 45 度) | §4 | §34 | `01-controls-input.md` | +| 直向持機顯示「請轉橫」遮罩 | §21 | §28 | `01-controls-input.md`(遮罩廢除) | +| manifest 鎖 `orientation: landscape` | §21 | §28 | `01-controls-input.md`(不鎖) | +| 虛擬手柄 A/B 斜排 64px | §21 | §34 | `01-controls-input.md` | +| cw(鏡頭朝左)為直持預設旋轉方向 | §28 | §87 | `01-controls-input.md`(改 ccw) | +| `DEFAULT_LAYOUT` 直橫持共用預設鍵位 | §34 | §95 | `01-controls-input.md`(旋轉感知分流) | +| 按鈕配置頁橫排操作列 | §34 | §88/§89 | `01-controls-input.md` | +| 彈匣全滿長按 B 0.8s 發動星暴 | §23 | §109 | `01-controls-input.md`(滿匣自動結晶) | +| 空中搖桿下+B 觸發下衝擊 | §23 | §44 | `01-controls-input.md`(改下+跳躍鍵) | +| 地面長按吸入鍵 0.6s 觸發星化變身 | §57 | §109 | `01-controls-input.md`(SP 鍵點按) | +| 滿匣長按維持星暴優先、殼盾讓位 | §40 | §109 | `01-controls-input.md`(頂槽即殼盾) | +| 下砸「空中」判定含 coyote 窗 | §44 | §77.1 | `01-controls-input.md`(收斂為真空中) | +| 下向判定=垂直位移 30px 門檻 | §23 | §85 | `01-controls-input.md`(扇區+18px) | +| 蹲姿/琥珀鍵僅在 down 持住時成立 | §77.2 | §85 | `01-controls-input.md`(drop-intent 窗) | +| `LANDING_SQUASH_MIN_VY` 著地速度閘 | §77.1 | §117 | `00-foundations.md`(補丁退場) | +| 空中疾衝 Air Dash | §30 | §44 | 已整體移除(見下方搬遷區) | + +### 怪物、魔王與關卡 + +| 被取代的敘述 | 原章 | 取代者 | 現行規則位置 | +| ---------------------------------------------- | ------------------ | --------------- | ------------------------------------------ | +| 四關制流程/總關數宣告 | §1/§3 | §84 | `04-levels-world.md`(20 關五區) | +| 七關雙魔王/九關/十二關/十六關的**總數**宣告 | §50/§60/§65/§76 | §84 | `04-levels-world.md` §84 | +| 世界地圖節點數與單頁佈局 | §60/§65/§76 | §78 | `04-levels-world.md`(五區分頁) | +| L1-L4 v2 直向世界寬配置表 | §15 | §21 起 | `logic/levels.ts`(見下方搬遷區) | +| 通關轉場卡(全屏 1.2s 關名) | §15 | §39 | `04-levels-world.md`(改世界地圖揭霧) | +| 四關累計總時語義 | §37 前 | §39 | `04-levels-world.md`(各關獨立 bestTime) | +| Jellord P1/P2 固定循環 | §6 | §111 | `03-enemies-bosses.md`(加權表選招) | +| Noctra `noctraAttackCycle` 循環游標 | §54 | §111 | `03-enemies-bosses.md`(加權表選招) | +| Noctra HP 70/狂暴 ×1.25/每損 10 HP 補給 | §54 | §63 | `03-enemies-bosses.md`(HP 52/×1.15/8) | +| Noctra 盤旋以凍結相位絕對座標直寫 | §54 | §64.1 | `03-enemies-bosses.md`(速度上限逼近) | +| Prismix/Syrona/Voidra 固定循環 | §68/§74/§82 | §112/§113 | `03-enemies-bosses.md`(加權表) | +| zappy 吸入得疾風星 | §30 | §40 | `02-combat-star.md`(改雷鏈星) | +| 星彈三系/五系/七系 | §20/§40/§46 | §53 | `02-combat-star.md`(九系) | +| v6 L1-L4 攻略 PoC 表 | §43 | §49/§56 | `04-levels-world.md`(見下方搬遷區) | +| 慈悲補血 35%/魔王房 60% RNG 擲骰 | §62/§63.1/§70 | §62(v19 改寫) | `08-safety-nets.md`(確定性 pity) | +| 魔王 EX 僅 L4/L7 兩王 | §58 | §86 | `03-enemies-bosses.md`(五王全開) | +| EX 差分止於 ×1.5 HP+一項質變 | §86.1 | §114–§116 | `03-enemies-bosses.md`(追加 P4 第二血條) | +| EX 段重試「段血回灌」語意 | §114.4 初版 | §114.4 裁決 A | `03-enemies-bosses.md`(進度保留) | + +### UI、存檔與偏好 + +| 被取代的敘述 | 原章 | 取代者 | 現行規則位置 | +| ---------------------------------------------- | ------------------ | --------- | ------------------------------------------- | +| 切背景自動暫停、回前景自動恢復 | §26 | §35 | `06-ui-shell-pwa.md`(停在暫停選單) | +| 「autoUpdate reload 蓋過暫停選單」為可接受邊界 | §35 | §118.4 | `05-save-settings.md`(更新套用閘根治) | +| 暫停/靜音鍵以 canvas 熱區承接命中 | §35 | §101 | `06-ui-shell-pwa.md`(DOM 鈕) | +| Title 次選單=圖鑑/技能介紹/按鈕配置 | §36 | §118.2 | `05-save-settings.md`(四鈕,配置頁轉入) | +| 圖鑑 4×2/5×2/7×2/8×2 單頁網格 | §36/§52/§59/§76 | §96/§104 | `06-ui-shell-pwa.md`(有界網格+分頁) | +| 技能分頁固定雙欄五列 | §36 | §96 | `06-ui-shell-pwa.md`(有界網格 3×3) | +| 勝利結算僅「世界地圖」單一動線 | §39 | §100 | `06-ui-shell-pwa.md`(「下一關」主 CTA) | +| 存檔 schema v1 | §38 | §94.2 | `05-save-settings.md`(v2 增 achievements) | +| 存檔無 checksum、無備援 | §38 | §118.3 | `05-save-settings.md`(checksum+備援輪替) | +| 重置進度「僅清 `sp-save`」 | §38 | §118.3 | `05-save-settings.md`(同時清備援) | +| 「本遊戲無設定頁」 | §38 | §118.2 | `05-save-settings.md`(Title 已有設定入口) | +| 靜音偏好存 `sp-muted` | §9 | §118.1 | `05-save-settings.md`(`sp-settings`) | +| 持向偏好存 `sp-rotation` | §87.1 | §118.1 | `05-save-settings.md`(`sp-settings`) | +| 鍵位布局存 `sp-key-layout` | §34/§89/§95.2 | §118.1 | `05-save-settings.md`(`sp-settings`) | +| 解析度 DPR cap 欄位 | §7 | 修復包 B | 已移除(Scale.FIT 自適應) | +| CODEX_MONSTERS 24 隻 | §104 | v17 訂正 | `06-ui-shell-pwa.md`(實為 23 隻) | + +## 已搬遷的失效內容 + +以下內容已完全失效,自現行章節移出留存於此,僅供追溯,**不得作為實作依據**。 + +### §15.1 L1-L4 v2 直向配置表(已失效) + +v3(§21)改橫式後世界寬全部重配(S1 2700/S2 3100/S3 3500/S4 854 單屏),怪物組合 +亦經 v4/v7/v16 多次重配。現行值以 `logic/levels.ts` 為 SSOT。 + +| # | 關卡 | 場景(bg key) | 世界寬 | 擊殺配額 | 生成間隔 | 怪物組合 | 難度設計 | +| --- | -------- | -------------- | ------------------- | -------- | ----------------------- | -------------------------------- | -------------------------------------------- | +| 1 | 果凍草原 | bg-meadow | 1680px | 6 | 2600ms | jelly 60%、floaty 40% | 教學關:平台低差、無地形威脅、幾乎不死 | +| 2 | 雲朵高台 | bg-heights | 1920px | 9 | 1800ms | floaty 40%、spiky 35%、puffy 25% | 垂直平台跳躍、spiky 巡邏走道、puffy 空中封位 | +| 3 | 星空回廊 | bg-arena | 2160px | 10 | 1300ms | 五種混編、可吸怪佔比 50% | 密度高壓、chompy 卡口、彈藥管理壓力 | +| 4 | 魔王城 | bg-throne | 480px(單屏 arena) | — | 補生 3500ms(僅可吸怪) | Jellord + jelly/floaty 補給 | §6 + §17 強化演出 | + +### §43 v6 L1-L4 攻略 PoC 表(已失效) + +v7(§47/§49)glowy/drilly 入編改寫 L2/L3 波次、v7 §48 加入精英房、v19 §109 廢除長按 +星暴——下表的權重、打法與觸發面均已不成立。現行逐關攻略見 §49/§56 與 +[`../WALKTHROUGH.md`](../WALKTHROUGH.md)。 + +| 關 | 設計意圖 | 最佳打法 | 無技能保底打法 | 難度曲線(quota/interval/構成) | +| --- | ------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------- | --------------------------------------------------------------------------- | +| 1 | 教學:移動/吸/射閉環,幾乎不死 | 開局反向拿 +1 HP 彩蛋,連吞 jelly×2 強化星速殺 | 站樁吸 jelly/floaty、點按發射,達 6 殺走右入門 | 6 / 2600ms / jelly 60%+floaty 40%(全可吸) | +| 2 | 垂直閱讀:平台跳躍+不可吸威脅初登場 | 吞 shelly(暈眩窗)備殼盾格擋 spiky 滾撞;雲台連站 3 次拿滿匣彩蛋 | 遠距吸 floaty/puffy 補彈、地面點射 spiky/shelly,貼牆等暈眩窗再殺 | 9 / 1800ms / floaty 35%+spiky 30%+puffy 20%+shelly 15%(可吸 ≥55%) | +| 3 | 高壓混編:彈藥管理+群戰清場 | 吞 zappy 得雷鏈星一發清簇;連吞 jelly→floaty→puffy 拿金星彈轟 chompy | 保持距離逐隻吸射;chompy 兩發標準星;彈盡靠 §26 飢荒強制補可吸怪 | 10 / 1300ms / 六種混編(jelly15+floaty10+puffy15+spiky25+chompy20+zappy15) | +| 4 | Boss Rush:彈幕閱讀+補給循環 | 開場 5s 內命中皇冠拿彩蛋;補生小怪吞成滿匣憋星暴(12 傷);P3 靠拍翅躲全場震落 | 吸補生小怪(飢荒立即補生)→ 點射果凍王,僅跳躍閃 slam/dash 即可磨死 | 0(HP 60 擊破制)/ 補生 3500ms / jelly+floaty(全可吸) | + +### §30 空中疾衝 Air Dash(已整體移除) + +v7 §44 裁決移除:雙擊 A 與拍翅節奏衝突且誤觸率高,輸入預算讓給下衝擊改制;相關輸入、 +純邏輯、殘影 fx、音效、圖鑑條目與測試全數清除(`movement` 夾速鏈保留供擊退殘速)。 + +> 原規格:空中雙擊 A 朝面向水平疾衝 180px、0.18s、無敵幀、CD 2s。 diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index e779f48f5..6ea396504 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:reward-starpuff-t7c-game-design-topic-split +- 原因:GAME_DESIGN.md 膨脹至 2436 行 118 章、以版本列車時序堆疊並靠「對舊章加取代標註」維護,讀者無法判斷哪一段現行有效,也無法憑主題定位(T7-C) +- 解法:以一次性腳本按 §NN 邊界機械拆為 design/00-08 九個主題檔+99-superseded 取代對照表,主檔改為索引入口(章號對照表+主題檔一覽+硬不變式);章號不重編以保 src 註解引用有效,拆分經逐章比對驗證 115/118 逐字元相同、3 章為刻意搬遷失效內容 + - 日期:2026-07-26 - ID:reward-starpuff-t7c-871-doc-drift-settings-mercy - 原因:T7-A(#864)改了慈悲補血判定與偏好儲存架構卻零文件同步,GAME_DESIGN 仍記 35%/60% RNG 擲骰與 sp-muted/sp-rotation/sp-key-layout 三散鍵,且宣告「本遊戲無設定頁」(issue #871,P1 SSOT drift) From e7e8e2a30dba19173e7373d65d79d37f4abfbfac Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 09:53:29 +0800 Subject: [PATCH 04/14] =?UTF-8?q?docs(starpuff):=20=E6=94=B6=E6=96=82?= =?UTF-8?q?=E6=94=BB=E7=95=A5=E8=88=87=20README=20=E7=9A=84=E5=AF=A6?= =?UTF-8?q?=E4=BD=9C=E6=BC=82=E7=A7=BB=E4=B8=A6=E9=96=8B=E5=88=97=E5=A4=A7?= =?UTF-8?q?=E7=BC=BA=E5=8F=A3=20issue=EF=BC=88T7-C=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - WALKTHROUGH 慈悲補血改述保底計數(非抽獎),補設定頁段落與 v21–v23 落後聲明 - README 修正變身觸發面(SP 鍵非長按)、補星暴 2.0、EX 五王 P4、設定頁與成就系統 - 大缺口不擅改:#874 魔王主題招式需真機實測、#875 六模組註解誤引 §5、#876 PRD 漂移待裁決 - 002 檔頭記分行改為本 PR 聚合淨變化(squash merge 對齊) 測試:以 mercyHeal.ts/transform.ts/settingsPage.ts/achievements.ts 核對每項敘述, prettier 3.8.1 通過;攻略打法未重測故不新增打法敘述,改以聲明標示落後範圍 Co-authored-by: Cursor --- apps/starpuff/README.md | 17 ++++++++++------- apps/starpuff/docs/WALKTHROUGH.md | 15 ++++++++++++++- docs/dev/002_development_reward_penalty_log.md | 5 +++++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/apps/starpuff/README.md b/apps/starpuff/README.md index c0ce0c9bb..0c84268d3 100644 --- a/apps/starpuff/README.md +++ b/apps/starpuff/README.md @@ -11,19 +11,22 @@ ## 玩法 -浮動搖桿移動、右下綠鍵(拇指)跳躍閃避果凍怪,右側偏上粉鍵(食指)按住吸入敵人、點按化為星彈反擊;空中「下+跳」使出下衝擊震開地面小怪(腹中含怪也能砸)。二十關五區世界:果凍平原、天風峽域(上升氣流)、幻晶深域(磁力域與星門折躍)、焙糖火山(糖漿潮汐與熱泉噴口)、星核聖域(低重力與流星雨)——十五關卷軸探索(各藏中魔王精英)加五座魔王關:果凍王、暗月蝠王、稜晶雙子、熔糖窯后,終戰蝕星魔核(定點轟炸生存段+低重力終局,段起點重試不回滾整場),全破迎來星光復甦謝幕,通關魔王更可挑戰 EX 變體。支援手機直持/橫持觸控手柄與桌面鍵盤(←→↓ 移動、Z 跳、X 吸射、ESC/P 暫停),PWA 安裝後可完全離線遊玩。 +浮動搖桿移動、右下綠鍵(拇指)跳躍閃避果凍怪,右側偏上粉鍵(食指)按住吸入敵人、點按化為星彈反擊;空中「下+跳」使出下衝擊震開地面小怪(腹中含怪也能砸)。二十關五區世界:果凍平原、天風峽域(上升氣流)、幻晶深域(磁力域與星門折躍)、焙糖火山(糖漿潮汐與熱泉噴口)、星核聖域(低重力與流星雨)——十五關卷軸探索(各藏中魔王精英)加五座魔王關:果凍王、暗月蝠王、稜晶雙子、熔糖窯后,終戰蝕星魔核(定點轟炸生存段+低重力終局,段起點重試不回滾整場),全破迎來星光復甦謝幕,通關魔王更可挑戰 EX 變體。支援手機直持/橫持觸控手柄與桌面鍵盤(←→↓ 移動、Z 跳、X 吸射、C 特殊技、ESC/P 暫停),PWA 安裝後可完全離線遊玩。 - 分區分頁世界地圖與存檔:五區各一頁、頁籤直達已解鎖區,區彩蛋收集分項計數;通關自動解鎖節點(揭霧動畫),進度、各關最佳用時與彩蛋收集存於本機(localStorage);點擊已通關節點可隨時重玩,地圖內可兩步確認重置進度;舊版存檔無縫升級二十節點。 - 吞噬賦星九系:果凍丁標準星/飄飄與風飄鳥疾風星/氣球魨爆裂星/殼殼殼盾星(長按舉盾格擋並反擊)/雷雷雷鏈星(命中跳電最近兩敵)/鑽鑽鼴重鑽星(破土窗吞取)/提燈水母流光星/孢子菇孢子星(命中緩速加持續傷)/迴力殼迴旋星(去而復返雙程判定)。 - 雙味混合星彈:依序吞兩隻不同怪即合成混合星(共九式——疾光穿透、巨爆、追電、雷爆、碎鑽散射、凝光凍結場、毒爆雲、電鋸迴旋、迴風刃),HUD 以雙色槽位顯示;基礎星彈恆可通關,混合僅為威力加成。 -- 星化變身:同系星彈集滿 3 發後長按吸入鍵 0.6 秒變身 10 秒——雷化(帶電衝鋒+鏈電束)、風化(近自由飛行+穿透風刃)、殼化(減傷反彈彈幕+強化下砸),再長按可提前解除。 -- EX 魔王挑戰:通關魔王節點後開啟第二入口——血量與速度強化、果凍王擊破分裂、蝠王月蝕彈幕矩陣,制霸取得紫星紀念章。 -- 慈悲補血:血量瀕危且久戰時,有機率在空中或地面出現補血愛心(每命至多兩次),接住回復 1 HP。 +- 星化變身:同系星彈集滿 3 發後於地面按 SP 情境鍵立即變身 10 秒——雷化(帶電衝鋒+鏈電束+放電反擊、磁力域免疫)、風化(近自由飛行+穿透風刃+落地滾翻與滑翔)、殼化(減傷反彈彈幕+滾殼衝撞+強化下砸),再按 SP 提前解除。 +- 星暴 2.0:彈匣集滿 5 槽瞬間自動結晶為頭頂蓄能星(彈匣清空、可繼續吸怪、可帶往下一關),按 SP 引爆全場清怪+魔王重擊+5 秒無敵。 +- EX 魔王挑戰:通關魔王節點後開啟第二入口——五座魔王全開,血量與節奏強化外各有專屬第四型態(第二血條):果凍狂潮、月相雙血條、裂核殘響、窯心暴走、內核裸奔;全制霸取得星核制霸金徽。 +- 慈悲補血:血量瀕危且久戰時會出現補血愛心(每命至多兩次、EX 一次),接住回復 1 HP;採保底計數而非抽獎——門檻到齊必出第一顆,之後依受傷次數或低血持續時間累積下一顆。 - 翔風峽谷上升氣流:踏入氣流柱免跳升空,乘風探索高台支線與隱藏彩蛋。 - 中魔王精英:走動關中段強化變體鎮守軟鎖門(迴聲石廊雙精英連戰),擊敗開門並掉落稀有味與回復食物(60 秒未敗門也會自動開啟,絕不卡關)。 -- 主選單:開始遊戲(接續當前進度)/世界地圖/圖鑑(全怪物行為與可吸標記)/技能介紹/按鈕配置;頁腳顯示建置版本號。 -- 按鈕配置:拖曳虛擬鍵自訂位置,儲存於本機(localStorage),一鍵恢復預設。 -- 暫停:HUD 右上暫停鍵或 ESC/P;切到背景自動暫停(物理、計時與音樂全停),回前景點「繼續」接關。 +- 主選單:開始遊戲(接續當前進度)/世界地圖/圖鑑(全怪物、技能與成就三分頁)/技能介紹/設定;桌機另有常駐「操作說明」,頁腳顯示建置版本號。 +- 設定:音效、震動回饋、遊戲中螢幕常亮、減少動態效果四個開關+震屏強度三段(關/弱/全),即改即存;按鈕配置由此轉入。 +- 按鈕配置:拖曳虛擬鍵自訂位置與大小,儲存於本機(localStorage),一鍵恢復預設。 +- 成就系統:21 條成就(進度/魔王/EX/收集/速通/隱藏),解鎖即時橫幅提示,圖鑑成就分頁可回顧。 +- 暫停:HUD 右上暫停鍵或 ESC/P;切到背景自動暫停(物理、計時與音樂全停),回前景點「繼續」接關。新版更新只在選單面套用,遊戲進行中絕不中斷。 ## 開發 diff --git a/apps/starpuff/docs/WALKTHROUGH.md b/apps/starpuff/docs/WALKTHROUGH.md index 6b06cdf94..410f3ef1d 100644 --- a/apps/starpuff/docs/WALKTHROUGH.md +++ b/apps/starpuff/docs/WALKTHROUGH.md @@ -4,6 +4,13 @@ > v15/v16 未變更關卡資料與魔王 FSM(僅 L1 教學關死亡重試改保留一半配額), > v18 修正本文「實測發現問題」三項:走動關飢荒救援、L5 供給調參、L14 滿潮雙修, > 對應章節已同步)。 +> +> **已知落後(issue #874)**:v21–v23 把五座魔王的固定招式循環改為**加權選招** +> (招池與 telegraph 數值不變,但出招序不再固定可背板),並新增六個一般模式即可 +> 遇到的主題招式——果凍回彈/蝕月斗篷/鏡界反射/鏡像殘影/焦糖化/星光虹吸。 +> 下列魔王章節的「招式循環」欄尚未涵蓋這些內容,補寫需重跑真機實測(本文件不收 +> 未實測的推導打法),追蹤於 #874;規格請暫以 +> [`design/03-enemies-bosses.md`](design/03-enemies-bosses.md) §111–§113 為準。 > 本攻略之路線與打法全數經真實瀏覽器實測驗證(Playwright 真機遊玩,非純資料推導); > 截圖存放於 QA 產物目錄 `screenshots/starpuff-walkthrough/`(repo 忽略清單內,僅供稽核佐證)。 > 更新約定:關卡資料 SSOT(`src/game/logic/levels.ts`)或魔王 FSM 變更時,本文件必須同 PR 更新對應章節。 @@ -13,6 +20,9 @@ - 行動裝置:左半屏浮動搖桿移動;右側 A 鍵跳躍(空中連按拍翅最多 3 次)、B 鍵吸/射; 技能可用時 B 鍵上方浮現 SP 情境鍵(引爆星暴/星化變身/解除變身,v19)。 桌機備援:方向鍵移動、Z 跳躍、X 吸射、C 特殊技(SP)。 +- 開玩前先進 Title「設定」(v19 起的統一設定頁):音效/震動回饋/遊戲中螢幕常亮/ + 減少動態效果四個開關+震屏強度三段(關/弱/全),改了即時生效即時存檔; + 虛擬鍵位置與大小的「按鈕配置」也從這裡進去。暈 3D 或想省電就把震屏調弱或關掉。 - 核心循環:長按吸入鍵吸入小怪 → 吞下得星彈(上限 5 發,吞什麼味射什麼味)→ 點按發射。 **吞入與射殺同樣計入擊殺配額**——搶配額時直接吞最快。 - 下衝擊(下砸):真空中「搖桿下+跳躍鍵」觸發,落地 60px 衝擊波 2 傷、冷卻 1.2 秒、零彈藥消耗、可破磚。 @@ -28,7 +38,10 @@ - 走動關死亡重試當前關(配額歸零重算;例外:L1 教學關死亡保留一半擊殺配額); 卡點關(L11/L15/L19)越過中點後死亡自 checkpoint 就地重生, 配額與計時保留。魔王關死亡進敗北結算,按重試自前室重來。 -- 慈悲補血:血量剩 1 顆心且久戰時,場上會隨機出現愛心(每命最多 2 次)——瀕死時留意撿取。 +- 慈悲補血:血量剩 1 顆心且久戰時,場上會出現愛心(每命最多 2 次,EX 1 次)——瀕死時留意撿取。 + **不是抽獎**(v19 起改保底計數):門檻到齊後第一顆固定會出;之後要再撐到「又被打 2 下」 + 或「低血硬撐 30 秒」(魔王房 15 秒)才會補下一顆,所以低血狀態撐久不會白費。 + 出現位置在你身邊 ±120–240px,空中緩降或地面浮動,15 秒沒撿會消失。 ## 精英房通則(走動關中段) diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index 6ea396504..ead6de315 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:reward-starpuff-t7c-cross-doc-drift-sweep +- 原因:交叉核對發現漂移不只 GAME_DESIGN——WALKTHROUGH 與 app README 仍寫「慈悲愛心隨機出現」「長按 0.6 秒變身」「主選單按鈕配置」,且五座魔王攻略未涵蓋 v21–v23 加權選招與六個主題招式 +- 解法:小漂移直接修(WALKTHROUGH 慈悲 pity/設定頁/版本落後聲明,README 變身觸發面/星暴 2.0/EX 五王 P4/設定頁/成就),大缺口開 issue 不擅改——#874 魔王主題招式需真機實測補寫、#875 六模組註解誤引 §5、#876 gitignored PRD 的 35%/60% 與 sp-rotation 漂移待 PM 裁決 + - 日期:2026-07-26 - ID:reward-starpuff-t7c-game-design-topic-split - 原因:GAME_DESIGN.md 膨脹至 2436 行 118 章、以版本列車時序堆疊並靠「對舊章加取代標註」維護,讀者無法判斷哪一段現行有效,也無法憑主題定位(T7-C) From a0b30a57be10e8ee77d375ccaccf51cd78004eac Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 10:02:46 +0800 Subject: [PATCH 05/14] =?UTF-8?q?docs(starpuff):=20=E8=A3=9C=E5=BB=BA=20T7?= =?UTF-8?q?-C=20=E6=96=87=E4=BB=B6=E4=BF=AE=E6=AD=A3=20changeset=EF=BC=88p?= =?UTF-8?q?atch=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 依 AGT-VER-01 與 docs-only patch 先例補建 changeset,描述玩家可見的說明錯誤修正 - 002 新增 neutral 條目並更新記分行計數(reward 3、neutral 1,本 PR 淨 +3) 測試:prettier 3.8.1 通過;純文件與 changeset 變更,無行為影響故未跑 vitest Co-authored-by: Cursor --- .changeset/starpuff-t7c-design-doc-split.md | 5 +++++ docs/dev/002_development_reward_penalty_log.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/starpuff-t7c-design-doc-split.md diff --git a/.changeset/starpuff-t7c-design-doc-split.md b/.changeset/starpuff-t7c-design-doc-split.md new file mode 100644 index 000000000..e11fcd1d9 --- /dev/null +++ b/.changeset/starpuff-t7c-design-doc-split.md @@ -0,0 +1,5 @@ +--- +'@app/starpuff': patch +--- + +修正說明文件與實際玩法不符之處:星化變身改為按 SP 情境鍵(非長按吸入鍵 0.6 秒)、慈悲補血愛心為保底計數而非隨機出現、主選單「按鈕配置」已改為「設定」入口,並補上星暴 2.0、EX 五王第四型態與成就系統說明;設計 SPEC 依主題拆分為多份文件並新增取代對照表,查閱時可直接判斷哪一段規格仍然有效 diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index ead6de315..e20c1a299 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:neutral-starpuff-t7c-docs-changeset +- 原因:AGT-VER-01 要求每個 PR 建 changeset;本 PR 為純文件但含使用者可見的錯誤指示修正(變身觸發面/慈悲補血/設定入口),需依 bfdf65585 docs-only patch 先例補建 +- 解法:新增 patch changeset 描述玩家看得到的說明修正與設計文件可查性提升;純文件無行為變更故不升 minor + - 日期:2026-07-26 - ID:reward-starpuff-t7c-cross-doc-drift-sweep - 原因:交叉核對發現漂移不只 GAME_DESIGN——WALKTHROUGH 與 app README 仍寫「慈悲愛心隨機出現」「長按 0.6 秒變身」「主選單按鈕配置」,且五座魔王攻略未涵蓋 v21–v23 加權選招與六個主題招式 From 58455dfec6bbfd26d46ae02dbf55b472064d8eb2 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 11:00:03 +0800 Subject: [PATCH 06/14] =?UTF-8?q?docs(starpuff):=20=E5=8F=8D=E8=BD=89?= =?UTF-8?q?=E5=8F=96=E4=BB=A3=E6=A8=99=E8=A8=BB=E6=96=B9=E5=90=91=E2=80=94?= =?UTF-8?q?=E2=80=94=E4=B8=BB=E5=8F=A5=E4=B8=80=E5=BE=8B=E7=82=BA=E7=8F=BE?= =?UTF-8?q?=E8=A1=8C=E8=A6=8F=E5=89=87=EF=BC=88=E5=AF=A9=E6=9F=A5=E5=BF=85?= =?UTF-8?q?=E4=BF=AE=201=EF=BC=8F2=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 全 10 個設計檔主句改寫為現行有效規則,舊規則降級為 35 條「已廢止」附註 - 99-superseded 新增「主句紀律」章立為鐵律,索引同步聲明,附註格式固定可 grep - 01 檔頭收窄職責為「輸入+與輸入直接連動的彈匣/蓄能狀態機」並說明為何不拆 §109.3 - 02 檔頭加星暴指路(現行規格在 §109.3),§63.1 歷史表 60% 去粗體並標 v9 限定 - 99 補回 §43 原引導句;002 新增 reward 條目 測試:prettier 3.8.1 通過;grep 抽驗 854×480/HP 70/168±14/35%/60% 等舊值全數 仍保留於附註內未遺失;純文件變更未跑 vitest Co-authored-by: Cursor --- apps/starpuff/docs/GAME_DESIGN.md | 7 + apps/starpuff/docs/WALKTHROUGH.md | 6 +- apps/starpuff/docs/design/00-foundations.md | 13 +- .../starpuff/docs/design/01-controls-input.md | 88 ++++++---- apps/starpuff/docs/design/02-combat-star.md | 51 ++++-- .../starpuff/docs/design/03-enemies-bosses.md | 161 ++++++++++-------- apps/starpuff/docs/design/04-levels-world.md | 21 ++- apps/starpuff/docs/design/05-save-settings.md | 16 +- apps/starpuff/docs/design/06-ui-shell-pwa.md | 21 ++- apps/starpuff/docs/design/07-art-audio-fx.md | 6 +- apps/starpuff/docs/design/08-safety-nets.md | 7 +- apps/starpuff/docs/design/99-superseded.md | 20 ++- .../dev/002_development_reward_penalty_log.md | 5 + 13 files changed, 277 insertions(+), 145 deletions(-) diff --git a/apps/starpuff/docs/GAME_DESIGN.md b/apps/starpuff/docs/GAME_DESIGN.md index a8745a95b..287201e8d 100644 --- a/apps/starpuff/docs/GAME_DESIGN.md +++ b/apps/starpuff/docs/GAME_DESIGN.md @@ -14,6 +14,13 @@ 的取代對照表,它逐條列出被取代的敘述與現行規則位置。 - **要玩/要驗收** → 全 20 關實測攻略見 [`WALKTHROUGH.md`](WALKTHROUGH.md)。 +### 主句紀律(MUST) + +各主題檔中**每一句主文都是現行有效規則**;被取代的舊規則一律降級為緊接其後的 +`> **已廢止**(<版本> 起,現行見 §<章號>):<舊敘述>` 附註。所以你可以放心直接讀主句, +不必擔心括號裡藏著「其實這條已經改了」。全量對照見 +[`design/99-superseded.md`](design/99-superseded.md)。 + ### 章號紀律(MUST) 章號 §N 是全專案穩定識別碼——`src/**` 程式註解、測試 describe 名稱與 issue 都直接引用。 diff --git a/apps/starpuff/docs/WALKTHROUGH.md b/apps/starpuff/docs/WALKTHROUGH.md index 410f3ef1d..1b816dace 100644 --- a/apps/starpuff/docs/WALKTHROUGH.md +++ b/apps/starpuff/docs/WALKTHROUGH.md @@ -38,10 +38,12 @@ - 走動關死亡重試當前關(配額歸零重算;例外:L1 教學關死亡保留一半擊殺配額); 卡點關(L11/L15/L19)越過中點後死亡自 checkpoint 就地重生, 配額與計時保留。魔王關死亡進敗北結算,按重試自前室重來。 -- 慈悲補血:血量剩 1 顆心且久戰時,場上會出現愛心(每命最多 2 次,EX 1 次)——瀕死時留意撿取。 +- 慈悲補血:**低血**(走動關 HP ≤1/魔王房 HP ≤2)**且久戰**(走動關 ≥60 秒/魔王房 ≥12 秒) + 時,愛心會**必定出現**(每命最多 2 次,EX 1 次)——瀕死時留意撿取。 **不是抽獎**(v19 起改保底計數):門檻到齊後第一顆固定會出;之後要再撐到「又被打 2 下」 或「低血硬撐 30 秒」(魔王房 15 秒)才會補下一顆,所以低血狀態撐久不會白費。 - 出現位置在你身邊 ±120–240px,空中緩降或地面浮動,15 秒沒撿會消失。 + 另有冷卻(走動關 45 秒/魔王房 18 秒)。出現位置在你身邊 ±120–240px, + 空中緩降或地面浮動,15 秒沒撿會消失。 ## 精英房通則(走動關中段) diff --git a/apps/starpuff/docs/design/00-foundations.md b/apps/starpuff/docs/design/00-foundations.md index db0e7019c..ea7c051ed 100644 --- a/apps/starpuff/docs/design/00-foundations.md +++ b/apps/starpuff/docs/design/00-foundations.md @@ -4,11 +4,14 @@ > > **不在本檔**:任何玩法數值與機制規格。操作與輸入見 `01-controls-input.md`;星彈與變身見 `02-combat-star.md`;怪物與魔王見 `03-enemies-bosses.md`;關卡與世界地圖見 `04-levels-world.md`。 > -> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 +> **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 ## 1. 產品定位 -- 橫式(landscape)四關側向卷軸動作遊戲:三關走動探索 + 魔王關(Boss Rush 收尾),單局 2–4 分鐘,可無限重玩。(v8 已由 §50 取代:七關雙魔王;v9 已由 §60 取代:九關——七關走動探索+兩座魔王關+雙 EX 變體。) +- 橫式(landscape)側向卷軸動作遊戲:**五區二十關**——十五關走動探索+五座魔王關(各王另有 EX 變體),單關 2–4 分鐘,可無限重玩。關卡編成見 §84。 + +> **已廢止**(v8→v12 逐版擴充,現行見 §84):四關制(三關走動+一座魔王 Boss Rush 收尾);其後 v8 七關雙魔王、v9 九關、v10 十二關、v11 十六關均為過渡值。 + - 原創 IP:主角與怪物皆為原創設計(果凍星球世界觀),嚴禁使用任天堂卡比之名稱、造型、配色構圖。 - 目標體驗:Q 彈、可愛、爽快——大量擠壓拉伸、粒子、震屏、音效回饋。 @@ -18,9 +21,11 @@ ## 3. 場景流程 -`BootScene`(載入+進度條)→ `TitleScene`(標題、開始按鈕、音效提示)→ `MapScene`(v6 世界地圖 hub,§39)→ `GameScene`(四關制)(v8 已由 §50 取代:七關流程;v9 已由 §60 取代:九關流程)→ `ResultScene`(勝/敗)。 +`BootScene`(載入+進度條)→ `TitleScene`(標題、開始按鈕、設定入口)→ `MapScene`(世界地圖 hub,五區分頁,§39/§78)→ `GameScene`(二十關,§84)→ `ResultScene`(勝/敗);L20 全破先經 `CreditsScene` 謝幕再進結算(§84)。 + +單關流程:自世界地圖節點進關 → 走動關側向卷軸(擊殺配額達成 → 星星門開啟 → 走入過關)/魔王關(前室補給廊道 §69 → 入場運鏡 → Boss 戰,期間補生可吸小怪供彈藥)→ 勝利星爆 / 敗北。過關**寫入存檔後自動回世界地圖揭霧**(§39),自節點進下一關或重玩;魔王關勝利結算另有「下一關」主 CTA(§100)。死亡處理:走動關重試當前關(卡點關自 checkpoint 就地重生 §67);魔王關進敗北結算(EX 與部分終段走段起點重試 §82/§114.4)。關卡資料驅動細節見 §15。 -四關制流程(v8 已由 §50 取代:七關流程——L1-L3 → L4 果凍王 → L5-L6 → L7 暗月蝠王):Title → Stage 1-3 側向卷軸(擊殺配額達成 → 星星門開啟 → 走入過關)→ Stage 4 魔王戰(入場動畫 → Boss 戰,期間補生可吸小怪供彈藥)→ 勝利星爆 / 敗北。死亡處理:Stage 1-3 重試當前關;魔王關進敗北結算。關卡資料驅動細節見 §15。(v6 已由 §39 取代直達下一關的轉場卡:過關寫入存檔後自動進世界地圖,自地圖節點進下一關或重玩。) +> **已廢止**(v6 起,現行見 §39):過關播全屏轉場卡直達下一關——轉場卡廢除,改世界地圖 hub。 ## 11. 技術架構 diff --git a/apps/starpuff/docs/design/01-controls-input.md b/apps/starpuff/docs/design/01-controls-input.md index b81950b61..12d98db1d 100644 --- a/apps/starpuff/docs/design/01-controls-input.md +++ b/apps/starpuff/docs/design/01-controls-input.md @@ -1,26 +1,36 @@ # 星噗噗 — 操作、輸入與虛擬鍵布局 -> **職責範圍**:玩家怎麼操作遊戲。搖桿與 A/B/SP 鍵語意、跳躍與下衝擊輸入矩陣、觸控寬容度與真實手勢判定、走動與移動手感、直持旋轉殼與座標換算,以及虛擬鍵布局 SSOT 與按鈕配置頁。 +> **職責範圍**:玩家怎麼操作遊戲,**以及與輸入直接連動的彈匣/蓄能狀態機**。搖桿與 A/B/SP 鍵語意、跳躍與下衝擊輸入矩陣、觸控寬容度與真實手勢判定、走動與移動手感、直持旋轉殼與座標換算、虛擬鍵布局 SSOT 與按鈕配置頁,以及星暴 2.0 的滿匣結晶與蓄能星生命週期(§109.3)。 > -> **不在本檔**:按下之後發生什麼事——星彈與技能效果見 `02-combat-star.md`;暫停選單、主選單、HUD 命中層見 `06-ui-shell-pwa.md`;偏好如何持久化見 `05-save-settings.md`。 +> **為什麼星暴狀態機在這裡**:SP 情境鍵的裁決(`resolveSpPress`:解除/引爆/變身)必須讀蓄能星相位才能決定按下去會發生什麼——把相位機拆去 `02` 會讓同一個狀態機有兩個 SSOT,正是本次拆檔要消滅的漂移。星暴的**世界結算效果**(清場、魔王傷、無敵窗)仍歸 `02-combat-star.md` 與 §64.2。 +> +> **不在本檔**:按下之後的戰鬥結算——星彈屬性、混合星、變身能力表見 `02-combat-star.md`;暫停選單、主選單、HUD 命中層見 `06-ui-shell-pwa.md`;偏好如何持久化見 `05-save-settings.md`。 > > **現行輸入 SSOT = §109**(B 鍵三語意+SP 情境鍵);§23/§57 的長按觸發面已退場。 > -> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 +> **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 ## 4. 操作(行動裝置優先) - 左半屏:浮動搖桿(觸點即中心、半徑 60px、死區 12px;水平移動 + 下向偵測供下衝擊,規格見 §21)。 -- 右側:A/B 圖形圓鍵(斜排布局 v5 已由 §34 取代:B 移右側偏上食指區、位置可自訂)——A 跳躍(空中連按=拍翅漂浮,最多 3 次,落地重置);B 吸/射(無彈藥=按住吸入;有彈藥=點按發射,長按仍可吸)。 -- 鍵盤(桌機備援):←→ / Z 跳 / X 吸射。 +- 右側:A/B 圖形圓鍵(B 位於右側偏上食指區、位置可自訂,§34;技能可用時 B 上方浮現 SP 情境鍵,§109.2)——A 跳躍(空中連按=拍翅漂浮,最多 3 次,落地重置);B 吸/射(三語意見 §109.1)。 + +> **已廢止**(v5 起,現行見 §34):A/B 斜排布局(B 在 A 左上 45 度)、位置不可自訂。 + +- 鍵盤(桌機備援):←→ / Z 跳 / X 吸射 / C 特殊技(SP,§109.2)。 - 全域:`touch-action: none`、禁雙擊縮放、首次觸控解鎖 AudioContext。 ## 21. v3 橫式轉向(PM 親撰) -- 邏輯畫布 854×480(橫式),Scale.FIT + CENTER_BOTH;manifest orientation 改 landscape(v4 已由 §28 免轉向旋轉殼取代:manifest 不鎖 orientation);直向持機時顯示「請轉橫」遮罩(v4 已由 §28 免轉向旋轉殼取代:遮罩廢除)。 +- 邏輯畫布高 480、寬 854–1200 動態(§28 響應寬幅),Scale.FIT + NO_CENTER 由旋轉殼定位;manifest **不鎖** orientation;直向持機走 CSS 旋轉殼直接呈現橫式(§28 免轉向)。 + +> **已廢止**(v4 起,現行見 §28):固定 854×480 + CENTER_BOTH、manifest orientation 鎖 landscape、直向持機顯示「請轉橫」遮罩(遮罩廢除)。 + - 世界尺寸:高 480;寬放大至 S1 2700 / S2 3100 / S3 3500(視野變寬 1.78 倍,維持等效走動時長);平台改雙層以內(天花板變低),高度差以跳躍 -420 可達為準。 - HUD 重排:頂列橫排——HP 心心左上、STAGE 標示中上、配額右上;Boss 條頂中置。全部 HUD 圖示改 graphics 繪製(星形/心形程序化),全遊戲禁用 emoji 與文字字元鍵帽。 -- 虛擬手柄(參考實體手柄配置):左側浮動搖桿(觸點即中心、半徑 60px、死區 12px、水平為主 + 下向偵測供下衝擊);右側 A(跳,右下)/ B(吸/射,A 左上 45 度)雙鍵 64px+ 斜排、間距 16px+(v5 已由 §34 取代:B 移右側偏上食指區、支援拖曳自訂布局);橫持 iPhone safe-area 側邊 inset 必須套用。按鍵一律 canvas/CSS 繪製圖形(無文字節點)。 +- 虛擬手柄(參考實體手柄配置):左側浮動搖桿(觸點即中心、半徑 60px、死區 12px、水平為主 + 下向偵測供下衝擊);右側 A(跳,右下拇指帶)/ B(吸/射,右側偏上食指區),布局可拖曳自訂與縮放(§34/§89);橫持 iPhone safe-area 側邊 inset 必須套用。按鍵一律 canvas/CSS 繪製圖形(無文字節點)。 + +> **已廢止**(v5 起,現行見 §34):A/B 雙鍵 64px+ 斜排、間距 16px+、B 固定在 A 左上 45 度、布局不可自訂。 ## 22. iOS 觸控直通(研究回寫後定稿) @@ -30,16 +40,24 @@ ## 28. v4 免轉向橫式與響應寬幅(PM 親撰) -- 免轉向:偵測 portrait viewport 時,以 CSS 旋轉容器方案將整個遊戲容器(canvas + DOM 控制層)旋轉 90 度呈現橫式——使用者直持手機即玩,不再顯示轉橫遮罩(遮罩廢除)。技術定案依調研回寫(Phaser 4 相容性、pointer 座標映射、safe-area 換軸)。(v14 已由 §87 取代預設旋轉方向:預設 ccw(rotate -90deg、鏡頭朝右),cw 舊方向降為可切換偏好。) +- 免轉向:偵測 portrait viewport 時,以 CSS 旋轉容器方案將整個遊戲容器(canvas + DOM 控制層)旋轉 90 度呈現橫式——使用者直持手機即玩,不再顯示轉橫遮罩(遮罩廢除)。**預設方向 ccw**(rotate -90deg、鏡頭朝右,§87);cw 為可切換偏好。技術定案依調研回寫(Phaser 4 相容性、pointer 座標映射、safe-area 換軸)。 + +> **已廢止**(v14 起,現行見 §87):預設方向為 cw(rotate 90deg、鏡頭朝左)。 + - 響應寬幅:邏輯高固定 480,寬依裝置比例擴展(下限 854、上限 1200);Scale 模式依調研定案(EXPAND/RESIZE 擇一)。HUD 錨定鏡頭邊緣自適應;世界生成邊距、星星門偵測、boss 單屏佈局以動態視寬計算,禁止硬編 854。 - 驗收基準機型:390×844(iPhone 13 直持)、430×932(Pro Max 直持)、844×390(橫持)三態皆可玩。 ## 34. v5 控制布局重設計與按鈕自訂 - 人體工學定案(§33 條目 7):雙手橫持時拇指錨於下側角、食指自然落在裝置上緣——A 跳躍維持右下(拇指連打),B 吸/射移至右側偏上(食指按壓;與 A 垂直遠離杜絕誤觸);方向搖桿維持左半屏。 -- 布局 SSOT:`core/layout.ts`——按鍵中心以 keys-layer 安全區內比例(cx/cy 0-1)表示,直橫持共用;`DEFAULT_LAYOUT`:A (0.92, 0.78)、B (0.92, 0.34)。(v16 已由 §95 取代「預設」的直持適用性:預設依殼旋轉態分流 `defaultLayoutFor`,直持採右下拇指帶錨點;自訂布局仍直橫持共用。) +- 布局 SSOT:`core/layout.ts`——按鍵中心以 keys-layer 安全區內比例(cx/cy 0-1)表示;**預設依殼旋轉態分流** `defaultLayoutFor`(直持採右下拇指帶錨點,§95),自訂布局仍直橫持共用。橫持 `DEFAULT_LAYOUT`:A (0.92, 0.78)、B (0.92, 0.34)。 + +> **已廢止**(v16 起,現行見 §95):預設鍵位直橫持共用同一組比例——該組比例在直持旋轉殼下會把 A/B 映射到裝置頂端(實測 A 裝置 fy≈0.09),雙拇指不可及。 + - `#keys-layer`:安全區內鋪滿的定位容器(四向 `max()` 地板+portrait 換軸表),按鍵以 `left/top %` + `translate(-50%,-50%)` 定位。 -- 按鈕自訂(KISS:拖曳+儲存+重置,不做進階編輯器)(v19 已由 §118.1/§118.2 取代入口與儲存位置:入口自 Title 直鈕改為設定頁轉入,布局改存 `sp-settings.keyLayout`,`sp-key-layout` 僅作 migration 來源):Title「按鈕配置」→ `systems/keyConfig.ts` DOM 覆層——直接拖曳真實 A/B 鍵即時預覽,「儲存並返回」寫入 localStorage `sp-key-layout`(schema `{version:1, a:{cx,cy}, b:{cx,cy}}`;版本不符/損毀回退預設),「恢復預設」一鍵還原。拖曳座標經 `pointerToLocal` 換軸,夾限 `KEY_CLAMP` 保證按鍵完整在畫面內。(v14 已由 §88/§89 取代操作列結構與 schema:schema 升 v2 增全域縮放、操作列直欄化並增持向切換與縮放列。) +- 按鈕自訂(KISS:拖曳+儲存+重置,不做進階編輯器):**Title「設定」→「按鈕配置」轉入**(§118.2)→ `systems/keyConfig.ts` DOM 覆層——直接拖曳真實 A/B 鍵即時預覽,「儲存」寫入 `sp-settings.keyLayout`(schema v2 `{version:2, a:{cx,cy}, b:{cx,cy}, scale}`;版本不符/損毀回退預設,§89),「恢復預設」一鍵還原。操作列直欄化(提示列+操作列+縮放列,§88)。拖曳座標經 `pointerToLocal` 換軸,夾限 `KEY_CLAMP` 保證按鍵完整在畫面內。 + +> **已廢止**(v14/v19 起,現行見 §88/§89/§118.1):Title 直接掛「按鈕配置」鈕;橫排操作列與「儲存並返回」標籤;schema v1 `{version:1, a, b}`;獨立 localStorage 鍵 `sp-key-layout`(僅存留為一次性 migration 來源)。 ## 41. v6 移動手感打磨(logic/movement.ts,pure TS 可測) @@ -55,10 +73,9 @@ 衝擊波傷害 2、CD 1.2s、零彈藥消耗、可破磚)。 - 空中疾衝(§30 Air Dash)整體移除:雙擊 A 與拍翅節奏衝突且誤觸率高;相關輸入、 純邏輯、殘影 fx、音效、圖鑑條目與測試全數清除(movement 夾速鏈保留供擊退殘速)。 -- 跳躍鍵輸入矩陣(`logic/skills.ts` `resolveJumpPress`,pure TS 可測): - -(v10.1 已由 §71.1 補訂:「空中」判定收斂為真空中——coyote 窗內視同在地不觸發下砸; -地面主地面下+跳自 §71.2 起帶蹲姿視覺,跳躍裁決不變。) +- 跳躍鍵輸入矩陣(`logic/skills.ts` `resolveJumpPress`,pure TS 可測)。「空中」= + **真空中**(coyote 窗內視同在地,不觸發下砸,§71.1);地面主地面下+跳帶蹲姿視覺 + (§71.2),跳躍裁決不變。下向判定吃 drop-intent 緩衝窗(§85.2),空中下砸維持即時 down: | 情境 | 下 | 跳 | 裁決 | | -------------- | --- | --- | --------------------------------------------------------------------------------- | @@ -118,9 +135,12 @@ **修法**(四點聯動,均有單測): -- 落地擠壓加最低著地速度閘 `LANDING_SQUASH_MIN_VY=120`:微速重新接觸不再擠壓, - 迴圈斷根(實測站立接觸穩定度 120/120 步)。**已退場(§117 根治)**:解耦後擠壓 - 不再縮物理箱,門檻無存在必要。 +- 落地擠壓迴圈已由 §117 visualScale 通道**架構級根治**:物理箱永不隨美術縮放,任意 + 著地速度皆可安全觸發擠壓,無需速度閘。 + +> **已廢止**(v19 §117 起):最低著地速度閘 `LANDING_SQUASH_MIN_VY=120`(微速重新接觸 +> 不再擠壓,實測站立接觸穩定度 120/120 步)——單案例補丁,解耦後無存在必要,已刪除。 + - `resolveJumpPress` 增 `recentlyGroundedMs`(傳 coyote 殘量):coyote 窗內視同在地, 下砸僅「真空中」(離地 >150ms)觸發——§44 矩陣「空中」行語意收斂為真空中。 - 站台判定抽 `stageModel.restingOnOneWay` 純函式:接觸旗標**或**沉降幾何 @@ -206,11 +226,12 @@ - CSS:預設殼 `top:100%; left:0; rotate(-90deg)`(ccw);`html.sp-rot-cw` 切回 舊方向。safe-area 換軸表雙套:ccw=裝置 left→殼上、top→殼右、right→殼下、 bottom→殼左;cw 維持 v4 原表。 -- 偏好持久化:localStorage `sp-rotation`('cw'|'ccw',缺省=ccw 新預設; - 不進 save schema);讀取走記憶體快取(pointer 熱路徑不重複讀 storage)。 - (v19 已由 §118.1 取代儲存位置:收斂為 `sp-settings.shellRotation`, - `null`=從未選擇;`sp-rotation` 僅作一次性 migration 來源,落盤後刪除。 - 記憶體快取語意不變。) +- 偏好持久化:`sp-settings.shellRotation`('cw'|'ccw'|`null`;`null`=從未選擇, + 供 §87.2 一次性告知判定,實際套用缺省=ccw 新預設。不進 save schema,§118.1); + 讀取走記憶體快取(pointer 熱路徑不重複讀 storage)。 + +> **已廢止**(v19 起,現行見 §118.1):獨立 localStorage 鍵 `sp-rotation`——僅存留為 +> 一次性 migration 來源,落盤成功後刪除。 ### 87.2 回訪玩家保護(肌肉記憶) @@ -218,8 +239,8 @@ `sp-settings.shellRotation === null`)首次進站於 Title 顯示一次性 方向告知卡(§92 殼層卡片):說明新方向並提供「切回舊方向」一鍵; 已示記憶 localStorage `sp-rotation-notice`。全新玩家無感知不打擾。 -- 持向切換入口常駐「按鈕配置」操作列(§88),納入草稿語意:切換即時預覽、 - 儲存才落地、取消回滾。 +- 持向切換入口常駐「按鈕配置」操作列(§88,自設定頁轉入),納入草稿語意:切換即時 + 預覽、儲存才落地、取消回滾。 ### 87.3 驗證 @@ -252,10 +273,13 @@ ## 89. v14 虛擬鍵大小自訂(sp-key-layout schema v2) -- schema v1→v2 versioned migration:v1 舊存檔鍵位保留、`scale` 補預設 1; +- schema v1→v2 versioned migration:v1 舊布局鍵位保留、`scale` 補預設 1; 未知版本回退預設。v2:`{version:2, a, b, scale}`,scale 夾限 0.8–1.3。 - (v19 已由 §118.1 取代儲存位置:**schema 形狀不變**,改存於 - `sp-settings.keyLayout` 子樹;`sp-key-layout` 僅作一次性 migration 來源。) + **儲存位置=`sp-settings.keyLayout` 子樹**(§118.1;schema 形狀不變)。 + +> **已廢止**(v19 起,現行見 §118.1):獨立 localStorage 鍵 `sp-key-layout`——僅存留為 +> 一次性 migration 來源,落盤成功後刪除。 + - 縮放經 CSS 變數 `--sp-key-scale` 單點驅動鍵體與鍵帽(clip-path 圖形同步), 觸控熱區隨元素幾何自然同步;`KEY_BASE_PX`(A76/B72)與 style.css 以單測 跨檔守門防雙寫漂移。 @@ -282,10 +306,12 @@ ### 95.2 儲存語意(配置頁) -- 預設態不落盤:從未自訂或按過「恢復預設」後儲存=清除布局(v19 §118.1: - `sp-settings.keyLayout` 置 null,v14–v18 為清除 `sp-key-layout` 鍵,語意等價), - 直橫持各自動態解析預設;拖曳/縮放屬自訂,儲存持久化具體布局(維持 v14 - 單一共用布局語意)。 +- 預設態不落盤:從未自訂或按過「恢復預設」後儲存=`sp-settings.keyLayout` 置 null + (§118.1),直橫持各自動態解析預設;拖曳/縮放屬自訂,儲存持久化具體布局 + (維持 v14 單一共用布局語意)。 + +> **已廢止**(v19 起,語意等價):v14–v18 的預設態不落盤實作為刪除 `sp-key-layout` 鍵。 + - 「恢復預設」依當前草稿持向給對的錨點;持向切換(cw/ccw)時預設態即時重映射, 自訂布局不動;拖曳逆變換取草稿持向(修正切換未儲存期間軸向錯置)。 - 局中轉向重套:controls 進場後監聽 resize(200ms)/orientationchange(400ms) diff --git a/apps/starpuff/docs/design/02-combat-star.md b/apps/starpuff/docs/design/02-combat-star.md index 28b550ee9..955b118a1 100644 --- a/apps/starpuff/docs/design/02-combat-star.md +++ b/apps/starpuff/docs/design/02-combat-star.md @@ -6,18 +6,22 @@ > > **硬不變式**:混合星與變身**永不為破關必需**——基礎星彈恆可通關(§46/§57/§110)。 > -> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 +> **星暴現行規格=§109.3**(`01-controls-input.md`):滿 5 槽自動結晶為蓄能星、按 SP 引爆。本檔 §23/§40 內的星暴敘述均為 v19 前的歷史值。 +> +> **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 ## 7. 戰鬥數值 - 玩家:移速 220px/s、跳躍初速 -420、漂浮升力 -260、重力 900。 - 吸入:長按 ≥150ms 啟動、錐形範圍 140px、拉力漸增;吞下 +1 彈藥(上限 5,v19 §109)。 - 星彈:傷害 5、速度 520、穿透 1 隻小怪、命中魔王消失。 -- 邏輯畫布:854×480(橫式,Scale.FIT;v4 改 NO_CENTER 由旋轉殼定位,見 §28);解析度採 Scale.FIT 自適應,不做 DPR cap(欄位已於修復包 B 移除)。 +- 邏輯畫布:高固定 480,寬依裝置比例擴展(下限 854、上限 1200,§28 響應寬幅——**禁硬編 854**);Scale.FIT + NO_CENTER 由旋轉殼定位,不做 DPR cap。 + +> **已廢止**(v4 起,現行見 §28):固定 854×480 + CENTER_BOTH;DPR cap 欄位已於修復包 B 移除。 ## 20. 技能系統:吞噬賦星(v2.1,PM 親撰) -吞下的怪決定星彈屬性(最後吞下者覆蓋既有彈藥屬性),表驅動實作(config 一張表,禁止散落分支)(v6 已由 §40 擴充為五系:shelly 殼盾星、zappy 雷鏈星,取代 v4 的標準星/疾風星代位): +吞下的怪決定星彈屬性(最後吞下者覆蓋既有彈藥屬性),表驅動實作(config 一張表,禁止散落分支)。**現行為九系**(§40 增殼盾/雷鏈、§47 增重鑽/流光、§53 增孢子/迴旋);下表為 v2.1 首發三系,仍是現行九系的子集: | 吞下 | 星彈屬性 | 效果 | 視覺 | | ------ | -------- | ----------------------------------- | ------------------------------- | @@ -33,8 +37,14 @@ - 三屬性沿用 §20;新增連鎖規則: - 同種連吞 ×2:該槽升級為強化星(傷害 ×1.6、尺寸 ×1.4、pitch -15%、金邊 tint)。 - - 彈匣全滿長按 B 0.8s:星暴大招——清場全部小怪 + 魔王 12 傷,震屏 + 白閃 + 星雨粒子,清空彈匣。(v9.1 已由 §64.2 補訂:發動附 5s 無敵窗,與受擊 i-frame 取較大值不疊加。)(v19 已由 §109 取代:滿匣自動結晶+SP 鍵手動引爆,B 長按星暴路徑退場。) - - 空中搖桿下 + B:下衝擊(v7 已由 §44 取代:改為空中搖桿下+跳躍鍵,B 鍵回歸純吸/射語意)。 + - 彈匣滿 5 槽瞬間**自動結晶**為蓄能星,按 SP 鍵引爆星暴——清場全部小怪 + 魔王 12 傷 + 5s 無敵窗(與受擊 i-frame 取較大值不疊加,§64.2),震屏 + 白閃 + 星雨粒子。完整規格見 §109.3。 + +> **已廢止**(v19 起,現行見 §109.3):彈匣全滿長按 B 0.8s 發動星暴——B 長按星暴路徑因誤觸清匣(#812)整體退場。 + +- 下衝擊:真空中「搖桿下+跳躍鍵(A)」觸發(§44 輸入矩陣)。 + +> **已廢止**(v7 起,現行見 §44):空中搖桿下+B 觸發下衝擊——B 鍵回歸純吸/射語意。 + - 彈匣槽各自帶 flavor 與強化態,後進先出發射;HUD 槽位顯示屬性色 + 強化金邊。 ## 40. v6 新技能:殼盾與雷鏈(PM 原創,補防禦與群戰原型) @@ -46,7 +56,10 @@ | shelly | 殼盾星 | 直射傷害 5、速度 480、穿透 0;頂槽時長按=舉盾(見下) | 青綠 tint #7FD8C8 | | zappy | 雷鏈星 | 直射傷害 5、速度 585、穿透 0;命中後跳電至 160px 內最近 2 敵、各 3 電傷 | 電黃 tint #FFE28A、折線閃電 | -- 殼盾(防禦原型):頂槽殼盾星且未滿匣時,長按 B ≥150ms 舉正面護盾(取代吸入語意;滿匣長按維持星暴優先,肌肉記憶不變)。格擋彈幕/接觸一次:不掉血不擊退、消耗頂槽、觸發反擊星爆(盾前 90px 傷害 3)+短無敵 0.8s,冷卻 4s。正面判定=傷害來源位於面向側(同 x 視為正面)。點按仍為發射。(v19 已由 §109 補訂:長按星暴退場,頂槽殼盾星即成立殼盾情境——滿匣不再讓位。) +- 殼盾(防禦原型):**頂槽為殼盾星時**長按 B ≥150ms 舉正面護盾(取代吸入語意;長按星暴已退場,滿匣不再讓位)。格擋彈幕/接觸一次:不掉血不擊退、消耗頂槽、觸發反擊星爆(盾前 90px 傷害 3)+短無敵 0.8s,冷卻 4s。正面判定=傷害來源位於面向側(同 x 視為正面)。點按仍為發射(殼盾情境走延遲:放開 <150ms 結算為點按發射,§109.1)。 + +> **已廢止**(v19 起,現行見 §109.1):舉盾附「且未滿匣」條件、滿匣長按讓位給星暴。 + - 雷鏈(群戰清場原型):命中主目標後由近至遠跳電(主目標排除、折線閃電演出+burstSmall);命中魔王同樣跳電波及補給小怪(v4 多平台混戰場景受益)。 - 純邏輯 SSOT:`logic/skills.ts`(`advanceShield`/`resolveShieldBlock`/`isFrontalHit`/`pickChainTargets`)+ `STAR_FLAVORS` chain 欄位(core/config.ts),vitest 全蓋。 - 事件契約增列:`skill:shield-block`(player 發出,GameScene 結算反擊星爆)。 @@ -101,17 +114,23 @@ ## 57. v9 星化變身系統(logic/transform.ts 純狀態機,表驅動) - 觸發:彈匣內同系可變身星彈合計 ≥3 發(強化槽為連吞兩發合成、計 2 發;金星/混合槽 - 破壞資格)時 HUD 彈藥列脈動亮起變身提示;**地面**長按吸入鍵 0.6s 觸發(吸入拉怪 - 進行中與空中不可起手;不新增實體按鍵)。消耗全部彈匣進入形態,持續 10s(玩家頭頂 - 倒數環),到時自動解除;再長按 0.6s 提前解除(不返彈)。 - (v19 已由 §109 取代觸發面:改 SP 鍵點按立即變身/再按提前解除,0.6s 長按門檻 - 廢除;資格條件與形態語彙不變。) -- 語意讓位(輸入矩陣,`resolveActionPress`/`resolveTransformHold`):同系 ≥3 星情境 - 長按=星化(優先於星暴與殼盾);非同系滿匣長按維持星暴;頂槽殼盾星未滿匣維持舉盾; - 點按放開(<150ms)仍發射。變身期間吸入停用(B 鍵改役),星暴/殼盾不充能。 - (v19 已由 §109 取代:長按讓位矩陣退場,SP 天然互斥裁決見 `resolveSpPress`。) + 破壞資格)時 HUD 彈藥列脈動亮起變身提示,SP 情境鍵浮現;**地面**按 SP 鍵**點按** + 立即變身(空中不可起手;裁決見 §109.2 `resolveSpPress`)。消耗全部彈匣進入形態, + 持續 10s(玩家頭頂倒數環),到時自動解除;**再按 SP 提前解除**(不返彈)。 + +> **已廢止**(v19 起,現行見 §109.2):地面長按吸入鍵 0.6s 觸發、再長按 0.6s 提前解除。 +> 0.6s 長按門檻整體廢除;資格條件與形態語彙不變。 + +- 互斥語意:SP 情境鍵天然互斥(變身中=解除 → 有蓄能星=引爆 → 否則=變身,§109.2 + `resolveSpPress`);B 鍵維持三語意不參與變身。變身期間吸入停用(B 鍵改役), + 星暴/殼盾不充能。 + +> **已廢止**(v19 起,現行見 §109):長按讓位矩陣(`resolveTransformHold`/同系 ≥3 +> 長按優先於星暴與殼盾/非同系滿匣長按維持星暴)——長按語意面整體退場。 + - 三形態(各改變 移動+攻擊+防禦 至少兩項;zappy→雷化、floaty/gusty 味→風化、 - shelly→殼化)(v20 已由 §110 加深:每形態補齊 攻/防/機動 三語彙,下表為 v9 基線): + shelly→殼化)。**現行能力表見 §110.1**(v20 每形態補齊 攻/防/機動 三語彙); + 下表為 v9 基線,仍是現行語彙的子集: | 形態 | 移動 | 攻擊 | 防禦 | | -------------- | ----------------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | diff --git a/apps/starpuff/docs/design/03-enemies-bosses.md b/apps/starpuff/docs/design/03-enemies-bosses.md index 272959e5b..8d7eec237 100644 --- a/apps/starpuff/docs/design/03-enemies-bosses.md +++ b/apps/starpuff/docs/design/03-enemies-bosses.md @@ -6,7 +6,7 @@ > > **硬不變式**:魔王關須有多種可行破關策略;telegraph 窗 ≥600ms 為可讀性紅線,EX 差分只縮體不縮窗。 > -> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 +> **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 ## 5. 角色設定(全部原創) @@ -20,9 +20,12 @@ ## 6. 魔王 AI(有限狀態機,pure TS 可測) -(v21 已由 §111 取代:P1/P2 固定循環改 `JELLORD_MOVES` 加權表選招,招池與 telegraph 數值不變。) +**選招現行為加權表驅動**(`JELLORD_MOVES`,§111.1)——招池與 telegraph 數值即下列各項, +但出招序由權重+條件帶(HP 帶/距離帶)抽選,非固定循環;P2 起另有主題招式「果凍回彈」(§111.2)。 -- P1(HP > 50%)循環:`idle(1.2s) → jellyRain(5 顆拋物線彈) → idle → slam(跳起落地雙向地面震波) → idle → …` +> **已廢止**(v21 起,現行見 §111):P1/P2 依固定循環出招(可背板)。 + +- P1(HP > 50%)招池:`idle(1.2s) → jellyRain(5 顆拋物線彈) → idle → slam(跳起落地雙向地面震波) → idle → …` - P2(HP ≤ 50%):變紅憤怒、速度 ×1.3,新增 `dash`(白閃三拍前搖 0.6s → 水平衝刺,牆邊回彈; #809 前搖 0.3s→0.6s 對齊 ≥600ms 衝撞可讀性紅線);jellyRain 升為 7 顆。 - 前室反制提示(#809):一次性浮字「被逼到角落?連按跳鍵拍翅可飛越魔王」——拍翅淨高 @@ -56,7 +59,7 @@ ≤60px 錐形豁免(停位貼腳死角);暈眩視覺=頭頂眩星公轉+殼體閃白脈動(與可吸窗 同生共滅);L2 首遇浮字教學。工具實測正確時機吞食 37%→73%(門檻 ≥60%)、 衝刺期 0% 不變(技巧性保留)。 - - 雷雷 Zappy:薰衣草黃電氣水母。緩慢懸浮追蹤,每 3s 放電環(半徑 70px、傷害 1、前搖 0.5s 閃爍預警)。可吸(吸入得疾風星)(v6 已由 §40 取代:吸入得雷鏈星)。HP 1。 + - 雷雷 Zappy:薰衣草黃電氣水母。緩慢懸浮追蹤,每 3s 放電環(半徑 70px、傷害 1、前搖 0.5s 閃爍預警)。可吸——**吸入得雷鏈星**(§40)。HP 1。(v6 前為疾風星代位。) - 魔王 P3(HP ≤ 25%):狂暴皇冠——rain 改追蹤彈 ×5(緩速跟蹤 2s 後直線)、slam 觸發全場單向平台震落效果(站立玩家強制彈起)、體色金紫閃爍;P3 進場演出:皇冠射出星環衝擊波 + 時停 0.3s。 - 關卡怪物組合更新:S2 加 shelly 15%、S3 加 zappy 15%(權重重配,可吸佔比維持 ≥50%)。 @@ -128,23 +131,34 @@ per-kind: scene。呈現層 `systems/noctra.ts` 與 boss.ts 共用 `BossHandle` 介面與 BOSS\_\* 事件契約 (GameScene 依 `level.boss` 品種擇一建立,HUD/fx/結算零分支)。 -- 數值:HP 70、身體傷害 1、P2 ≤60%、P3 ≤30%、狂暴節奏 ×1.25、每損 10 HP 掉補給小怪 - (§26 飢荒保證律不變——基礎星彈恆可通關)。(v9 已由 §63 難度根修取代:HP 52、 - 狂暴 ×1.15、每損 8 HP 補給;實測 0% 勝率歸因與全參數表見 §63。) -- 招式循環(表驅動 `noctraAttackCycle`;換階段循環游標重置)(v21 已由 §111 取代: - `noctraMoveTable` 加權表選招,循環游標敘述作廢;招池與 telegraph 數值不變): - - P1 `bomb(盤旋投彈 ×4,落點預警先行)→ dive(俯衝:telegraph+shake+變色前搖 -0.55s → 鎖定點撲擊 → 回升)` - - P2 `bomb ×5 → dive → dive(俯衝連擊)→ summon(召喚 floaty,場上上限 2——cap 由 -FSM 指令帶出、GameScene 依現量夾限走正式 spawn 管線)`(v9 已由 §63 取代:單 dive、 - bomb ×3) - - P3 `barrage(狂暴彈幕:全向放射彈環 ×10)→ sweep(全場俯掠:橫帶預警閃爍 0.6s 後 -貼 y=280 帶速掠全場,站立可躲)→ bomb` +- 數值:**HP 52**、身體傷害 1、P2 ≤60%、P3 ≤30%、**狂暴節奏 ×1.15**、**每損 8 HP** 掉補給 + 小怪(§26 飢荒保證律不變——基礎星彈恆可通關)。全參數表與 0% 勝率歸因見 §63。 + +> **已廢止**(v9 §63 難度根修起):HP 70、狂暴 ×1.25、每損 10 HP 補給——雙水準 bot 實測 +> 勝率皆 0%,保底線名存實亡。 + +- 招池(**加權表驅動** `noctraMoveTable`,§111.1;telegraph 數值不變,P2 起另有主題招式 + 「蝕月斗篷」§111.3): + - P1 `bomb(盤旋投彈 ×3,落點預警先行)`、`dive(俯衝:telegraph+shake+變色前搖 +0.72s → 鎖定點撲擊 → 落地滯留 0.3s 輸出窗 → 回升)` + - P2 `bomb ×3`、`dive`、`summon(召喚 floaty,場上上限 2——cap 由 FSM 指令帶出、 +GameScene 依現量夾限走正式 spawn 管線)` + - P3 `barrage(狂暴彈幕:全向放射彈環 ×7)`、`sweep(全場俯掠:橫帶預警閃爍 0.75s 後 +貼 y=280 帶速掠全場,站立可躲)`、`bomb` + +> **已廢止**(v9 §63/v21 §111 起):固定循環游標出招(`noctraAttackCycle`,換階段游標 +> 重置);P1 bomb ×4、P2 `bomb ×5 → dive → dive 連擊 → summon`、P3 彈環 ×10; +> dive/sweep telegraph 0.55s/0.6s。 + - telegraph 全數必備:dive 落點標記、sweep 橫帶閃爍、bomb 落點標記、階段轉換體色循環 (P2 白紅、P3 金紫)+白閃抖動;統一走 systems/fx 慣例。 -- 盤旋駕駛:常態沿視寬正弦盤旋(高度 168±14 呼吸浮動);dive/sweep tween 接管期間讓位 - (steering 互斥),死亡冪等(FSM defeated 單向鎖存,演出僅執行一次)。(v9.1 已由 §64 - 補訂:接管結束改速度上限逼近歸位,禁止相位座標直寫——修正返空瞬移。) +- 盤旋駕駛:常態沿視寬正弦盤旋(**高度 246±14** 呼吸浮動,§63 根修入單跳星彈可打帶); + dive/sweep tween 接管期間讓位(steering 互斥),**接管結束以速度上限逼近歸位** + (`approachPoint`,禁相位座標直寫,§64.1);死亡冪等(FSM defeated 單向鎖存,演出僅執行一次)。 + +> **已廢止**(v9 §63/v9.1 §64.1 起):盤旋高度 168±14;接管結束以凍結相位的絕對座標 +> 逐幀直寫——該寫法即「返空瞬移」P0 根因。 + - 可達性:玩家跳躍+拍翅 ×3 可觸及盤旋帶;dive/sweep 主動進入地面帶提供輸出窗; 補給小怪維持彈藥循環。擊破沿 §17 演出(皇冠戰利品:蝠「王」同為王權敘事)。 - anti-softlock:入場運鏡 active 前傷害靜默忽略;退出/重整走 §35 暫停與 scene restart @@ -192,28 +206,28 @@ FSM 指令帶出、GameScene 依現量夾限走正式 spawn 管線)`(v9 已 ### 63.1 調參前後值(基準表;EX 沿新基準 ×1.5/×1.15) -| 位置 | 參數 | v8 出貨 | v9 根修 | 目的 | -| --------- | ------------------------------- | --------------------: | ----------------------------: | ------------------------------------------------------------------------------------------------ | -| noctra.ts | `HOVER_Y` | 168 | **246** | 體底降入單跳星彈可打帶(含 ±14 浮動恆可命中) | -| noctra.ts | `SIDE_MARGIN_X` | 130 | **190** | 收窄掃幅,牆側留玩家喘息帶(錨點打法成立) | -| noctra.ts | 盤旋掃速 | 0.0009 | **0.0007** | 峰值橫移降至玩家走速下,保距走位可行 | -| noctra.ts | `DIVE_TELEGRAPH_MS` | 550 | **720** | 普通反應(250-400ms)可讀可躲 | -| noctra.ts | `SWEEP_TELEGRAPH_MS` | 600 | **750** | 俯掠可讀 | -| noctraFsm | `diveHoldMs` | 無 | **300** | 俯衝落地滯留=地面明確輸出窗 | -| noctraFsm | `diveDurationMs` | 1500 | **2100** | 容納前搖+滯留(EX 最高速率下不與下招重疊) | -| noctraFsm | `diveStunWindowMs` | 600 | **900** | 頭頂下砸長暈窗涵蓋滯留段 | -| noctraFsm | `idleMs` | 1100 | **1600** | 表觀 hit window ≥55% | -| noctraFsm | `bombCountP1/P2` | 4/5 | **2/3** | P1/P2 落彈鏈為主要死因 | -| noctraFsm | `barrageCount` | 10 | **7** | P3 密度 | -| noctraFsm | P2 循環 | bomb,dive,dive,summon | **bomb,dive,summon** | 去連擊 | -| noctraFsm | `enrageSpeedMultiplier` | 1.25 | **1.15** | P2/P3 節奏回讀帶 | -| noctraFsm | `maxHp` | 70 | **52** | TTK 對齊補給經濟(普通保底線 ~40-60s 擊破) | -| noctraFsm | `minionSpawnHpStep` | 10 | **8** | 輸出愈多彈藥愈順(正回饋) | -| levels L7 | `spawnIntervalMs`/`maxOnScreen` | 3200/2 | **4500/1** | 供給定位是彈藥非第二傷害源 | -| levels L7 | 補給構成 | jelly/floaty/gusty | **jelly/floaty/zappy** | 移除俯衝型騷擾;保雷化斷召素材 | -| waves.ts | 補給入場側 | 左右交替 | **玩家遠側** | 走向玩家的路程=拾取節奏 | -| homing.ts | `BOSS_AIM_ASSIST` | 無 | **range 560 / 0.0012 rad/ms** | 一般星彈對魔王微導向:地面平射自然上彎入盤旋帶(追蹤彈 1/5 轉率、須大致對向;追電/迴旋星不疊加) | -| mercyHeal | 魔王房 override | 無 | **HP≤2、12s、18s CD、60%** | boss 戰長度下保底真正可觸發(v19 已由 §62 取代 60% 擲骰:改 pity 受傷 2 次/低血 15s 保底) | +| 位置 | 參數 | v8 出貨 | v9 根修 | 目的 | +| --------- | ------------------------------- | --------------------: | ----------------------------------------: | ------------------------------------------------------------------------------------------------ | +| noctra.ts | `HOVER_Y` | 168 | **246** | 體底降入單跳星彈可打帶(含 ±14 浮動恆可命中) | +| noctra.ts | `SIDE_MARGIN_X` | 130 | **190** | 收窄掃幅,牆側留玩家喘息帶(錨點打法成立) | +| noctra.ts | 盤旋掃速 | 0.0009 | **0.0007** | 峰值橫移降至玩家走速下,保距走位可行 | +| noctra.ts | `DIVE_TELEGRAPH_MS` | 550 | **720** | 普通反應(250-400ms)可讀可躲 | +| noctra.ts | `SWEEP_TELEGRAPH_MS` | 600 | **750** | 俯掠可讀 | +| noctraFsm | `diveHoldMs` | 無 | **300** | 俯衝落地滯留=地面明確輸出窗 | +| noctraFsm | `diveDurationMs` | 1500 | **2100** | 容納前搖+滯留(EX 最高速率下不與下招重疊) | +| noctraFsm | `diveStunWindowMs` | 600 | **900** | 頭頂下砸長暈窗涵蓋滯留段 | +| noctraFsm | `idleMs` | 1100 | **1600** | 表觀 hit window ≥55% | +| noctraFsm | `bombCountP1/P2` | 4/5 | **2/3** | P1/P2 落彈鏈為主要死因 | +| noctraFsm | `barrageCount` | 10 | **7** | P3 密度 | +| noctraFsm | P2 循環 | bomb,dive,dive,summon | **bomb,dive,summon** | 去連擊 | +| noctraFsm | `enrageSpeedMultiplier` | 1.25 | **1.15** | P2/P3 節奏回讀帶 | +| noctraFsm | `maxHp` | 70 | **52** | TTK 對齊補給經濟(普通保底線 ~40-60s 擊破) | +| noctraFsm | `minionSpawnHpStep` | 10 | **8** | 輸出愈多彈藥愈順(正回饋) | +| levels L7 | `spawnIntervalMs`/`maxOnScreen` | 3200/2 | **4500/1** | 供給定位是彈藥非第二傷害源 | +| levels L7 | 補給構成 | jelly/floaty/gusty | **jelly/floaty/zappy** | 移除俯衝型騷擾;保雷化斷召素材 | +| waves.ts | 補給入場側 | 左右交替 | **玩家遠側** | 走向玩家的路程=拾取節奏 | +| homing.ts | `BOSS_AIM_ASSIST` | 無 | **range 560 / 0.0012 rad/ms** | 一般星彈對魔王微導向:地面平射自然上彎入盤旋帶(追蹤彈 1/5 轉率、須大致對向;追電/迴旋星不疊加) | +| mercyHeal | 魔王房 override | 無 | **HP≤2、12s、18s CD**(v9 另加 60% 擲骰) | boss 戰長度下保底真正可觸發。**v19 起擲骰改 pity(受傷 2 次/低血 15s),現行值見 §62** | ### 63.2 驗收證據(噗頭對噗頭 bot 實測,序列執行;`scripts/noctra-bot-audit.mjs`) @@ -263,22 +277,25 @@ FSM 指令帶出、GameScene 依現量夾限走正式 spawn 管線)`(v9 已 變化」迫使玩家切換單體集火與多目標處理。HP 80(階梯 60→52→80)、體傷 1、狂暴 ×1.15、 每損 10 HP 掉補給(§26)。 -- 三階段(phase truth 全收斂 FSM;呈現層 systems/prismix.ts 接 BossHandle) - (v22 已由 §112 取代:固定循環改 `prismixMoveTable` 加權表選招,P2 追加鏡界反射與 - 鏡像殘影;招池數值與 telegraph 不變): - - P1 單體(總血 >66%):`idle(1.5s) → 晶柱衝擊(地面尖晶 ×3,落點預警 0.95s)→ idle → -折射光束(橫掃一次,預示線 0.5s)→ …` - - 晶柱預警(#810 修復):0.6s→0.95s——500ms 反應玩家迴避率 0%→88%(工具實測); - 預警視覺為落點橢圓+尖刺實際範圍白框+裂紋豎線閃爍(形狀與明滅雙訊號,色弱不依賴 - tint);下限 SSOT=`difficulty.AUDIT_THRESHOLDS.spikeTelegraphMinMs`(900ms)。 - - P2 分裂(≤66%):剩餘 HP 均分為**雙獨立血條**(HUD 魔王條雙節顯示,BOSS_TWIN_HP - 事件);鏡像雙子同一指令左右對稱執行——`雙生夾擊(同步閃爍 0.6s → 左右對衝互換位, +- 三階段(phase truth 全收斂 FSM;呈現層 systems/prismix.ts 接 BossHandle)。**選招為 + 加權表驅動** `prismixMoveTable`(§112.1;telegraph 數值不變),P2 另有主題招式鏡界反射 + (§112.2)與鏡像殘影(§112.3): + +> **已廢止**(v22 起,現行見 §112):P1–P3 依固定循環出招(可背板)。 + +- P1 單體(總血 >66%)招池:`idle(1.5s)`、`晶柱衝擊(地面尖晶 ×3,落點預警 0.95s)`、 + `折射光束(橫掃一次,預示線 0.5s)` +- 晶柱預警(#810 修復):0.6s→0.95s——500ms 反應玩家迴避率 0%→88%(工具實測); + 預警視覺為落點橢圓+尖刺實際範圍白框+裂紋豎線閃爍(形狀與明滅雙訊號,色弱不依賴 + tint);下限 SSOT=`difficulty.AUDIT_THRESHOLDS.spikeTelegraphMinMs`(900ms)。 +- P2 分裂(≤66%):剩餘 HP 均分為**雙獨立血條**(HUD 魔王條雙節顯示,BOSS_TWIN_HP + 事件);鏡像雙子同一指令左右對稱執行——`雙生夾擊(同步閃爍 0.6s → 左右對衝互換位, 跳越可躲;#809 衝撞前搖對齊 ≥600ms 可讀性紅線)→ 交錯光束(一具地面帶、一具空中帶) → 召喚 mirri(場上限 2,雷化鏈電可中斷 §58 慣例)`。 - - 殘核掙扎(事件驅動):單具擊破 → 另一具入 1.0s 掙扎僵直(體色轉暗 telegraph、可傷); - 窗滿 → 存活具吸收殘核合體入 P3(裂核 HP=存活具剩餘)。 - - P3 裂核:環繞碎晶盾 ×4(可擊破星彈屏障,軌道公轉)→ 全域折射彈幕(放射 ×8,蓄能 - 轉白)→ 晶雨(落點預警 0.6s ×3)→ … +- 殘核掙扎(事件驅動):單具擊破 → 另一具入 1.0s 掙扎僵直(體色轉暗 telegraph、可傷); + 窗滿 → 存活具吸收殘核合體入 P3(裂核 HP=存活具剩餘)。 +- P3 裂核:環繞碎晶盾 ×4(可擊破星彈屏障,軌道公轉)→ 全域折射彈幕(放射 ×8,蓄能 + 轉白)→ 晶雨(落點預警 0.6s ×3)→ … - **雙子連破**(§70 彩蛋):掙扎窗內補殺第二具=總血歸零直接擊破、跳過 P3。 - 多本體工程契約:BossHandle 增選配 `getBodies()`/`applyDamageAt(x,y)`/`getShields()`; GameScene 星彈/觸碰/下砸/反彈逐本體接線,受擊側依命中位置歸最近存活本體;準星輔助、 @@ -311,16 +328,19 @@ FSM 指令帶出、GameScene 依現量夾限走正式 spawn 管線)`(v9 已 王窯座(不追打),威脅來自「地形被改寫」:潮汐、噴泉、滴落把可站空間動態壓縮, 考驗空間規劃。HP **90**(階梯 60→52→80→90)、體傷 1、狂暴 ×1.15、每損 10 HP 掉補給。 -- 三階段(phase truth 全收斂 FSM;呈現層 systems/syrona.ts 接 BossHandle) - (v22 已由 §112 取代:固定循環改 `syronaMoveTable` 加權表選招,糖漿波追加焦糖化; - 招池數值與 telegraph 不變): - - P1(>66%):`糖漿噴泉(地面點 ×3 順序噴發,冒泡 telegraph 0.8s)→ 散熱僵直 2.5s → -焦糖射彈(拋物 ×3,舉臂 0.5s)→ 僵直 → …` - - P2(66-33%):**潮汐入場**(phase 事件觸發 startTide,沿 §71 管線);循環 - `熔糖滴落(天花板 ×4 預警光斑 0.7s → 直墜)→ 吟唱僵直 2.0s → 召喚 Bubbla(上限 2, +- 三階段(phase truth 全收斂 FSM;呈現層 systems/syrona.ts 接 BossHandle)。**選招為 + 加權表驅動** `syronaMoveTable`(§112.1;telegraph 數值不變),P3 糖漿波另帶主題招式 + 焦糖化(§112.4): + +> **已廢止**(v22 起,現行見 §112):P1–P3 依固定循環出招(可背板)。 + +- P1(>66%)招池:`糖漿噴泉(地面點 ×3 順序噴發,冒泡 telegraph 0.8s)`、 + `焦糖射彈(拋物 ×3,舉臂 0.5s;限遠距帶)`,招間散熱僵直 2.5s +- P2(66-33%):**潮汐入場**(phase 事件觸發 startTide,沿 §71 管線);循環 + `熔糖滴落(天花板 ×4 預警光斑 0.7s → 直墜)→ 吟唱僵直 2.0s → 召喚 Bubbla(上限 2, 雷化鏈電可中斷 §58 慣例)→ 噴泉加密 ×4 → …` - - P3(≤33%):**大沸騰**(boilTide:潮汐週期 -30%、漲頂 +24px);循環 - `全場糖漿波(邊緣起浪 0.9s → 單向橫越 250px/s,跳越可躲)→ 波後僵直 2.0s → +- P3(≤33%):**大沸騰**(boilTide:潮汐週期 -30%、漲頂 +24px);循環 + `全場糖漿波(邊緣起浪 0.9s → 單向橫越 250px/s,跳越可躲)→ 波後僵直 2.0s → 噴口超載 2.6s(arena 雙噴口恆噴+升托增強至 -640,開放直達皇冠的垂直路線)→ …` - arena 場控幾何(§28 禁硬編,呈現層依動態視寬比例佈建;LevelSpec 幾何表留空): 浮台 ×3(22%/47%/70%,y 336/304/336——低台 P2 漲頂下可站、高台 304 沸騰期保底位, @@ -361,11 +381,14 @@ FSM 指令帶出、GameScene 依現量夾限走正式 spawn 管線)`(v9 已 (落點預警 0.7s)+炮擊過熱窗 ×3(核心下沉 3.0s=唯一輸出窗);沿途空投星屑 ×5(§83 彩蛋收集);段內固定慈悲愛心 1 顆(16s 投放)。時間驅動(40s 播完) 與傷害驅動(過熱窗打穿 40%)雙轉換路徑入 P3。 - - **P3 核心決戰(≤40%)**:全場低重力 0.55 注入 → barrage 蝕星彈幕(放射 ×8+ - 螺旋雙層)→ crush 黑洞潮汐(水平牽引 150px/s < 玩家全速 220,交叉不變式 16; - arena 無坑洞+實牆邊界);裂核大窗 3.5s(金紋呼吸提示)。 - (v23 已由 §113 取代:P1/P3 固定循環改 `voidraMoveTable` 加權表選招並追加 - 星光虹吸;招池與 telegraph 數值不變、P2 波次表驅動不變。) + - **P3 核心決戰(≤40%)**:全場低重力 0.55 注入;招池 barrage 蝕星彈幕(放射 ×8+ + 螺旋雙層)、crush 黑洞潮汐(水平牽引 150px/s < 玩家全速 220,交叉不變式 16; + arena 無坑洞+實牆邊界)、星光虹吸(§113.2);裂核大窗 3.5s(金紋呼吸提示)。 +- **P1/P3 選招為加權表驅動** `voidraMoveTable`(§113.1;telegraph 數值不變);P2 生存段 + 維持波次表驅動不變。 + +> **已廢止**(v23 起,現行見 §113):P1/P3 依固定循環出招;死碼 `voidraAttackCycle` 已移除。 + - anti-softlock(主計畫 §10.2-8):P2 零擊殺可過(純走位 40s)、無位置懲罰即死、 不設計時失敗;**段起點重試**——P2/P3 死亡不回滾整場(trySegmentRespawn:彈幕/ 星屑/轟炸/殘留 delayedCall 清場+FSM resetToPhase+玩家沿 checkpoint 管線重生於 diff --git a/apps/starpuff/docs/design/04-levels-world.md b/apps/starpuff/docs/design/04-levels-world.md index b5f34e050..db7973795 100644 --- a/apps/starpuff/docs/design/04-levels-world.md +++ b/apps/starpuff/docs/design/04-levels-world.md @@ -6,11 +6,13 @@ > > **關卡表沿革**:L1-L4(§15)→ L5-L7(§50)→ L8-L9(§60)→ L10-L12(§65)→ L13-L16(§76)→ L17-L20(§84)。各章的**關卡列仍為該批關卡的現行規格**;被取代的只有當時的「總關數/世界地圖節點數」宣告(詳見 [`99-superseded.md`](99-superseded.md))。 > -> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md)。 +> **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 ## 15. 關卡系統(levels.ts 為 SSOT,pure TS 可測) -流程改為:Title → Stage 1 → 2 → 3 → 4(魔王)→ Result。死亡重試當前關;通關進下一關(轉場卡全屏 1.2s:關卡編號+名稱+緩動)(v6 已由 §39 取代:通關 → 世界地圖揭霧 → 自節點進下一關,轉場卡廢除)。 +流程:自世界地圖節點進關 → 走動關達配額開星星門過關 → **回世界地圖揭霧**(§39),自節點進下一關或重玩。死亡重試當前關(卡點關自 checkpoint 重生,§67)。 + +> **已廢止**(v6 起,現行見 §39):Title → Stage 1 → 2 → 3 → 4(魔王)→ Result 線性串關;通關播全屏轉場卡(1.2s 關卡編號+名稱+緩動)直達下一關——轉場卡廢除。 L1-L4 的 v2 直向世界寬配置表已全數失效(v3 §21 改橫式尺寸、後續各版重配怪物組合), 移至 [`99-superseded.md`](99-superseded.md#151-l1-l4-v2-直向配置表已失效);**現行值以 @@ -64,7 +66,9 @@ Arcade Physics 相容優先(斜坡不做——Arcade 無原生支援,違反 - 揭霧動畫:通關進場帶 `reveal` 節點——霧散(alpha/scale tween)+節點 Back.easeOut 彈出+zzfx reveal sting;視寬重排 restart 不重播。 - 彩蛋計數:標題下方 `彩蛋 found/total`,total 由 LEVELS easterEggs 推導。 - 命中一律 DOM 鈕(`data-menu="node-N"`,旋轉殼 hit-test 天然正確);鎖定節點無入口。鍵盤備援:ENTER 進當前挑戰關、ESC 回 Title。 -- 計時語義變更:hub 模型下各關獨立計時入存檔 bestTime;Result 顯示該關用時(v5 四關累計總時語義廢除)。 +- 計時語義:hub 模型下各關獨立計時入存檔 bestTime;Result 顯示該關用時。 + +> **已廢止**(v6 起):v5 的四關累計總時語義。 ## 43. 每關攻略 PoC 與反卡關驗證 @@ -99,8 +103,7 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 ## 50. v8 關卡 4→7 與雙魔王總覽(levels.ts 資料驅動擴充) -流程擴為:L1-L3 → L4 果凍王 → L5-L6 → L7 暗月蝠王(第二魔王收尾)(v9 已由 §60 擴為 -九關;v10 已由 §65 取代:十二關三魔王)。解鎖鏈沿 §39 +本批新增 L5-L7(第二魔王暗月蝠王收尾);**全線編成現行值見 §84(五區二十關)**。解鎖鏈沿 §39 (第 N 關需 N-1 通關);世界地圖擴為七節點鋸齒路徑(節點半徑收斂 30),新節點沿用 迷霧鎖定態。save schema v1 不變——舊存檔(≤4 關條目)原樣載入,L5 依解鎖規則自然 開放、L6/L7 鎖定(相容契約見 save.test「v8 存檔相容」與 e2e「舊存檔相容」案)。 @@ -157,7 +160,9 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 - e2e 通關 bot(v8.spec.ts):舊存檔相容七節點案、L5 氣流升空案、L5 精英線通關案、 L6 雙精英逐房通關案、Noctra 三階段擊破入結算案、新混合三式案、spora/boomy 行為案。 -## 60. v9 關卡 7→9 與世界地圖(levels.ts 資料驅動擴充)(v10 已由 §65 取代:十二關與十二節點) +## 60. v9 關卡 7→9 與世界地圖(levels.ts 資料驅動擴充) + +**下表 L8/L9 為現行關卡規格**;本節當時的「九關/九節點」總數宣告已由 §84(二十關)與 §78(五區分頁)取代。 | # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | | --- | -------- | --------- | ------ | ---- | ------ | ----------------------------------- | ------------- | @@ -191,7 +196,9 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 星彈(近戰路徑恆存);L8/L9 可吸佔比 ≥50%(levels.test);雙精英房距 ≥600; EX 為選配挑戰(不阻主線、無新解鎖依賴)。 -## 65. v10 關卡 9→12 與世界地圖(levels.ts 資料驅動擴充)(v11 已由 §76 取代:十六關與十六節點) +## 65. v10 關卡 9→12 與世界地圖(levels.ts 資料驅動擴充) + +**下表 L10–L12 為現行關卡規格**;本節當時的「十二關/十二節點」總數宣告已由 §84(二十關)與 §78(五區分頁)取代。 | # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | | --- | -------- | ----------- | ------------ | ---- | ------ | ------------------------------------------ | ------------- | diff --git a/apps/starpuff/docs/design/05-save-settings.md b/apps/starpuff/docs/design/05-save-settings.md index 390a91424..515e2d17c 100644 --- a/apps/starpuff/docs/design/05-save-settings.md +++ b/apps/starpuff/docs/design/05-save-settings.md @@ -6,16 +6,24 @@ > > **現行儲存鍵**:`sp-save`(存檔,schema v2)/`sp-save-backup`(備援)/`sp-settings`(全部偏好,schema v1)。`sp-muted`、`sp-rotation`、`sp-key-layout` 已於 §118.1 收斂,僅作一次性 migration 來源。 > -> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 +> **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 ## 38. 存檔系統(core/save.ts 為 SSOT,pure TS 可測) -- localStorage `sp-save` schema v1:`{ schemaVersion, highestClearedLevel, levels: { [id]: { cleared, bestTimeMs, eggsFound: string[] } }, lastPlayedAt }`。(v15 已由 §94.2 升 v2 增 `achievements`;v19 已由 §118.3 補訂 checksum 欄與 `sp-save-backup` 備援。) +- localStorage `sp-save` **schema v2**:`{ schemaVersion, highestClearedLevel, levels: { [id]: { cleared, bestTimeMs, eggsFound: string[], exCleared? } }, lastPlayedAt, achievements, checksum }`(`achievements` 見 §94.2、`checksum` 與備援鍵 `sp-save-backup` 見 §118.3)。 + +> **已廢止**(v15/v19 起):schema v1(無 `achievements`、無 `checksum`、無備援)——v1 舊檔由 `parseSave` 遷移,禁 discard。 + - 寫入時機:通關(星星門吸入當下即寫,演出中斷不掉進度)、魔王擊破、彩蛋觸發(`trigger` 型別字串為關內唯一 id)。 - 容錯(沿用 §34 鍵位布局 parse/fallback 模式):schema 版本不符、形狀損毀、隱私模式拋錯——一律回退預設值;`highestClearedLevel` 由關卡條目重新推導,不信任持久化值。 - `bestTimeMs`=該關單次成功嘗試的最短用時(死亡重試重計);`eggsFound` 去重持久化,跨局累計。 -- 重置進度:世界地圖左下「重置進度」兩步確認(武裝態 3s 未確認自動退回),僅清存檔(偏好不動)。全新存檔不顯示入口。(v19 已由 §118.3 補訂清除範圍:同時清 `sp-save` 與備援 `sp-save-backup`;偏好鍵自 `sp-key-layout`/`sp-muted` 收斂為 `sp-settings`。) -- 偏離備註:任務原文「設定頁加重置進度」——v6 當時本遊戲無設定頁(按鈕配置為鍵位編輯器,語義不符),重置入口落於世界地圖(進度顯示與進度管理同場景,KISS)。(v19 已由 §118.2 取代前提:Title 已有「設定」入口,但重置進度**維持在世界地圖**——進度顯示與進度管理同場景的 KISS 裁決不變。) +- 重置進度:世界地圖左下「重置進度」兩步確認(武裝態 3s 未確認自動退回),**清 `sp-save` 與備援 `sp-save-backup`**(§118.3;不清則會自備援恢復舊進度),偏好(`sp-settings`)不動。全新存檔不顯示入口。 + +> **已廢止**(v19 §118.3 起):清除範圍僅 `sp-save`;當時的偏好鍵表述為「`sp-key-layout`、`sp-muted` 不動」。 + +- 入口位置裁決:重置進度**維持在世界地圖**——進度顯示與進度管理同場景(KISS)。Title 雖已有「設定」入口(§118.2),仍不搬入。 + +> **已廢止**(v19 §118.2 起):原偏離備註的前提「本遊戲無設定頁(按鈕配置為鍵位編輯器,語義不符)」——設定頁已存在,但入口裁決結論不變。 ## 94. v15 成就系統(logic/achievements.ts,純呈現層聚合) diff --git a/apps/starpuff/docs/design/06-ui-shell-pwa.md b/apps/starpuff/docs/design/06-ui-shell-pwa.md index 4416dc2be..1f42e0b5e 100644 --- a/apps/starpuff/docs/design/06-ui-shell-pwa.md +++ b/apps/starpuff/docs/design/06-ui-shell-pwa.md @@ -6,7 +6,7 @@ > > **命中紀律**:選單與 HUD 一律以 DOM 鈕承接命中(旋轉殼下 hit-test 天然正確),canvas 圖示僅保留視覺;命中短邊 48px 保底(§98)。全遊戲禁 emoji 與文字鍵帽。 > -> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 +> **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 ## 33. v5 iOS PWA UX 調研回寫(2026-07-15 定稿) @@ -31,16 +31,25 @@ - 全停語義:`scene.pause(Game)`(物理/計時/tween/輸入輪詢全停)+ `AudioContext.suspend()`(BGM 與 SFX 全停)。 - 重新開始=重置當前關卡全狀態(血量/彈藥/擊殺數/計時/實體經 scene.restart 重生),保留已完成關卡累計用時與本輪死亡數。 - 離頁自動暫停:`visibilitychange`(hidden)與 `pagehide`(同走 hidden 檢查防雙觸發)即開暫停選單;回前景停在選單、玩家點「繼續」才接續(取代 §26 的自動恢復,杜絕回前景瞬間被偷襲)。音訊恢復一律走手勢堆疊內 `resume()`(§33 條目 6),刻意暫停期間全域復聲保險不生效。 -- 與 PWA 週期更新 hooks(main.ts `import './pwa'`)共存:兩者互不依賴,同檔並列。已知邊界:回前景恰逢新版部署時,autoUpdate 完成後的 reload 會重新載入頁面蓋過暫停選單,屬可接受權衡,不特別攔截。(v19 已由 §118.4 取代此已知邊界:更新套用改經殼層安靜閘,遊戲進行中與暫停選單期間絕不 reload。) +- 與 PWA 週期更新 hooks(main.ts `import './pwa'`)共存:兩者互不依賴,同檔並列。**更新套用經殼層安靜閘**(§118.4)——遊戲進行中與暫停選單期間絕不 reload。 + +> **已廢止**(v19 §118.4 起):原記為可接受權衡的已知邊界「回前景恰逢新版部署時,autoUpdate 的 reload 會蓋過暫停選單,不特別攔截」——該競態已由更新閘根治。 ## 36. v5 開場主選單與圖鑑/技能介紹 - Title 開場動畫:主標縮放彈出(Back.easeOut)、副標延遲淡入、主角自天而降 Bounce 落定+光暈淡入;維持既有美術風格與 zzfx 音效(選單按壓 pop)。 -- 主選單:開始遊戲(主鈕)+次選單列 圖鑑/技能介紹/按鈕配置(DOM 鈕承接命中,data-menu 標識)。(v6 §39 增「世界地圖」;v19 已由 §118.2 取代次選單構成:世界地圖/圖鑑/技能介紹/設定四鈕,按鈕配置移入設定頁轉入口;桌機另增常駐「操作說明」,見 §87.4。) +- 主選單:開始遊戲(主鈕)+次選單列 **世界地圖/圖鑑/技能介紹/設定** 四鈕(DOM 鈕承接命中,data-menu 標識);按鈕配置自設定頁轉入(§118.2),桌機另增常駐「操作說明」(§87.4)。 + +> **已廢止**(v6 §39/v19 §118.2 起):次選單列為 圖鑑/技能介紹/按鈕配置 三鈕(無世界地圖、按鈕配置為 Title 直鈕)。 + - 圖鑑/技能介紹(`CodexScene` 單場景雙分頁,資料 SSOT `core/codex.ts`,立繪一律取既有 sprite 資產、禁止新美術): - - 圖鑑分頁:全 8 角色(jelly/floaty/spiky/puffy/chompy/shelly/zappy/boss)4×2 網格——立繪+名稱+行為一句話+可吸/不可吸圓點標記。(v7 擴 5×2 十格;v8 擴 7×2 十四格;v9 已由 §59 取代:8×2 十六格。) - - 技能分頁:吸入/星彈三系(含來源怪物對應)(v6 已由 §40 擴充為五系+殼盾/雷鏈條目;v7 §44/§46 移除空中疾衝、增混合星彈與七系敘述)/強化星/星暴/下衝擊/漂浮,雙欄列表(名稱+操作+效果)。 - - 分頁切換以 scene.restart 重建(選單輕量無局內狀態);ESC 或返回鈕回 Title。 + - 圖鑑分頁(怪物):**23 隻分頁呈現,每頁 12 格 6×2**+底緣翻頁列(§104)——立繪+名稱+行為一句話+可吸/不可吸圓點標記。 + - 技能分頁:吸入/**星彈九系**(含來源怪物對應)/混合星/強化星/星暴/下衝擊/殼盾/雷鏈/漂浮,**有界網格 3 欄 3 列**(§96)。 + - 成就分頁:21 條徽章 6 欄網格(§94.3)。 + +> **已廢止**(v9 §59/v16 §96/§104 起):圖鑑單頁 4×2 八格(其後 5×2/7×2/8×2 亦為過渡值);技能分頁固定雙欄五列與「星彈三系/七系」敘述。 + +- 分頁切換以 scene.restart 重建(選單輕量無局內狀態);ESC 或返回鈕回 Title。 ## 37. v5 全元素位置稽核 diff --git a/apps/starpuff/docs/design/07-art-audio-fx.md b/apps/starpuff/docs/design/07-art-audio-fx.md index c61e2fe63..e702f2829 100644 --- a/apps/starpuff/docs/design/07-art-audio-fx.md +++ b/apps/starpuff/docs/design/07-art-audio-fx.md @@ -6,7 +6,7 @@ > > **紀律**:codex imagegen 僅用於本檔列出的資產批次;走路/跳躍等動作一律程式 tween,不生成逐幀序列。 > -> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 +> **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 ## 8. Juice 清單(品質關鍵,全數必做) @@ -14,7 +14,9 @@ hit-stop 60ms、震屏 4px、受擊白閃、squash & stretch(跳躍/落地/吸 ## 9. 音效(zzfx,零音檔資產) -jump、flap、inhale(迴圈)、swallow、shoot、hit、hurt、metal(皇冠落地)、pop(puffy 爆裂)、chomp(咬咬花咬合)、boss-roar、boss-slam、win、lose;BGM 用 zzfx 合成短循環(手刻序列混音,零依賴)。首次觸控後 resume AudioContext(iOS 必須)。靜音偏好存 localStorage(sp-muted)(v19 已由 §118.1 取代:收斂為 `sp-settings.audioMuted`,`sp-muted` 僅作一次性 migration 來源,落盤後刪除)。 +jump、flap、inhale(迴圈)、swallow、shoot、hit、hurt、metal(皇冠落地)、pop(puffy 爆裂)、chomp(咬咬花咬合)、boss-roar、boss-slam、win、lose;BGM 用 zzfx 合成短循環(手刻序列混音,零依賴)。首次觸控後 resume AudioContext(iOS 必須)。靜音偏好存 `sp-settings.audioMuted`(§118.1),設定頁「音效」開關即改即存。 + +> **已廢止**(v19 起,現行見 §118.1):獨立 localStorage 鍵 `sp-muted`——僅存留為一次性 migration 來源,落盤成功後刪除。 ## 10. 美術資產規格(codex imagegen 專用;除此之外嚴禁動用 codex) diff --git a/apps/starpuff/docs/design/08-safety-nets.md b/apps/starpuff/docs/design/08-safety-nets.md index 9e4ce22bb..8c8e9500e 100644 --- a/apps/starpuff/docs/design/08-safety-nets.md +++ b/apps/starpuff/docs/design/08-safety-nets.md @@ -6,14 +6,17 @@ > > **硬不變式(使用者明令,全部 MUST)**:基礎星彈恆可通關;魔王關須有多種可行破關策略;難度循序漸進,永不無限卡關。關卡難度以分級 bot 勝率量化驗收(普通 ≥40%、熟練 ≥80%)。 > -> 章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號;索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。 +> **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 ## 26. 反卡死保證(softlock 防護,全部 MUST) - Spawner 保證律:玩家彈藥 0 且場上無可吸怪時,下一隻生成強制可吸(覆蓋權重);boss 期同律且立即補生(不等間隔)。 - 星星門必達:配額達成即於可達地面生成,overlap 高度涵蓋跳躍弧線。 - 場景無坑洞設計維持(無墜落死);世界邊界實牆。 -- visibilitychange:切背景暫停物理與計時(v5 已由 §35 取代:回前景停在暫停選單、點繼續才接續,不自動恢復)。 +- visibilitychange/pagehide:切背景即開暫停選單;**回前景停在選單、玩家點「繼續」才接續**(§35,杜絕回前景瞬間被偷襲)。 + +> **已廢止**(v5 起,現行見 §35):切背景僅暫停物理與計時、回前景自動恢復。 + - 深度探索 QA 劇本:邊緣紮營 5 分鐘、只殺不可吸怪、彈藥歸零僵持、暫停/恢復循環、快速連死——全數不得卡關。 ## 62. v9 慈悲補血愛心(logic/mercyHeal.ts 純決策,保底機制非資源農場) diff --git a/apps/starpuff/docs/design/99-superseded.md b/apps/starpuff/docs/design/99-superseded.md index 9b8528567..b0ec08071 100644 --- a/apps/starpuff/docs/design/99-superseded.md +++ b/apps/starpuff/docs/design/99-superseded.md @@ -6,11 +6,25 @@ > > **不在本檔**:任何現行有效規格。所有現行規格都在 `00`–`08` 各主題檔內。 > -> **為什麼多數取代標註仍留在原章節**:星噗噗的取代多半是「某章內的一條 bullet +> **為什麼多數取代註記仍留在原章節**:星噗噗的取代多半是「某章內的一條 bullet > 被改掉」而非整章作廢(例如 §23 的星暴長按行退場,但同章的連鎖規則仍有效)。 -> 把這些單行搬離會切斷上下文、讓原章讀不懂,因此原章保留 inline 取代標註, +> 把這些單行搬離會切斷上下文、讓原章讀不懂,因此原章就地保留註記, > 由下方 §取代對照表 作為權威索引。只有**整塊完全失效**的內容才實體搬到本檔。 +## 主句紀律(全設計檔一致,MUST) + +**每一句主文都必須是現行有效規則。** 被取代的舊規則一律降級為緊接其後的獨立附註: + +```markdown +- 同系星彈 ≥3 且在地面時,按 SP 鍵點按立即變身;再按 SP 提前解除。 + +> **已廢止**(v19 起,現行見 §109.2):地面長按吸入鍵 0.6s 觸發、再長按 0.6s 解除。 +``` + +理由:掃讀的人只讀主句。把過期規則留在主句、只把修正塞進括號,讀者會照舊規格實作—— +這正是本檔存在要消滅的失效模式。附註格式固定為 +`> **已廢止**(<起始版本> 起,現行見 §<章號>):<舊敘述>`,方便 grep 盤點。 + ## 章號紀律 章號 §N 是全專案穩定識別碼——`src/**` 程式註解、測試 describe 名稱與 issue 都直接 @@ -131,6 +145,8 @@ v7(§47/§49)glowy/drilly 入編改寫 L2/L3 波次、v7 §48 加入精英 星暴——下表的權重、打法與觸發面均已不成立。現行逐關攻略見 §49/§56 與 [`../WALKTHROUGH.md`](../WALKTHROUGH.md)。 +原引導句:設計意圖 → 最佳打法 → 無技能保底打法(僅移動+吸入+星彈必可通關,§26 保證律背書)逐關表: + | 關 | 設計意圖 | 最佳打法 | 無技能保底打法 | 難度曲線(quota/interval/構成) | | --- | ------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------- | --------------------------------------------------------------------------- | | 1 | 教學:移動/吸/射閉環,幾乎不死 | 開局反向拿 +1 HP 彩蛋,連吞 jelly×2 強化星速殺 | 站樁吸 jelly/floaty、點按發射,達 6 殺走右入門 | 6 / 2600ms / jelly 60%+floaty 40%(全可吸) | diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index e20c1a299..73e36dda0 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:reward-starpuff-t7c-r2-supersession-main-clause-inversion +- 原因:審查 Grok 席指出取代寫法方向錯誤——過期規則仍是主句、修正只在括號裡(如 §57 主句仍寫「地面長按 0.6s 變身」),掃讀者會照舊規格實作,changeset 承諾的「可直接判斷哪段有效」名實不符;另 01 檔頭宣告「不在本檔:按下之後發生什麼事」卻承載 §109.3 星暴狀態機 +- 解法:全 10 檔主句反轉為現行規則、舊規則降級為 35 條 `> **已廢止**(vNN 起,現行見 §YY)` 附註並立為全檔鐵律(99 增「主句紀律」章、索引同步);01 檔頭改採收窄方案(納入「與輸入直接連動的彈匣/蓄能狀態機」並說明 resolveSpPress 需讀蓄能相位,拆去 02 會製造雙 SSOT),02 檔頭加星暴指路 + - 日期:2026-07-26 - ID:neutral-starpuff-t7c-docs-changeset - 原因:AGT-VER-01 要求每個 PR 建 changeset;本 PR 為純文件但含使用者可見的錯誤指示修正(變身觸發面/慈悲補血/設定入口),需依 bfdf65585 docs-only patch 先例補建 From fadedf542a4f0bd7c7e2dee628c46877c83cd577 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 11:07:51 +0800 Subject: [PATCH 07/14] =?UTF-8?q?test(starpuff):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E8=A8=AD=E8=A8=88=E6=96=87=E4=BB=B6=E7=B4=A2=E5=BC=95=E5=AE=88?= =?UTF-8?q?=E9=96=80=E4=B8=A6=E6=8E=9B=E9=80=B2=20vitest=EF=BC=88=E5=AF=A9?= =?UTF-8?q?=E6=9F=A5=E5=BF=85=E4=BF=AE=203=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 scripts/verify-design-docs.mjs:索引存在性/檔名/零重複/零缺號/標題同步、 每檔職責聲明、主句紀律附註格式、全 repo 零錨點引用共六類檢查 - 同名 .test.mjs 掛進 vitest(include 增 scripts/**/*.test.mjs),另設 pnpm verify:docs - 守門上線即抓到我漏更的 §60/§65 索引標題,已同步修正 測試:pnpm --filter @app/starpuff test:run 69 檔 936 案全綠(新增 4 案); 四種故障注入實證守門非空轉(漏登新章/索引指錯檔/重複章號/行內取代標註回歸)皆 exit 1 Co-authored-by: Cursor --- apps/starpuff/docs/GAME_DESIGN.md | 240 +++++++++--------- apps/starpuff/package.json | 3 +- apps/starpuff/scripts/verify-design-docs.mjs | 189 ++++++++++++++ .../scripts/verify-design-docs.test.mjs | 41 +++ apps/starpuff/vitest.config.ts | 3 +- .../dev/002_development_reward_penalty_log.md | 5 + 6 files changed, 359 insertions(+), 122 deletions(-) create mode 100644 apps/starpuff/scripts/verify-design-docs.mjs create mode 100644 apps/starpuff/scripts/verify-design-docs.test.mjs diff --git a/apps/starpuff/docs/GAME_DESIGN.md b/apps/starpuff/docs/GAME_DESIGN.md index 287201e8d..a6312c988 100644 --- a/apps/starpuff/docs/GAME_DESIGN.md +++ b/apps/starpuff/docs/GAME_DESIGN.md @@ -52,123 +52,123 @@ ## 章號對照表 -| 章號 | 標題 | 檔案 | -| ---- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------- | -| §1 | 產品定位 | [`00-foundations.md`](design/00-foundations.md) | -| §2 | 核心循環 | [`00-foundations.md`](design/00-foundations.md) | -| §3 | 場景流程 | [`00-foundations.md`](design/00-foundations.md) | -| §4 | 操作(行動裝置優先) | [`01-controls-input.md`](design/01-controls-input.md) | -| §5 | 角色設定(全部原創) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §6 | 魔王 AI(有限狀態機,pure TS 可測) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §7 | 戰鬥數值 | [`02-combat-star.md`](design/02-combat-star.md) | -| §8 | Juice 清單(品質關鍵,全數必做) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §9 | 音效(zzfx,零音檔資產) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §10 | 美術資產規格(codex imagegen 專用;除此之外嚴禁動用 codex) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §11 | 技術架構 | [`00-foundations.md`](design/00-foundations.md) | -| §12 | 品質門檻 | [`00-foundations.md`](design/00-foundations.md) | -| §13 | 安全與合規 | [`00-foundations.md`](design/00-foundations.md) | -| §14 | 效能與範圍紀律 | [`00-foundations.md`](design/00-foundations.md) | -| §15 | 關卡系統(levels.ts 為 SSOT,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | -| §16 | 新怪物 ×2(多樣性;全原創) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §17 | 魔王關演出強化(動畫品質關鍵) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §18 | 動畫流暢度打磨清單(全實體) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §19 | v2 美術資產增補(codex 專用;生成尺寸同 §10 規範) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §20 | 技能系統:吞噬賦星(v2.1,PM 親撰) | [`02-combat-star.md`](design/02-combat-star.md) | -| §21 | v3 橫式轉向(PM 親撰) | [`01-controls-input.md`](design/01-controls-input.md) | -| §22 | iOS 觸控直通(研究回寫後定稿) | [`01-controls-input.md`](design/01-controls-input.md) | -| §23 | 技能組合 v3:吞噬連鎖(表驅動,logic/skills.ts) | [`02-combat-star.md`](design/02-combat-star.md) | -| §24 | 關卡彩蛋(data-driven:levels.ts easterEggs[]) | [`04-levels-world.md`](design/04-levels-world.md) | -| §25 | 背景連續感與視覺升級 | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §26 | 反卡死保證(softlock 防護,全部 MUST) | [`08-safety-nets.md`](design/08-safety-nets.md) | -| §27 | v3 美術資產(codex 專用;橫向平鋪) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §28 | v4 免轉向橫式與響應寬幅(PM 親撰) | [`01-controls-input.md`](design/01-controls-input.md) | -| §29 | v4 平台玩法元素包(調研回寫後定案數值) | [`04-levels-world.md`](design/04-levels-world.md) | -| §30 | v4 內容擴充:新技能、新怪物、魔王 P3(PM 親撰) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §31 | v4 美術資產(codex 專用) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §32 | 場景裝飾密度規範 | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §33 | v5 iOS PWA UX 調研回寫(2026-07-15 定稿) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §34 | v5 控制布局重設計與按鈕自訂 | [`01-controls-input.md`](design/01-controls-input.md) | -| §35 | v5 暫停系統與離頁自動暫停 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §36 | v5 開場主選單與圖鑑/技能介紹 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §37 | v5 全元素位置稽核 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §38 | 存檔系統(core/save.ts 為 SSOT,pure TS 可測) | [`05-save-settings.md`](design/05-save-settings.md) | -| §39 | 迷霧世界地圖(MapScene,data-driven 自 LEVELS) | [`04-levels-world.md`](design/04-levels-world.md) | -| §40 | v6 新技能:殼盾與雷鏈(PM 原創,補防禦與群戰原型) | [`02-combat-star.md`](design/02-combat-star.md) | -| §41 | v6 移動手感打磨(logic/movement.ts,pure TS 可測) | [`01-controls-input.md`](design/01-controls-input.md) | -| §42 | 版本號顯示 | [`00-foundations.md`](design/00-foundations.md) | -| §43 | 每關攻略 PoC 與反卡關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | -| §44 | v7 下衝擊觸發改制與跳躍鍵輸入矩陣(PM 親撰,取代 §23 下+B 觸發) | [`01-controls-input.md`](design/01-controls-input.md) | -| §45 | v7 走動手感根修與抖動歸因(logic/walkFeel.ts,pure TS 可測) | [`01-controls-input.md`](design/01-controls-input.md) | -| §46 | v7 雙味混合星彈(config STAR_MIXES 為 SSOT,表驅動) | [`02-combat-star.md`](design/02-combat-star.md) | -| §47 | v7 新怪物 ×2(全原創;素材 codex imagegen 僅此 2 張,風格與既有嚴格一致) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §48 | v7 中魔王精英系統(levels.ts elite 為 SSOT,零新美術) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §49 | v7 每關攻略 PoC 與節奏補訂(引入→練習→考驗→獎勵) | [`04-levels-world.md`](design/04-levels-world.md) | -| §50 | v8 關卡 4→7 與雙魔王總覽(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | -| §51 | v8 上升氣流機制(logic/updraft.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | -| §52 | v8 新怪物 ×3 與雙精英(FSM-first;素材 §55) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §53 | v8 星彈九系與新混合三式(config 表驅動擴充) | [`02-combat-star.md`](design/02-combat-star.md) | -| §54 | v8 第二魔王:暗月蝠王 Noctra(logic/noctraFsm.ts 表驅動,空中型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §55 | v8 美術資產(codex imagegen 專用;配額 6/6 用滿) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §56 | v8 每關攻略 PoC 與 anti-softlock 不變式 | [`04-levels-world.md`](design/04-levels-world.md) | -| §57 | v9 星化變身系統(logic/transform.ts 純狀態機,表驅動) | [`02-combat-star.md`](design/02-combat-star.md) | -| §58 | v9 魔王攻略多樣化與 EX 變體(表驅動擴充,禁止散落 scene) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §59 | v9 新怪物 ×2(FSM-first 進 enemyFsm,均歸既有味系) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §60 | v9 關卡 7→9 與世界地圖(levels.ts 資料驅動擴充)(v10 已由 §65 取代:十二關與十二節點) | [`04-levels-world.md`](design/04-levels-world.md) | -| §61 | v9 美術資產(codex imagegen 專用;配額 5/5) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | -| §62 | v9 慈悲補血愛心(logic/mercyHeal.ts 純決策,保底機制非資源農場) | [`08-safety-nets.md`](design/08-safety-nets.md) | -| §63 | v9 Noctra 難度根修(實測席稽核回寫;bot 勝率門檻收斂定案) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §64 | v9.1 熱修:Noctra 返空連續飛行與星暴無敵窗(P0) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §65 | v10 關卡 9→12 與世界地圖(levels.ts 資料驅動擴充)(v11 已由 §76 取代:十六關與十六節點) | [`04-levels-world.md`](design/04-levels-world.md) | -| §66 | v10 星門折躍(logic/warp.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | -| §67 | v10 卡點關中點重生(LevelSpec.checkpointX,§4 主計畫卡點緩解) | [`04-levels-world.md`](design/04-levels-world.md) | -| §68 | v10 第三魔王:稜晶雙子 Prismix(logic/prismixFsm.ts 表驅動,分裂型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §69 | v10 魔王關特殊體系(前室/短期增益/L12 首發;L4/L7 回補延 v11+) | [`04-levels-world.md`](design/04-levels-world.md) | -| §70 | v10 魔王關專屬彩蛋與每關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | -| §71 | v11 糖漿潮汐(logic/tide.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | -| §72 | v11 熱泉噴口(updraft 週期參數化,零新 element kind) | [`04-levels-world.md`](design/04-levels-world.md) | -| §73 | v11 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §74 | v11 第四魔王:Syrona 熔糖窯后(logic/syronaFsm.ts 表驅動,場控型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §75 | v11 魔王關專屬彩蛋與每關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | -| §76 | v11 關卡 12→16 與世界地圖(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | -| §77 | v11.1 熱修:下跳穿落根修、蹲姿指示與吸入豁免 | [`01-controls-input.md`](design/01-controls-input.md) | -| §78 | v12 分區分頁世界地圖(logic/zones.ts+MapScene,主計畫 §2.2 硬項落地) | [`04-levels-world.md`](design/04-levels-world.md) | -| §79 | v12 流星雨(logic/meteor.ts+systems/meteor.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | -| §80 | v12 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §81 | v12 低重力(LevelSpec.gravityScale,零新 element kind) | [`04-levels-world.md`](design/04-levels-world.md) | -| §82 | v12 最終魔王:蝕星魔核 Voidra(logic/voidraFsm.ts 表驅動,場控收束型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §83 | v12 魔王關專屬彩蛋與每關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | -| §84 | v12 關卡 16→20 與全線收尾(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | -| §85 | v12.1 熱修:真實觸控下滑判定重修(補訂 §21/§23/§77) | [`01-controls-input.md`](design/01-controls-input.md) | -| §86 | v13 EX 全魔王與星核制霸(EX 體系收尾+全制霸獎勵) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §87 | v14 直持預設旋轉方向翻轉(取代 §28 預設方向) | [`01-controls-input.md`](design/01-controls-input.md) | -| §88 | v14 按鈕配置頁操作列直欄化與標籤單行(取代 §34 操作列) | [`01-controls-input.md`](design/01-controls-input.md) | -| §89 | v14 虛擬鍵大小自訂(sp-key-layout schema v2) | [`01-controls-input.md`](design/01-controls-input.md) | -| §90 | v14 PWA 安裝偵測與分平台指引 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §91 | v14 觸覺回饋與螢幕常亮(調研加碼,ROI 閘通過二項) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §92 | v14 殼層卡片基建(shellCards.ts) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §93 | v14 殼局部 safe-area 量測(canvas 內 HUD 避讓預備) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §94 | v15 成就系統(logic/achievements.ts,純呈現層聚合) | [`05-save-settings.md`](design/05-save-settings.md) | -| §95 | v16 直持預設鍵位重錨(D1,取代 §34 預設在直持殼的適用性) | [`01-controls-input.md`](design/01-controls-input.md) | -| §96 | v16 圖鑑分頁有界網格(P1-01,取代 §36 技能雙欄與 §94.3 成就網格常數) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §97 | v16 區/關命名層級標示(F-01 裁決) | [`04-levels-world.md`](design/04-levels-world.md) | -| §98 | v16 選單 DOM 鈕命中短邊保底(D2,補充 §33 條目 7) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §99 | v16 版本頁腳 SHA 來源修正(F-02,補充 §42) | [`00-foundations.md`](design/00-foundations.md) | -| §100 | v16 勝利結算「下一關」主 CTA(D3,取代 §39 勝利回地圖單一動線) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §101 | v16 HUD 暫停/靜音 DOM 化(F-06+D4,取代 §35 暫停鍵與修復包 B 靜音鈕的命中層) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §102 | v16 配置模式遮罩加深(F-04,補充 §34) | [`01-controls-input.md`](design/01-controls-input.md) | -| §103 | v16 標題字形品牌化(D6,補充 §36) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §104 | v16 怪物圖鑑分頁(F-03,取代 §76 單頁定案) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | -| §105 | v16 前期節奏保守調參(D5+F-05,補充 §15 教學關與 §48 精英房) | [`04-levels-world.md`](design/04-levels-world.md) | -| §106 | GameScene strangler 拆解與守門(三席維護性 5/7/8 收斂) | [`00-foundations.md`](design/00-foundations.md) | -| §107 | 走動關供給保證與滿潮平衡(issue #804/#805/#806) | [`08-safety-nets.md`](design/08-safety-nets.md) | -| §108 | 難度量化工具(#818,T1 量測基礎設施) | [`08-safety-nets.md`](design/08-safety-nets.md) | -| §109 | v19 星暴 2.0+SP 情境鍵+B 鍵收斂(#815,修 #812 輸入面;輸入層 SSOT) | [`01-controls-input.md`](design/01-controls-input.md) | -| §110 | v20 變身系統 2.0——三形態加深+教學矩陣(#816;T4 列車) | [`02-combat-star.md`](design/02-combat-star.md) | -| §111 | v21 魔王主題化 W1——加權選招+Jellord/Noctra 主題招式(#813;T5 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §112 | v22 魔王主題化 W2——Prismix/Syrona 加權選招與主題招式(#813;T5 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §113 | v23 魔王主題化 W3——Voidra 加權選招與星光虹吸(#813;T5 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §114 | v24 EX 全面重設計 W1——Prismix P4 裂核殘響(#814;T6 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §115 | v24 EX 全面重設計 W2——Syrona 窯心暴走+Voidra 內核裸奔(#814;T6 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §116 | v24 EX 全面重設計 W3——Jellord 果凍狂潮+Noctra 月相雙血條+皇冠共鳴(#814;T6 收斂) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | -| §117 | 物理/視覺縮放解耦 visualScale(#819 子項 3;T7-B 列車) | [`00-foundations.md`](design/00-foundations.md) | -| §118 | 使用者設定 SSOT、存檔備援與 PWA 更新閘(#819;T7-A 列車) | [`05-save-settings.md`](design/05-save-settings.md) | +| 章號 | 標題 | 檔案 | +| ---- | ------------------------------------------------------------------------------------ | ----------------------------------------------------- | +| §1 | 產品定位 | [`00-foundations.md`](design/00-foundations.md) | +| §2 | 核心循環 | [`00-foundations.md`](design/00-foundations.md) | +| §3 | 場景流程 | [`00-foundations.md`](design/00-foundations.md) | +| §4 | 操作(行動裝置優先) | [`01-controls-input.md`](design/01-controls-input.md) | +| §5 | 角色設定(全部原創) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §6 | 魔王 AI(有限狀態機,pure TS 可測) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §7 | 戰鬥數值 | [`02-combat-star.md`](design/02-combat-star.md) | +| §8 | Juice 清單(品質關鍵,全數必做) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §9 | 音效(zzfx,零音檔資產) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §10 | 美術資產規格(codex imagegen 專用;除此之外嚴禁動用 codex) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §11 | 技術架構 | [`00-foundations.md`](design/00-foundations.md) | +| §12 | 品質門檻 | [`00-foundations.md`](design/00-foundations.md) | +| §13 | 安全與合規 | [`00-foundations.md`](design/00-foundations.md) | +| §14 | 效能與範圍紀律 | [`00-foundations.md`](design/00-foundations.md) | +| §15 | 關卡系統(levels.ts 為 SSOT,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §16 | 新怪物 ×2(多樣性;全原創) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §17 | 魔王關演出強化(動畫品質關鍵) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §18 | 動畫流暢度打磨清單(全實體) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §19 | v2 美術資產增補(codex 專用;生成尺寸同 §10 規範) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §20 | 技能系統:吞噬賦星(v2.1,PM 親撰) | [`02-combat-star.md`](design/02-combat-star.md) | +| §21 | v3 橫式轉向(PM 親撰) | [`01-controls-input.md`](design/01-controls-input.md) | +| §22 | iOS 觸控直通(研究回寫後定稿) | [`01-controls-input.md`](design/01-controls-input.md) | +| §23 | 技能組合 v3:吞噬連鎖(表驅動,logic/skills.ts) | [`02-combat-star.md`](design/02-combat-star.md) | +| §24 | 關卡彩蛋(data-driven:levels.ts easterEggs[]) | [`04-levels-world.md`](design/04-levels-world.md) | +| §25 | 背景連續感與視覺升級 | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §26 | 反卡死保證(softlock 防護,全部 MUST) | [`08-safety-nets.md`](design/08-safety-nets.md) | +| §27 | v3 美術資產(codex 專用;橫向平鋪) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §28 | v4 免轉向橫式與響應寬幅(PM 親撰) | [`01-controls-input.md`](design/01-controls-input.md) | +| §29 | v4 平台玩法元素包(調研回寫後定案數值) | [`04-levels-world.md`](design/04-levels-world.md) | +| §30 | v4 內容擴充:新技能、新怪物、魔王 P3(PM 親撰) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §31 | v4 美術資產(codex 專用) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §32 | 場景裝飾密度規範 | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §33 | v5 iOS PWA UX 調研回寫(2026-07-15 定稿) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §34 | v5 控制布局重設計與按鈕自訂 | [`01-controls-input.md`](design/01-controls-input.md) | +| §35 | v5 暫停系統與離頁自動暫停 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §36 | v5 開場主選單與圖鑑/技能介紹 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §37 | v5 全元素位置稽核 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §38 | 存檔系統(core/save.ts 為 SSOT,pure TS 可測) | [`05-save-settings.md`](design/05-save-settings.md) | +| §39 | 迷霧世界地圖(MapScene,data-driven 自 LEVELS) | [`04-levels-world.md`](design/04-levels-world.md) | +| §40 | v6 新技能:殼盾與雷鏈(PM 原創,補防禦與群戰原型) | [`02-combat-star.md`](design/02-combat-star.md) | +| §41 | v6 移動手感打磨(logic/movement.ts,pure TS 可測) | [`01-controls-input.md`](design/01-controls-input.md) | +| §42 | 版本號顯示 | [`00-foundations.md`](design/00-foundations.md) | +| §43 | 每關攻略 PoC 與反卡關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | +| §44 | v7 下衝擊觸發改制與跳躍鍵輸入矩陣(PM 親撰,取代 §23 下+B 觸發) | [`01-controls-input.md`](design/01-controls-input.md) | +| §45 | v7 走動手感根修與抖動歸因(logic/walkFeel.ts,pure TS 可測) | [`01-controls-input.md`](design/01-controls-input.md) | +| §46 | v7 雙味混合星彈(config STAR_MIXES 為 SSOT,表驅動) | [`02-combat-star.md`](design/02-combat-star.md) | +| §47 | v7 新怪物 ×2(全原創;素材 codex imagegen 僅此 2 張,風格與既有嚴格一致) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §48 | v7 中魔王精英系統(levels.ts elite 為 SSOT,零新美術) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §49 | v7 每關攻略 PoC 與節奏補訂(引入→練習→考驗→獎勵) | [`04-levels-world.md`](design/04-levels-world.md) | +| §50 | v8 關卡 4→7 與雙魔王總覽(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | +| §51 | v8 上升氣流機制(logic/updraft.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §52 | v8 新怪物 ×3 與雙精英(FSM-first;素材 §55) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §53 | v8 星彈九系與新混合三式(config 表驅動擴充) | [`02-combat-star.md`](design/02-combat-star.md) | +| §54 | v8 第二魔王:暗月蝠王 Noctra(logic/noctraFsm.ts 表驅動,空中型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §55 | v8 美術資產(codex imagegen 專用;配額 6/6 用滿) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §56 | v8 每關攻略 PoC 與 anti-softlock 不變式 | [`04-levels-world.md`](design/04-levels-world.md) | +| §57 | v9 星化變身系統(logic/transform.ts 純狀態機,表驅動) | [`02-combat-star.md`](design/02-combat-star.md) | +| §58 | v9 魔王攻略多樣化與 EX 變體(表驅動擴充,禁止散落 scene) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §59 | v9 新怪物 ×2(FSM-first 進 enemyFsm,均歸既有味系) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §60 | v9 關卡 7→9 與世界地圖(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | +| §61 | v9 美術資產(codex imagegen 專用;配額 5/5) | [`07-art-audio-fx.md`](design/07-art-audio-fx.md) | +| §62 | v9 慈悲補血愛心(logic/mercyHeal.ts 純決策,保底機制非資源農場) | [`08-safety-nets.md`](design/08-safety-nets.md) | +| §63 | v9 Noctra 難度根修(實測席稽核回寫;bot 勝率門檻收斂定案) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §64 | v9.1 熱修:Noctra 返空連續飛行與星暴無敵窗(P0) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §65 | v10 關卡 9→12 與世界地圖(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | +| §66 | v10 星門折躍(logic/warp.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §67 | v10 卡點關中點重生(LevelSpec.checkpointX,§4 主計畫卡點緩解) | [`04-levels-world.md`](design/04-levels-world.md) | +| §68 | v10 第三魔王:稜晶雙子 Prismix(logic/prismixFsm.ts 表驅動,分裂型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §69 | v10 魔王關特殊體系(前室/短期增益/L12 首發;L4/L7 回補延 v11+) | [`04-levels-world.md`](design/04-levels-world.md) | +| §70 | v10 魔王關專屬彩蛋與每關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | +| §71 | v11 糖漿潮汐(logic/tide.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §72 | v11 熱泉噴口(updraft 週期參數化,零新 element kind) | [`04-levels-world.md`](design/04-levels-world.md) | +| §73 | v11 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §74 | v11 第四魔王:Syrona 熔糖窯后(logic/syronaFsm.ts 表驅動,場控型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §75 | v11 魔王關專屬彩蛋與每關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | +| §76 | v11 關卡 12→16 與世界地圖(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | +| §77 | v11.1 熱修:下跳穿落根修、蹲姿指示與吸入豁免 | [`01-controls-input.md`](design/01-controls-input.md) | +| §78 | v12 分區分頁世界地圖(logic/zones.ts+MapScene,主計畫 §2.2 硬項落地) | [`04-levels-world.md`](design/04-levels-world.md) | +| §79 | v12 流星雨(logic/meteor.ts+systems/meteor.ts,pure TS 可測) | [`04-levels-world.md`](design/04-levels-world.md) | +| §80 | v12 新怪物 ×2(FSM-first 進 enemyFsm;零新星味裁決延續 §8 主計畫) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §81 | v12 低重力(LevelSpec.gravityScale,零新 element kind) | [`04-levels-world.md`](design/04-levels-world.md) | +| §82 | v12 最終魔王:蝕星魔核 Voidra(logic/voidraFsm.ts 表驅動,場控收束型) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §83 | v12 魔王關專屬彩蛋與每關驗證 | [`04-levels-world.md`](design/04-levels-world.md) | +| §84 | v12 關卡 16→20 與全線收尾(levels.ts 資料驅動擴充) | [`04-levels-world.md`](design/04-levels-world.md) | +| §85 | v12.1 熱修:真實觸控下滑判定重修(補訂 §21/§23/§77) | [`01-controls-input.md`](design/01-controls-input.md) | +| §86 | v13 EX 全魔王與星核制霸(EX 體系收尾+全制霸獎勵) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §87 | v14 直持預設旋轉方向翻轉(取代 §28 預設方向) | [`01-controls-input.md`](design/01-controls-input.md) | +| §88 | v14 按鈕配置頁操作列直欄化與標籤單行(取代 §34 操作列) | [`01-controls-input.md`](design/01-controls-input.md) | +| §89 | v14 虛擬鍵大小自訂(sp-key-layout schema v2) | [`01-controls-input.md`](design/01-controls-input.md) | +| §90 | v14 PWA 安裝偵測與分平台指引 | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §91 | v14 觸覺回饋與螢幕常亮(調研加碼,ROI 閘通過二項) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §92 | v14 殼層卡片基建(shellCards.ts) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §93 | v14 殼局部 safe-area 量測(canvas 內 HUD 避讓預備) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §94 | v15 成就系統(logic/achievements.ts,純呈現層聚合) | [`05-save-settings.md`](design/05-save-settings.md) | +| §95 | v16 直持預設鍵位重錨(D1,取代 §34 預設在直持殼的適用性) | [`01-controls-input.md`](design/01-controls-input.md) | +| §96 | v16 圖鑑分頁有界網格(P1-01,取代 §36 技能雙欄與 §94.3 成就網格常數) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §97 | v16 區/關命名層級標示(F-01 裁決) | [`04-levels-world.md`](design/04-levels-world.md) | +| §98 | v16 選單 DOM 鈕命中短邊保底(D2,補充 §33 條目 7) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §99 | v16 版本頁腳 SHA 來源修正(F-02,補充 §42) | [`00-foundations.md`](design/00-foundations.md) | +| §100 | v16 勝利結算「下一關」主 CTA(D3,取代 §39 勝利回地圖單一動線) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §101 | v16 HUD 暫停/靜音 DOM 化(F-06+D4,取代 §35 暫停鍵與修復包 B 靜音鈕的命中層) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §102 | v16 配置模式遮罩加深(F-04,補充 §34) | [`01-controls-input.md`](design/01-controls-input.md) | +| §103 | v16 標題字形品牌化(D6,補充 §36) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §104 | v16 怪物圖鑑分頁(F-03,取代 §76 單頁定案) | [`06-ui-shell-pwa.md`](design/06-ui-shell-pwa.md) | +| §105 | v16 前期節奏保守調參(D5+F-05,補充 §15 教學關與 §48 精英房) | [`04-levels-world.md`](design/04-levels-world.md) | +| §106 | GameScene strangler 拆解與守門(三席維護性 5/7/8 收斂) | [`00-foundations.md`](design/00-foundations.md) | +| §107 | 走動關供給保證與滿潮平衡(issue #804/#805/#806) | [`08-safety-nets.md`](design/08-safety-nets.md) | +| §108 | 難度量化工具(#818,T1 量測基礎設施) | [`08-safety-nets.md`](design/08-safety-nets.md) | +| §109 | v19 星暴 2.0+SP 情境鍵+B 鍵收斂(#815,修 #812 輸入面;輸入層 SSOT) | [`01-controls-input.md`](design/01-controls-input.md) | +| §110 | v20 變身系統 2.0——三形態加深+教學矩陣(#816;T4 列車) | [`02-combat-star.md`](design/02-combat-star.md) | +| §111 | v21 魔王主題化 W1——加權選招+Jellord/Noctra 主題招式(#813;T5 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §112 | v22 魔王主題化 W2——Prismix/Syrona 加權選招與主題招式(#813;T5 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §113 | v23 魔王主題化 W3——Voidra 加權選招與星光虹吸(#813;T5 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §114 | v24 EX 全面重設計 W1——Prismix P4 裂核殘響(#814;T6 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §115 | v24 EX 全面重設計 W2——Syrona 窯心暴走+Voidra 內核裸奔(#814;T6 列車) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §116 | v24 EX 全面重設計 W3——Jellord 果凍狂潮+Noctra 月相雙血條+皇冠共鳴(#814;T6 收斂) | [`03-enemies-bosses.md`](design/03-enemies-bosses.md) | +| §117 | 物理/視覺縮放解耦 visualScale(#819 子項 3;T7-B 列車) | [`00-foundations.md`](design/00-foundations.md) | +| §118 | 使用者設定 SSOT、存檔備援與 PWA 更新閘(#819;T7-A 列車) | [`05-save-settings.md`](design/05-save-settings.md) | diff --git a/apps/starpuff/package.json b/apps/starpuff/package.json index 0ae35c922..b055b1eba 100644 --- a/apps/starpuff/package.json +++ b/apps/starpuff/package.json @@ -14,7 +14,8 @@ "lint": "eslint src --ext .ts,.tsx", "lint:fix": "eslint src --ext .ts,.tsx --fix", "test:e2e": "playwright test", - "audit:level": "node scripts/level-audit.mjs" + "audit:level": "node scripts/level-audit.mjs", + "verify:docs": "node scripts/verify-design-docs.mjs" }, "dependencies": { "phaser": "^4.2.1", diff --git a/apps/starpuff/scripts/verify-design-docs.mjs b/apps/starpuff/scripts/verify-design-docs.mjs new file mode 100644 index 000000000..3aaa43435 --- /dev/null +++ b/apps/starpuff/scripts/verify-design-docs.mjs @@ -0,0 +1,189 @@ +// 設計文件守門(T7-C):docs/GAME_DESIGN.md 索引是拆檔後唯一的「章號 → 檔案」解析器, +// 而 src 註解有 77 處直接引用 §N——索引一旦失真,可導航性承諾即失效且不會有人發現。 +// 本腳本把「索引與章節標題一致」「主句紀律」「零錨點引用」機械化,供 vitest 與 CLI 共用。 +// +// CLI:node apps/starpuff/scripts/verify-design-docs.mjs +// 測試:scripts/verify-design-docs.test.mjs(掛進 pnpm test) + +import { readFileSync, readdirSync } from 'node:fs'; +import { execFileSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url)); +const DOCS_DIR = join(SCRIPT_DIR, '..', 'docs'); +const DESIGN_DIR = join(DOCS_DIR, 'design'); +const INDEX_FILE = join(DOCS_DIR, 'GAME_DESIGN.md'); +const REPO_ROOT = join(SCRIPT_DIR, '..', '..', '..'); + +// 主題檔命名契約:0*.md 為現行規格檔,99-superseded.md 為歷史檔(不含 `## N.` 章節)。 +const SECTION_FILE_PATTERN = /^0\d-[a-z-]+\.md$/; +const HISTORY_FILE = '99-superseded.md'; + +// 取代附註的唯一合法形狀(99-superseded.md「主句紀律」章定義)。 +const DEPRECATION_LINE = /^> \*\*已廢止\*\*([^)]+):.+/; +// 主句紀律違規樣態:把過期規則留在主句、修正塞進行內括號。 +const INLINE_SUPERSESSION = /(v\d+(\.\d+)? 已(由|於) §/; + +function listSectionFiles() { + return readdirSync(DESIGN_DIR) + .filter((name) => SECTION_FILE_PATTERN.test(name)) + .sort(); +} + +// 解析 `## N. 標題`;回傳 [{ num, title, file, line }]。 +function parseHeadings(file) { + const text = readFileSync(join(DESIGN_DIR, file), 'utf8'); + const out = []; + text.split('\n').forEach((line, i) => { + const m = /^## (\d+)\. (.*)$/.exec(line); + if (m) out.push({ num: Number(m[1]), title: m[2].trim(), file, line: i + 1 }); + }); + return out; +} + +// 解析索引表列 `| §N | 標題 | [`檔名`](design/檔名) |`(prettier 會補對齊空白)。 +function parseIndexRows() { + const text = readFileSync(INDEX_FILE, 'utf8'); + const rows = []; + text.split('\n').forEach((line, i) => { + const m = /^\|\s*§(\d+)\s*\|(.*?)\|\s*\[`([^`]+)`\]\(design\/([^)]+)\)\s*\|/.exec(line); + if (m) { + rows.push({ + num: Number(m[1]), + title: m[2].trim(), + label: m[3], + file: m[4], + line: i + 1, + }); + } + }); + return rows; +} + +// 錨點引用掃描:拆檔後 GAME_DESIGN.md 不再有章節錨點,任何 `GAME_DESIGN.md#` 連結必然死鏈。 +function findAnchorReferences() { + const tracked = execFileSync('git', ['ls-files', '-z'], { + cwd: REPO_ROOT, + encoding: 'utf8', + maxBuffer: 64 * 1024 * 1024, + }) + .split('\0') + .filter(Boolean); + const hits = []; + for (const rel of tracked) { + if (!/\.(md|ts|tsx|mjs|js|json|ya?ml)$/.test(rel)) continue; + let text; + try { + text = readFileSync(join(REPO_ROOT, rel), 'utf8'); + } catch { + continue; + } + if (!text.includes('GAME_DESIGN.md#')) continue; + text.split('\n').forEach((line, i) => { + if (line.includes('GAME_DESIGN.md#')) hits.push(`${rel}:${i + 1}`); + }); + } + return hits; +} + +export function verifyDesignDocs() { + const problems = []; + const files = listSectionFiles(); + if (files.length === 0) problems.push('design/ 下找不到任何 0*.md 主題檔'); + + // 1. 章節標題彙整與重複檢查。 + const headings = new Map(); + for (const file of files) { + for (const h of parseHeadings(file)) { + const prev = headings.get(h.num); + if (prev) { + problems.push(`§${h.num} 重複定義:${prev.file}:${prev.line} 與 ${h.file}:${h.line}`); + continue; + } + headings.set(h.num, h); + } + } + + // 2. 章號連續無缺號(新增章節必須接續遞增,不得跳號或回收)。 + const nums = [...headings.keys()].sort((a, b) => a - b); + if (nums.length > 0) { + if (nums[0] !== 1) problems.push(`章號未自 §1 起算(實得 §${nums[0]})`); + for (let i = 1; i < nums.length; i += 1) { + if (nums[i] !== nums[i - 1] + 1) { + problems.push(`章號不連續:§${nums[i - 1]} 之後跳到 §${nums[i]}`); + } + } + } + + // 3. 索引表逐列核對:存在性、檔名正確、零重複、標題同步。 + const rows = parseIndexRows(); + const seenRows = new Set(); + for (const row of rows) { + if (seenRows.has(row.num)) { + problems.push(`索引 §${row.num} 重複列(GAME_DESIGN.md:${row.line})`); + continue; + } + seenRows.add(row.num); + if (row.label !== row.file) { + problems.push(`索引 §${row.num} 連結文字與路徑不符:${row.label} vs design/${row.file}`); + } + const h = headings.get(row.num); + if (!h) { + problems.push(`索引 §${row.num} 指向不存在的章節(GAME_DESIGN.md:${row.line})`); + continue; + } + if (h.file !== row.file) { + problems.push(`索引 §${row.num} 指向 ${row.file},實際位於 ${h.file}`); + } + if (h.title !== row.title) { + problems.push(`索引 §${row.num} 標題與章節不同步:「${row.title}」vs「${h.title}」`); + } + } + for (const num of nums) { + if (!seenRows.has(num)) problems.push(`§${num}(${headings.get(num).file})未登記於索引表`); + } + + // 4. 每檔職責範圍聲明(讀者不需要猜這檔放什麼)。 + for (const file of [...files, HISTORY_FILE]) { + const text = readFileSync(join(DESIGN_DIR, file), 'utf8'); + if (!text.includes('**職責範圍**')) problems.push(`${file} 缺「職責範圍」聲明`); + if (!text.includes('**不在本檔**')) problems.push(`${file} 缺「不在本檔」邊界聲明`); + } + + // 5. 主句紀律:取代註記必須是獨立「已廢止」附註,不得以行內括號夾在主句裡。 + for (const file of [...files, HISTORY_FILE]) { + const text = readFileSync(join(DESIGN_DIR, file), 'utf8'); + let inFence = false; + text.split('\n').forEach((line, i) => { + if (line.startsWith('```')) inFence = !inFence; + if (inFence) return; + if (INLINE_SUPERSESSION.test(line)) { + problems.push(`${file}:${i + 1} 行內取代標註——舊規則須降級為「已廢止」附註`); + } + if (line.startsWith('> **已廢止**') && !DEPRECATION_LINE.test(line)) { + problems.push( + `${file}:${i + 1} 已廢止附註格式不符(應為 > **已廢止**(<版本> 起,現行見 §<章號>):<舊敘述>)`, + ); + } + }); + } + + // 6. 全 repo 零 GAME_DESIGN.md 錨點引用。 + for (const hit of findAnchorReferences()) { + problems.push(`${hit} 使用 GAME_DESIGN.md 錨點連結——拆檔後必為死鏈,改引用 §N`); + } + + return { problems, sectionCount: headings.size, indexRowCount: rows.length, files }; +} + +if (process.argv[1] === fileURLToPath(import.meta.url)) { + const { problems, sectionCount, indexRowCount, files } = verifyDesignDocs(); + console.log(`主題檔 ${files.length} 個、章節 ${sectionCount} 章、索引 ${indexRowCount} 列`); + if (problems.length > 0) { + console.error(`\n設計文件守門失敗(${problems.length} 項):`); + problems.forEach((p) => console.error(` - ${p}`)); + process.exit(1); + } + console.log('設計文件守門通過:索引與章節一致、主句紀律成立、零錨點引用'); +} diff --git a/apps/starpuff/scripts/verify-design-docs.test.mjs b/apps/starpuff/scripts/verify-design-docs.test.mjs new file mode 100644 index 000000000..42c8d9cf2 --- /dev/null +++ b/apps/starpuff/scripts/verify-design-docs.test.mjs @@ -0,0 +1,41 @@ +import { describe, expect, it } from 'vitest'; + +import { verifyDesignDocs } from './verify-design-docs.mjs'; + +// 設計文件守門(T7-C):索引是拆檔後唯一的「章號 → 檔案」解析器,失真不會有人發現, +// 故機械化為測試。負向案確保守門本身不是空轉——規則真的抓得到漂移。 + +describe('設計文件守門', () => { + const result = verifyDesignDocs(); + + it('索引與章節標題完全一致、主句紀律成立、零錨點引用', () => { + expect(result.problems).toEqual([]); + }); + + it('章節與索引列數相符且已涵蓋全部主題檔', () => { + expect(result.sectionCount).toBe(result.indexRowCount); + expect(result.sectionCount).toBeGreaterThan(0); + expect(result.files.length).toBeGreaterThan(0); + }); +}); + +describe('守門規則負向驗證(規則本身抓得到漂移)', () => { + // 與 verify-design-docs.mjs 同源的兩條樣態規則;此處獨立重述以確保語意不被誤放寬。 + const inlineSupersession = /(v\d+(\.\d+)? 已(由|於) §/; + const deprecationLine = /^> \*\*已廢止\*\*([^)]+):.+/; + + it('抓得到行內取代標註(審查必修 1 的回歸樣態)', () => { + expect(inlineSupersession.test('- 地面長按 0.6s 觸發(v19 已由 §109 取代:改 SP 鍵)')).toBe( + true, + ); + expect(inlineSupersession.test('- 同系 ≥3 且在地面時按 SP 鍵點按立即變身。')).toBe(false); + }); + + it('抓得到格式不符的已廢止附註', () => { + expect( + deprecationLine.test('> **已廢止**(v19 起,現行見 §109.2):地面長按 0.6s 觸發。'), + ).toBe(true); + expect(deprecationLine.test('> **已廢止**:地面長按 0.6s 觸發。')).toBe(false); + expect(deprecationLine.test('> **已廢止**(v19 起,現行見 §109.2):')).toBe(false); + }); +}); diff --git a/apps/starpuff/vitest.config.ts b/apps/starpuff/vitest.config.ts index 7b36a90a5..2ac83abc5 100644 --- a/apps/starpuff/vitest.config.ts +++ b/apps/starpuff/vitest.config.ts @@ -4,7 +4,8 @@ export default defineConfig({ test: { environment: 'node', globals: true, - include: ['src/**/*.test.ts'], + // scripts 的 .mjs 測試僅供設計文件守門(T7-C);src 仍為 .test.ts 唯一來源。 + include: ['src/**/*.test.ts', 'scripts/**/*.test.mjs'], exclude: ['node_modules', 'dist'], }, }); diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index 73e36dda0..263931ecb 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:reward-starpuff-t7c-r2-design-docs-gate +- 原因:拆檔後 GAME_DESIGN 索引是唯一的「章號 → 檔案」解析器(src 有 77 處 §N 引用),卻零 CI 守門——本輪正確性全靠一次性腳本與兩席人工重算,未來新增 §119 漏登索引或誤重複編號不會被攔截,索引會悄悄失真 +- 解法:新增 `apps/starpuff/scripts/verify-design-docs.mjs`(索引存在性/檔名/零重複/零缺號/標題同步、每檔職責聲明、主句紀律附註格式、全 repo 零錨點引用六項)+同名 .test.mjs 掛進 vitest(include 增 scripts/\*_/_.test.mjs)與 `pnpm verify:docs`;上線即抓到我自己漏更的 §60/§65 索引標題,另以四種故障注入實證守門非空轉 + - 日期:2026-07-26 - ID:reward-starpuff-t7c-r2-supersession-main-clause-inversion - 原因:審查 Grok 席指出取代寫法方向錯誤——過期規則仍是主句、修正只在括號裡(如 §57 主句仍寫「地面長按 0.6s 變身」),掃讀者會照舊規格實作,changeset 承諾的「可直接判斷哪段有效」名實不符;另 01 檔頭宣告「不在本檔:按下之後發生什麼事」卻承載 §109.3 星暴狀態機 From db666455636bc7f8123a9e7e813144da974efcd3 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 11:14:47 +0800 Subject: [PATCH 08/14] =?UTF-8?q?fix(starpuff):=20=E8=A8=AD=E8=A8=88?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=AE=88=E9=96=80=E6=8E=92=E9=99=A4=E8=87=AA?= =?UTF-8?q?=E8=BA=AB=E9=81=BF=E5=85=8D=E6=AA=A2=E8=88=89=E8=87=AA=E5=B7=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 掃描器內含 GAME_DESIGN 錨點偵測字面值,入版控後被自己掃出三筆偽陽性 - 自身路徑改由 import.meta.url 推導後排除(非硬編,搬移改名仍成立) 測試:pnpm --filter @app/starpuff test:run 69 檔 936 案全綠; 另注入他檔錨點驗證自我排除未削弱偵測(07-art-audio-fx.md 仍被抓出) Co-authored-by: Cursor --- apps/starpuff/scripts/verify-design-docs.mjs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/starpuff/scripts/verify-design-docs.mjs b/apps/starpuff/scripts/verify-design-docs.mjs index 3aaa43435..15fb512b2 100644 --- a/apps/starpuff/scripts/verify-design-docs.mjs +++ b/apps/starpuff/scripts/verify-design-docs.mjs @@ -8,7 +8,7 @@ import { readFileSync, readdirSync } from 'node:fs'; import { execFileSync } from 'node:child_process'; import { fileURLToPath } from 'node:url'; -import { dirname, join } from 'node:path'; +import { dirname, join, relative, sep } from 'node:path'; const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url)); const DOCS_DIR = join(SCRIPT_DIR, '..', 'docs'); @@ -62,6 +62,12 @@ function parseIndexRows() { } // 錨點引用掃描:拆檔後 GAME_DESIGN.md 不再有章節錨點,任何 `GAME_DESIGN.md#` 連結必然死鏈。 +// 本檔自身帶有偵測字面值,必須自我排除,否則掃描器會檢舉自己。路徑自 import.meta.url +// 推導(非硬編),檔案搬移或改名時排除仍然成立。 +const SELF_REL_PATH = relative(REPO_ROOT, fileURLToPath(import.meta.url)) + .split(sep) + .join('/'); + function findAnchorReferences() { const tracked = execFileSync('git', ['ls-files', '-z'], { cwd: REPO_ROOT, @@ -72,6 +78,7 @@ function findAnchorReferences() { .filter(Boolean); const hits = []; for (const rel of tracked) { + if (rel === SELF_REL_PATH) continue; if (!/\.(md|ts|tsx|mjs|js|json|ya?ml)$/.test(rel)) continue; let text; try { From 971a33887d38c7470dd90a5e2da59b9b18283a5f Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 11:24:49 +0800 Subject: [PATCH 09/14] =?UTF-8?q?docs(starpuff):=20=E8=A3=9C=E8=A8=98?= =?UTF-8?q?=E5=AE=88=E9=96=80=E8=87=AA=E6=88=91=E6=8E=92=E9=99=A4=20002=20?= =?UTF-8?q?=E6=A2=9D=E7=9B=AE=E4=B8=A6=E9=87=8D=E7=AE=97=20PR=20=E8=81=9A?= =?UTF-8?q?=E5=90=88=E8=A8=98=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 neutral 條目記錄 verify-design-docs 自我檢舉偽陽性的成因與修法 - 檔頭記分行重算:本 PR 共 7 條(reward 5、penalty 0、neutral 2),淨 +5、累計 +247 測試:prettier 3.8.1 通過;純文件變更未跑 vitest Co-authored-by: Cursor --- docs/dev/002_development_reward_penalty_log.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index 263931ecb..42cc7487a 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:neutral-starpuff-t7c-r2-gate-self-exclusion +- 原因:verify-design-docs.mjs 自身含 GAME_DESIGN 錨點偵測字面值,未入版控時 git ls-files 掃不到故 CLI 綠燈,commit 後轉為 tracked 即自我檢舉三筆偽陽性,pre-push 擋下 +- 解法:以 import.meta.url 推導自身相對路徑後排除(非硬編,搬移改名仍成立);另注入他檔錨點複驗自我排除未削弱偵測能力 + - 日期:2026-07-26 - ID:reward-starpuff-t7c-r2-design-docs-gate - 原因:拆檔後 GAME_DESIGN 索引是唯一的「章號 → 檔案」解析器(src 有 77 處 §N 引用),卻零 CI 守門——本輪正確性全靠一次性腳本與兩席人工重算,未來新增 §119 漏登索引或誤重複編號不會被攔截,索引會悄悄失真 From 113d204e7fc9c9474503f39d965dd920f8463a13 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 12:13:44 +0800 Subject: [PATCH 10/14] =?UTF-8?q?docs(starpuff):=20=E4=BF=AE=E6=AD=A3=20?= =?UTF-8?q?=C2=A760=20L8=20hint=20=E4=B8=BB=E5=8F=A5=E8=88=87=E5=AF=A6?= =?UTF-8?q?=E4=BD=9C=E8=A1=9D=E7=AA=81=EF=BC=88=E8=A4=87=E5=AF=A9=E5=BF=85?= =?UTF-8?q?=E4=BF=AE=20HIGH=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 主句改為與 levels.ts:613 逐字一致的「站在地面按 SP 鍵星化變身」並加綁定標記 - 舊文案「地面長按吸入鍵 0.6 秒」降級為已廢止附註 - 該句原本無取代標註,故首輪 sweep 與守門的行內標註規則皆掃不到 測試:verify-design-docs 通過;逐字比對 levels.ts hint 與文件引述一致;prettier 通過 Co-authored-by: Cursor --- apps/starpuff/docs/design/04-levels-world.md | 7 +++++-- docs/dev/002_development_reward_penalty_log.md | 5 +++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/starpuff/docs/design/04-levels-world.md b/apps/starpuff/docs/design/04-levels-world.md index db7973795..9ac3ca386 100644 --- a/apps/starpuff/docs/design/04-levels-world.md +++ b/apps/starpuff/docs/design/04-levels-world.md @@ -172,8 +172,11 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 - 新組合情境:L8 磁場(彈道不可靠)×drilly(地下突襲)→ 近戰/下砸/星化應對; L9 鏡面反射 × 雙移動平台/雙彈簧 → 反射窗躲位靠垂直機動;magno/mirri 雙新怪同場。 - L8 開場 hint 浮字(LevelSpec.hint 資料驅動,沿教學浮字機制):首次星化教學 - 「同系星彈集滿 3 發,地面長按吸入鍵 0.6 秒星化變身」;起手區前 500px 無精英 - 無破磚(安全教學帶)。 + 「同系星彈集滿 3 發,站在地面按 SP 鍵星化變身」(`levels.ts` L8 hint);起手區前 + 500px 無精英無破磚(安全教學帶)。 + +> **已廢止**(v19 起,現行見 §109.2):hint 文案為「同系星彈集滿 3 發,地面長按吸入鍵 0.6 秒星化變身」——0.6s 長按觸發面整體退場。 + - L9 雙精英:銀鏡鏡面蟲(mirri 基底 HP 17 ×1.4,掉孢子味)+暗磁磁極獸(magno 基底 HP 19 ×1.3,掉迴旋味);房址 1250/2550(房距 1300 ≥ 2×門距)。 - 世界地圖九節點鋸齒路徑;解鎖鏈沿 §39;save schema v1 不變——v8 舊檔(≤7 關)載入 diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index 42cc7487a..cfa035259 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:reward-starpuff-t7c-r3-l8-hint-drift +- 原因:§60 的 L8 開場 hint 主句仍寫「地面長按吸入鍵 0.6 秒星化變身」,與 levels.ts:613 實值、WALKTHROUGH 與我自己改好的 §57 三處衝突;因該句「沒有帶取代標註」,必修 1 的 sweep 與守門的行內標註規則都掃不到(複審 Grok REQUEST_CHANGES 唯一理由) +- 解法:主句改為與 levels.ts:613 逐字一致的 SP 文案並加 `levels.ts` L8 hint 綁定標記,舊文案降級為已廢止附註;此漏網暴露「無標註過期內容」的守門盲區,後續以 doc↔code 引述綁定檢查根治 + - 日期:2026-07-26 - ID:neutral-starpuff-t7c-r2-gate-self-exclusion - 原因:verify-design-docs.mjs 自身含 GAME_DESIGN 錨點偵測字面值,未入版控時 git ls-files 掃不到故 CLI 綠燈,commit 後轉為 tracked 即自我檢舉三筆偽陽性,pre-push 擋下 From d2a19dd1e36b0d64e3f0c45597b343187ca9a736 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 12:17:25 +0800 Subject: [PATCH 11/14] =?UTF-8?q?docs(starpuff):=20=E6=94=B6=E4=B9=BE=2002?= =?UTF-8?q?=20=E6=AA=94=E9=A0=AD=E8=87=AA=E7=9B=B8=E7=9F=9B=E7=9B=BE?= =?UTF-8?q?=E8=88=87=E5=9B=9B=E7=AF=80=E7=AF=80=E9=BB=9E=E5=AE=A3=E5=91=8A?= =?UTF-8?q?=EF=BC=88=E8=A4=87=E5=AF=A9=E5=BF=85=E4=BF=AE=20MEDIUM=201?= =?UTF-8?q?=EF=BC=8F3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 02 檔頭不再宣稱 §23/§40 星暴敘述皆為歷史值——§23 主句已是現行的自動結晶+SP - §50/§60/§65/§76 正文的「七/九/十二/十六節點單頁鋸齒」改為中性的新增節點敘述 - 舊佈局降級為已廢止附註(現行五區分頁見 §78);§50/§76 補齊引導句與 §60/§65 同構 測試:verify-design-docs 通過;rg 確認正文零殘留節點總數宣告;prettier 通過 Co-authored-by: Cursor --- apps/starpuff/docs/design/02-combat-star.md | 2 +- apps/starpuff/docs/design/04-levels-world.md | 32 +++++++++++++------ .../dev/002_development_reward_penalty_log.md | 5 +++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/apps/starpuff/docs/design/02-combat-star.md b/apps/starpuff/docs/design/02-combat-star.md index 955b118a1..ff94a0330 100644 --- a/apps/starpuff/docs/design/02-combat-star.md +++ b/apps/starpuff/docs/design/02-combat-star.md @@ -6,7 +6,7 @@ > > **硬不變式**:混合星與變身**永不為破關必需**——基礎星彈恆可通關(§46/§57/§110)。 > -> **星暴現行規格=§109.3**(`01-controls-input.md`):滿 5 槽自動結晶為蓄能星、按 SP 引爆。本檔 §23/§40 內的星暴敘述均為 v19 前的歷史值。 +> **星暴完整規格=§109.3**(`01-controls-input.md`):滿 5 槽自動結晶為蓄能星、按 SP 引爆、跨關持有與死亡清除。本檔 §23/§40 只寫到與星彈系統交界的部分;v19 前的 B 長按觸發面見各該節的已廢止附註。 > > **閱讀慣例**:每一句主文都是現行有效規則;被取代的舊規則一律降級為緊接其後的 `> **已廢止**` 附註,僅供追溯。索引與取代對照見 [`../GAME_DESIGN.md`](../GAME_DESIGN.md) 與 [`99-superseded.md`](99-superseded.md)。章號 §N 為全專案穩定識別碼(程式註解直接引用),拆檔不重新編號。 diff --git a/apps/starpuff/docs/design/04-levels-world.md b/apps/starpuff/docs/design/04-levels-world.md index 9ac3ca386..aadf64ce0 100644 --- a/apps/starpuff/docs/design/04-levels-world.md +++ b/apps/starpuff/docs/design/04-levels-world.md @@ -103,10 +103,13 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 ## 50. v8 關卡 4→7 與雙魔王總覽(levels.ts 資料驅動擴充) -本批新增 L5-L7(第二魔王暗月蝠王收尾);**全線編成現行值見 §84(五區二十關)**。解鎖鏈沿 §39 -(第 N 關需 N-1 通關);世界地圖擴為七節點鋸齒路徑(節點半徑收斂 30),新節點沿用 -迷霧鎖定態。save schema v1 不變——舊存檔(≤4 關條目)原樣載入,L5 依解鎖規則自然 -開放、L6/L7 鎖定(相容契約見 save.test「v8 存檔相容」與 e2e「舊存檔相容」案)。 +**下表 L5–L7 為現行關卡規格**;本節當時的「七關/七節點」總數宣告已由 §84(二十關)與 §78(五區分頁)取代。 + +本批新增 L5-L7(第二魔王暗月蝠王收尾)。解鎖鏈沿 §39(第 N 關需 N-1 通關),世界地圖 +新增三節點、沿用迷霧鎖定態。save schema v1 不變——舊存檔(≤4 關條目)原樣載入,L5 依 +解鎖規則自然開放、L6/L7 鎖定(相容契約見 save.test「v8 存檔相容」與 e2e「舊存檔相容」案)。 + +> **已廢止**(v12 §78 起):當時的「七節點單頁鋸齒路徑、節點半徑收斂 30」佈局。 | # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | | --- | -------- | ---------- | ------ | ---- | ------ | ------------------------------ | ---------------- | @@ -179,8 +182,11 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 - L9 雙精英:銀鏡鏡面蟲(mirri 基底 HP 17 ×1.4,掉孢子味)+暗磁磁極獸(magno 基底 HP 19 ×1.3,掉迴旋味);房址 1250/2550(房距 1300 ≥ 2×門距)。 -- 世界地圖九節點鋸齒路徑;解鎖鏈沿 §39;save schema v1 不變——v8 舊檔(≤7 關)載入 +- 世界地圖新增 L8/L9 兩節點;解鎖鏈沿 §39;save schema v1 不變——v8 舊檔(≤7 關)載入 L8 自然開放、L9 迷霧鎖定(save.test/e2e 守門)。 + +> **已廢止**(v12 §78 起):當時的「九節點單頁鋸齒路徑」佈局——現行為五區分頁,每區一頁 ≤5 節點。 + - 背景重用(§55 慣例,不生成新背景):`bg-cavern`→`bg-eclipse` 貼圖(鋼藍 grade+ 磁塵 ambience)、`bg-mirror`→`bg-arena` 貼圖(銀鏡 grade+鏡光塵 ambience); 道具條沿用 arena 主題(晶洞/鏡晶質感)。 @@ -209,8 +215,11 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 | 11 | 磁晶險徑 | bg-magnetic | 3700 | 13 | 1100ms | 磁力域×折躍複合(卡點一,checkpoint §67) | 雙精英 | | 12 | 稜晶王殿 | bg-prism | 854+前室400 | — | 3000ms | 第三魔王稜晶雙子(§68)+魔王關體系(§69) | — | -- 世界地圖十二節點:佈局由關卡數推導(三階鋸齒、節點半徑 24、魔王節點恆最高階——EX - 徽鈕上方淨空恆成立);雙位數關號縮字級 20px。分區分頁延期(最遲 v12,主計畫 §2.2)。 +- 世界地圖新增 L10–L12 三節點,佈局由關卡數推導(魔王節點恆最高階——EX 徽鈕上方淨空 + 恆成立);雙位數關號縮字級。 + +> **已廢止**(v12 §78 起):當時的「十二節點單頁三階鋸齒、節點半徑 24、關號 20px、分區分頁延期」——現行為五區分頁,每區一頁 ≤5 節點、半徑回復 24。 + - save schema v1 不變:`LEVEL_IDS` 擴至 12;v9 舊檔(≤9 關)載入 L10 自然開放、L11/L12 迷霧鎖定(save.test/e2e 守門)。 - 背景重用(§55 慣例,零新背景):`bg-lumen`→`bg-arena`(幽青 grade+冰青湖光塵)、 @@ -340,6 +349,8 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 ## 76. v11 關卡 12→16 與世界地圖(levels.ts 資料驅動擴充) +**下表 L13–L16 為現行關卡規格**;本節當時的「十六關/十六節點」總數宣告已由 §84(二十關)與 §78(五區分頁)取代。 + | # | 關卡 | bgKey | 世界寬 | 配額 | 間隔 | 主場機制 | 精英 | | --- | -------- | ----------- | ------------ | ---- | ------ | ------------------------------------------------- | --------------- | | 13 | 焙糖丘陵 | bg-kiln | 3300 | 11 | 1400ms | 熱泉噴口首發(§72)×Bubbla/Splatta 亮相 | 焦糖泡霸 ×1 | @@ -347,9 +358,10 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 | 15 | 沸糖窯道 | bg-kilnway | 3800 | 14 | 1100ms | 潮汐×噴口複合 gauntlet(卡點二,checkpoint 1900) | 雙精英 | | 16 | 熔糖王窯 | bg-kilnhall | 854+前室400 | — | 3000ms | 第四魔王 Syrona(§74)+魔王關體系(§69) | — | -- 世界地圖十六節點:節點半徑再收斂 24→20(854 寬間距 ≈51px 單頁可容納);三階鋸齒 - 12 項循環下四魔王節點(L4/L7/L12/L16)恰全落最高階,EX 徽鈕淨空恆成立; - 雙位數關號字級 17px。**分區分頁為 v12 硬項**(主計畫 §2.2,20 節點單頁確定放不下)。 +- 世界地圖新增 L13–L16 四節點;魔王節點(L4/L7/L12/L16)恆落最高階,EX 徽鈕淨空恆成立。 + +> **已廢止**(v12 §78 起):當時的「十六節點單頁、半徑 24→20、三階鋸齒 12 項循環、關號 17px」與「分區分頁列為 v12 硬項」的待辦敘述——分區分頁已於 §78 落地。 + - save schema v1 不變:`LEVEL_IDS` 擴至 16;v10 舊檔(≤12 關)載入 L13 自然開放、 L14-L16 迷霧鎖定(save.test/e2e 守門)。 - 美術(§9 主計畫 v11 批 5 張):`bg-kiln-l`(1536×512 無縫,四關共用 grade 區分)、 diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index cfa035259..988a02238 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:reward-starpuff-t7c-r3-header-and-node-count-cleanup +- 原因:02 檔頭寫「§23/§40 星暴敘述均為 v19 前歷史值」但 §23 主句早已改成現行的自動結晶+SP,檔頭自打臉;§50/§60/§65 正文仍以現在式寫「七/九/十二節點單頁鋸齒」,§76 則缺引導句且正文仍寫十六節點——標題改對了內文沒跟上 +- 解法:02 檔頭改述為「§109.3 為完整規格、本檔只寫與星彈系統交界部分」;四節正文的節點佈局宣告改為「新增 N 節點」中性敘述,舊佈局降級為已廢止附註,§50/§76 補齊與 §60/§65 同構的引導句 + - 日期:2026-07-26 - ID:reward-starpuff-t7c-r3-l8-hint-drift - 原因:§60 的 L8 開場 hint 主句仍寫「地面長按吸入鍵 0.6 秒星化變身」,與 levels.ts:613 實值、WALKTHROUGH 與我自己改好的 §57 三處衝突;因該句「沒有帶取代標註」,必修 1 的 sweep 與守門的行內標註規則都掃不到(複審 Grok REQUEST_CHANGES 唯一理由) From 33b3fd0bd2ad137ba65375056b2bdff3597abfb4 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 12:23:06 +0800 Subject: [PATCH 12/14] =?UTF-8?q?test(starpuff):=20=E5=AE=88=E9=96=80?= =?UTF-8?q?=E8=A3=9C=E3=80=8C=E5=B7=B2=E8=A2=AB=E3=80=8D=E6=A8=A3=E6=85=8B?= =?UTF-8?q?=E4=B8=A6=E6=96=B0=E5=A2=9E=20doc=E2=86=94code=20=E5=BC=95?= =?UTF-8?q?=E8=BF=B0=E7=B6=81=E5=AE=9A=E6=AA=A2=E6=9F=A5=EF=BC=88=E8=A4=87?= =?UTF-8?q?=E5=AF=A9=E5=BF=85=E4=BF=AE=20MEDIUM=202=EF=BC=8B=E5=BB=BA?= =?UTF-8?q?=E8=AD=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - INLINE_SUPERSESSION 補被動語態「已被」,負向測試改參數化鎖三式(已由/已於/已被) - 新增引述綁定:文件標註「引述」(`來源檔.ts` 說明)後守門逐字比對 src,抄舊值即失敗 - 新增 hint 近似網攔截無標註的過期抄寫(Dice bigram,門檻 0.5 依實測校準並以單測鎖住) - 四處既有程式碼字串引述(L8 hint、變身首教浮字、結晶/帶星 toast)全數補上綁定標記 測試:verify-design-docs 通過;三種故障注入皆 exit 1(綁定抄舊值/無標記過期抄寫/ 綁定指向不存在來源檔);vitest 該檔 5 案全綠 Co-authored-by: Cursor --- .../starpuff/docs/design/01-controls-input.md | 4 +- apps/starpuff/docs/design/02-combat-star.md | 2 +- apps/starpuff/scripts/verify-design-docs.mjs | 112 +++++++++++++++++- .../scripts/verify-design-docs.test.mjs | 31 ++++- .../dev/002_development_reward_penalty_log.md | 5 + 5 files changed, 141 insertions(+), 13 deletions(-) diff --git a/apps/starpuff/docs/design/01-controls-input.md b/apps/starpuff/docs/design/01-controls-input.md index 12d98db1d..5e098f9af 100644 --- a/apps/starpuff/docs/design/01-controls-input.md +++ b/apps/starpuff/docs/design/01-controls-input.md @@ -377,8 +377,8 @@ - 不疊加:蓄能星存在時再滿匣不再結晶(HUD 滿匣金色脈動提示;彈匣維持滿可正常 射擊/殼盾)。變身窗口=同系 3–4 發按 SP;滿匣即選擇星暴線(L3 hint 明示一次)。 - 跨關持有/死亡清除/EX 進場清除:session 記憶(`systems/starburstDirector`, - 不動 save schema);首次結晶浮字「星力結晶!按 SP 鍵引爆」、首次帶星過關 toast - 「蓄能星會跟你到下一關」各一次。已知行為(設計取捨):detonating 相位過關 + 不動 save schema);首次結晶浮字「星力結晶!按 SP 鍵引爆」(`starburstDirector.ts` 首次結晶浮字)、 + 首次帶星過關 toast「蓄能星會跟你到下一關」(`starburstDirector.ts` 帶星過關 toast)各一次。已知行為(設計取捨):detonating 相位過關 (0.3s 蓄爆窄窗撞入門)不持有也不結算——引爆效果隨場景凍結靜默丟棄。 - 引爆:SP 點按 → 0.3s 蓄爆(`STARSTORM.chargeMs`,不可取消)→ 清場全小怪+ 魔王 12 傷+5s 無敵窗(沿 §64.2 取 max 不疊加)+既有震屏白閃星雨呈現。 diff --git a/apps/starpuff/docs/design/02-combat-star.md b/apps/starpuff/docs/design/02-combat-star.md index ff94a0330..bc5439041 100644 --- a/apps/starpuff/docs/design/02-combat-star.md +++ b/apps/starpuff/docs/design/02-combat-star.md @@ -170,7 +170,7 @@ - 教學前置完整性由 `levels.test` 圖遍歷守門:任一關 `bossApplies` 機制必已在較早關 `teaches`;機制唯一首教;各魔王關驗收含 `transform`。 - L3 變身首教位點:進關前段(x 460–600)drillSpawns 保證 3 隻 floaty(同系→風化); - SP 資格徽章首次浮現時一次性教學浮字「同系星彈 ×3!按 SP 鍵立即變身」(session 慣例)。 + SP 資格徽章首次浮現時一次性教學浮字「同系星彈 ×3!按 SP 鍵立即變身」(`GameScene.ts` 變身首教浮字,session 慣例)。 - 首教關對映(依 repo 資料實況錨定):L1 吸射、L2 殼盾+下砸、L3 變身+星暴、L5 氣流、 L8 磁力域、L9 鏡性、L10 折躍、L13 噴口、L14 潮汐、L17 低重力、L18 流星讀影。 diff --git a/apps/starpuff/scripts/verify-design-docs.mjs b/apps/starpuff/scripts/verify-design-docs.mjs index 15fb512b2..e9981346f 100644 --- a/apps/starpuff/scripts/verify-design-docs.mjs +++ b/apps/starpuff/scripts/verify-design-docs.mjs @@ -5,7 +5,7 @@ // CLI:node apps/starpuff/scripts/verify-design-docs.mjs // 測試:scripts/verify-design-docs.test.mjs(掛進 pnpm test) -import { readFileSync, readdirSync } from 'node:fs'; +import { readFileSync, readdirSync, statSync } from 'node:fs'; import { execFileSync } from 'node:child_process'; import { fileURLToPath } from 'node:url'; import { dirname, join, relative, sep } from 'node:path'; @@ -19,11 +19,23 @@ const REPO_ROOT = join(SCRIPT_DIR, '..', '..', '..'); // 主題檔命名契約:0*.md 為現行規格檔,99-superseded.md 為歷史檔(不含 `## N.` 章節)。 const SECTION_FILE_PATTERN = /^0\d-[a-z-]+\.md$/; const HISTORY_FILE = '99-superseded.md'; +const SRC_DIR = join(SCRIPT_DIR, '..', 'src'); +const WALKTHROUGH = join(DOCS_DIR, 'WALKTHROUGH.md'); + +// doc↔code 引述綁定:文件引述程式碼字串時標註來源檔,例如 +// 「同系星彈集滿 3 發,站在地面按 SP 鍵星化變身」(`levels.ts` L8 hint) +// 守門逐字比對該字串確實存在於該來源檔,杜絕「文件抄了舊值」這類無標註漂移。 +const QUOTE_BINDING = /「([^」]+)」(`([\w.-]+\.ts)`[^)]*)/g; +// 近似網(僅針對 LevelSpec.hint 九條):抓沒有綁定標記、又與現行 hint 高度相似的引述。 +// 門檻依實測校準——211 筆引述中,非漂移的最高相似度為 0.412 +//(§110.2 的變身首教浮字,與 hint 是不同字串),真漏網的 L8 舊文案為 0.558。 +export const HINT_SIMILARITY_THRESHOLD = 0.5; // 取代附註的唯一合法形狀(99-superseded.md「主句紀律」章定義)。 const DEPRECATION_LINE = /^> \*\*已廢止\*\*([^)]+):.+/; // 主句紀律違規樣態:把過期規則留在主句、修正塞進行內括號。 -const INLINE_SUPERSESSION = /(v\d+(\.\d+)? 已(由|於) §/; +// 被動語態三式(已由/已於/已被)皆須涵蓋——初版漏「已被」,複審實測可繞過守門。 +const INLINE_SUPERSESSION = /(v\d+(\.\d+)? 已(由|於|被) §/; function listSectionFiles() { return readdirSync(DESIGN_DIR) @@ -94,6 +106,90 @@ function findAnchorReferences() { return hits; } +// src 檔案索引(basename → 絕對路徑),供引述綁定解析來源檔。 +function indexSourceFiles(dir, acc = new Map()) { + for (const name of readdirSync(dir)) { + const full = join(dir, name); + if (statSync(full).isDirectory()) indexSourceFiles(full, acc); + else if (name.endsWith('.ts')) (acc.get(name) ?? acc.set(name, []).get(name)).push(full); + } + return acc; +} + +// 字元 bigram Dice 係數:對中文短句的近似度量比編輯距離穩定,且不需分詞。 +export function diceSimilarity(a, b) { + const grams = (s) => { + const t = s.replace(/\s+/g, ''); + return new Set(Array.from({ length: Math.max(0, t.length - 1) }, (_, i) => t.slice(i, i + 2))); + }; + const A = grams(a); + const B = grams(b); + if (A.size === 0 || B.size === 0) return 0; + let shared = 0; + for (const g of A) if (B.has(g)) shared += 1; + return (2 * shared) / (A.size + B.size); +} + +function readLevelHints() { + const levels = join(SRC_DIR, 'game', 'logic', 'levels.ts'); + const text = readFileSync(levels, 'utf8'); + return [...text.matchAll(/^\s*hint:\s*'([^']+)'/gm)].map((m) => m[1]); +} + +// 引述綁定與近似網:文件引述的程式碼字串必須與 src 逐字相符。 +function checkQuoteBindings(docFiles) { + const problems = []; + const sources = indexSourceFiles(SRC_DIR); + const hints = readLevelHints(); + const bound = new Set(); + + for (const { name, path } of docFiles) { + const lines = readFileSync(path, 'utf8').split('\n'); + lines.forEach((line, i) => { + for (const m of line.matchAll(QUOTE_BINDING)) { + const [, quoted, srcName] = m; + bound.add(quoted); + const candidates = sources.get(srcName); + if (!candidates) { + problems.push(`${name}:${i + 1} 引述綁定指向不存在的來源檔 ${srcName}`); + continue; + } + const hit = candidates.some((p) => readFileSync(p, 'utf8').includes(quoted)); + if (!hit) { + problems.push( + `${name}:${i + 1} 引述與 ${srcName} 不符(逐字比對失敗):「${quoted}」——` + + `文件抄了舊值或來源已改,請同步`, + ); + } + } + }); + } + + // 近似網:沒帶綁定標記、又與現行 hint 高度相似的引述=疑似過期抄寫(L8 漏網的樣態)。 + // 已廢止附註內本就是舊值,不受檢。 + for (const { name, path } of docFiles) { + const lines = readFileSync(path, 'utf8').split('\n'); + lines.forEach((line, i) => { + if (line.startsWith('> **已廢止**')) return; + for (const m of line.matchAll(/「([^」]+)」/g)) { + const quoted = m[1]; + if (bound.has(quoted) || hints.includes(quoted)) continue; + for (const hint of hints) { + if (diceSimilarity(quoted, hint) >= HINT_SIMILARITY_THRESHOLD) { + problems.push( + `${name}:${i + 1} 疑似過期的關卡 hint 引述:「${quoted}」——` + + `現行值為「${hint}」;若為刻意不同的文案請改寫,若是引述請加綁定標記`, + ); + break; + } + } + } + }); + } + + return problems; +} + export function verifyDesignDocs() { const problems = []; const files = listSectionFiles(); @@ -176,7 +272,15 @@ export function verifyDesignDocs() { }); } - // 6. 全 repo 零 GAME_DESIGN.md 錨點引用。 + // 6. doc↔code 引述綁定:文件引述的程式碼字串必須與 src 逐字相符(含 hint 近似網)。 + const docFiles = [...files, HISTORY_FILE].map((name) => ({ + name, + path: join(DESIGN_DIR, name), + })); + docFiles.push({ name: 'WALKTHROUGH.md', path: WALKTHROUGH }); + problems.push(...checkQuoteBindings(docFiles)); + + // 7. 全 repo 零 GAME_DESIGN.md 錨點引用。 for (const hit of findAnchorReferences()) { problems.push(`${hit} 使用 GAME_DESIGN.md 錨點連結——拆檔後必為死鏈,改引用 §N`); } @@ -192,5 +296,5 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) { problems.forEach((p) => console.error(` - ${p}`)); process.exit(1); } - console.log('設計文件守門通過:索引與章節一致、主句紀律成立、零錨點引用'); + console.log('設計文件守門通過:索引與章節一致、主句紀律成立、引述與 src 逐字相符、零錨點引用'); } diff --git a/apps/starpuff/scripts/verify-design-docs.test.mjs b/apps/starpuff/scripts/verify-design-docs.test.mjs index 42c8d9cf2..0667527d4 100644 --- a/apps/starpuff/scripts/verify-design-docs.test.mjs +++ b/apps/starpuff/scripts/verify-design-docs.test.mjs @@ -1,6 +1,10 @@ import { describe, expect, it } from 'vitest'; -import { verifyDesignDocs } from './verify-design-docs.mjs'; +import { + HINT_SIMILARITY_THRESHOLD, + diceSimilarity, + verifyDesignDocs, +} from './verify-design-docs.mjs'; // 設計文件守門(T7-C):索引是拆檔後唯一的「章號 → 檔案」解析器,失真不會有人發現, // 故機械化為測試。負向案確保守門本身不是空轉——規則真的抓得到漂移。 @@ -21,16 +25,31 @@ describe('設計文件守門', () => { describe('守門規則負向驗證(規則本身抓得到漂移)', () => { // 與 verify-design-docs.mjs 同源的兩條樣態規則;此處獨立重述以確保語意不被誤放寬。 - const inlineSupersession = /(v\d+(\.\d+)? 已(由|於) §/; + const inlineSupersession = /(v\d+(\.\d+)? 已(由|於|被) §/; const deprecationLine = /^> \*\*已廢止\*\*([^)]+):.+/; - it('抓得到行內取代標註(審查必修 1 的回歸樣態)', () => { - expect(inlineSupersession.test('- 地面長按 0.6s 觸發(v19 已由 §109 取代:改 SP 鍵)')).toBe( - true, - ); + it('抓得到行內取代標註的被動語態三式(含複審實測繞過的「已被」)', () => { + for (const verb of ['已由', '已於', '已被']) { + expect( + inlineSupersession.test(`- 地面長按 0.6s 觸發(v19 ${verb} §109 取代:改 SP 鍵)`), + `「${verb}」應被守門攔截`, + ).toBe(true); + } expect(inlineSupersession.test('- 同系 ≥3 且在地面時按 SP 鍵點按立即變身。')).toBe(false); }); + // hint 近似網的門檻校準(實測值鎖定):真漏網的 L8 舊文案必須高於門檻, + // 而非漂移的最相近引述(§110.2 變身首教浮字,與 hint 是不同字串)必須低於門檻。 + it('hint 近似網門檻能分開「過期抄寫」與「刻意不同的文案」', () => { + const current = '同系星彈集滿 3 發,站在地面按 SP 鍵星化變身'; + const staleQuote = '同系星彈集滿 3 發,地面長按吸入鍵 0.6 秒星化變身'; + const differentString = '同系星彈 ×3!按 SP 鍵立即變身'; + + expect(diceSimilarity(staleQuote, current)).toBeGreaterThanOrEqual(HINT_SIMILARITY_THRESHOLD); + expect(diceSimilarity(differentString, current)).toBeLessThan(HINT_SIMILARITY_THRESHOLD); + expect(diceSimilarity(current, current)).toBe(1); + }); + it('抓得到格式不符的已廢止附註', () => { expect( deprecationLine.test('> **已廢止**(v19 起,現行見 §109.2):地面長按 0.6s 觸發。'), diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index 988a02238..28355d657 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:reward-starpuff-t7c-r3-doc-code-quote-binding +- 原因:守門只查「行內取代標註格式」,抓不到「沒有帶任何標註的過期內容」——L8 hint 漏網即此盲區;另 INLINE_SUPERSESSION 漏被動語態「已被」,複審實測可繞過 +- 解法:regex 補「已被」並以三式參數化負向測試鎖住;新增 doc↔code 引述綁定檢查——文件以「引述」(`來源檔.ts` 說明)標註後守門逐字比對 src,另加 hint 近似網(Dice bigram,門檻 0.5 由實測校準:211 筆引述中非漂移最高 0.412、真漏網 0.558,已廢止附註豁免)攔截無標註的過期抄寫;四處既有引述全數補標記,三種故障注入實證 + - 日期:2026-07-26 - ID:reward-starpuff-t7c-r3-header-and-node-count-cleanup - 原因:02 檔頭寫「§23/§40 星暴敘述均為 v19 前歷史值」但 §23 主句早已改成現行的自動結晶+SP,檔頭自打臉;§50/§60/§65 正文仍以現在式寫「七/九/十二節點單頁鋸齒」,§76 則缺引導句且正文仍寫十六節點——標題改對了內文沒跟上 From 4e209323d67185a420a9eaad95bc20bfdb7ba310 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 13:24:15 +0800 Subject: [PATCH 13/14] =?UTF-8?q?docs(starpuff):=20=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E5=AE=88=E9=96=80=E6=A0=A1=E6=BA=96=E8=A8=BB=E8=A7=A3=E6=95=B8?= =?UTF-8?q?=E5=AD=97=E8=88=87=20=C2=A776=20=E9=99=84=E8=A8=BB=E6=BC=8F?= =?UTF-8?q?=E5=B8=B6=E6=8E=A8=E5=B0=8E=E5=80=BC=EF=BC=88=E7=B5=82=E8=BC=AA?= =?UTF-8?q?=E6=AE=98=E7=95=99=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 校準註解改實測值:全量 218 筆引述、近似網實際受檢 200 筆,並註明綁定後受檢集最高 0.182 - §76 已廢止附註補回「854 寬間距 ≈51px 單頁可容納」與「20 節點單頁確定放不下」 - 門檻 0.5 與 0.558/0.412 兩側校準值不變,仍由單測鎖住 測試:verify-design-docs 通過;守門單測 5 案綠;數值 token 逐檔比對全 10 檔零規格值遺失 Co-authored-by: Cursor --- apps/starpuff/docs/design/04-levels-world.md | 2 +- apps/starpuff/scripts/verify-design-docs.mjs | 6 ++++-- docs/dev/002_development_reward_penalty_log.md | 5 +++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/starpuff/docs/design/04-levels-world.md b/apps/starpuff/docs/design/04-levels-world.md index aadf64ce0..4d0e80359 100644 --- a/apps/starpuff/docs/design/04-levels-world.md +++ b/apps/starpuff/docs/design/04-levels-world.md @@ -360,7 +360,7 @@ v6 當時的 L1-L4 攻略表已失效(怪物權重、星暴長按觸發、精 - 世界地圖新增 L13–L16 四節點;魔王節點(L4/L7/L12/L16)恆落最高階,EX 徽鈕淨空恆成立。 -> **已廢止**(v12 §78 起):當時的「十六節點單頁、半徑 24→20、三階鋸齒 12 項循環、關號 17px」與「分區分頁列為 v12 硬項」的待辦敘述——分區分頁已於 §78 落地。 +> **已廢止**(v12 §78 起):當時的「十六節點單頁、半徑 24→20(854 寬間距 ≈51px 單頁可容納)、三階鋸齒 12 項循環、關號 17px」與「分區分頁列為 v12 硬項(20 節點單頁確定放不下)」的待辦敘述——分區分頁已於 §78 落地。 - save schema v1 不變:`LEVEL_IDS` 擴至 16;v10 舊檔(≤12 關)載入 L13 自然開放、 L14-L16 迷霧鎖定(save.test/e2e 守門)。 diff --git a/apps/starpuff/scripts/verify-design-docs.mjs b/apps/starpuff/scripts/verify-design-docs.mjs index e9981346f..ee494b11c 100644 --- a/apps/starpuff/scripts/verify-design-docs.mjs +++ b/apps/starpuff/scripts/verify-design-docs.mjs @@ -27,8 +27,10 @@ const WALKTHROUGH = join(DOCS_DIR, 'WALKTHROUGH.md'); // 守門逐字比對該字串確實存在於該來源檔,杜絕「文件抄了舊值」這類無標註漂移。 const QUOTE_BINDING = /「([^」]+)」(`([\w.-]+\.ts)`[^)]*)/g; // 近似網(僅針對 LevelSpec.hint 九條):抓沒有綁定標記、又與現行 hint 高度相似的引述。 -// 門檻依實測校準——211 筆引述中,非漂移的最高相似度為 0.412 -//(§110.2 的變身首教浮字,與 hint 是不同字串),真漏網的 L8 舊文案為 0.558。 +// 門檻依實測校準——導入時全量掃描設計文件+攻略共 218 筆「」引述,近似網實際受檢 200 筆 +//(扣除已廢止附註、已綁定、與 hint 逐字相符者):真漏網的 L8 舊文案 0.558 高於門檻, +// 受檢集內非漂移的最高者 0.412(§110.2 變身首教浮字,與 hint 是不同字串;該處其後補上 +// 綁定標記而退出受檢集,故現行受檢集最高僅 0.182)。0.558/0.412 兩側由單測鎖住。 export const HINT_SIMILARITY_THRESHOLD = 0.5; // 取代附註的唯一合法形狀(99-superseded.md「主句紀律」章定義)。 diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index 28355d657..8e8a3d323 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-07-26 +- ID:reward-starpuff-t7c-r4-calibration-comment-and-note-value +- 原因:終輪雙席抓到兩處殘留——守門校準註解寫「211 筆」但實測為 218 筆(文件成長後數字漂移),§76 已廢止附註漏帶推導值「854 寬間距 ≈51px 單頁可容納」 +- 解法:註解改為實測值並區分「全量 218 筆」與「近似網實際受檢 200 筆」及綁定後受檢集最高值 0.182,避免再漂移;§76 附註補回推導值與「20 節點單頁確定放不下」理由;另以數值 token 逐檔比對全 10 檔確認反轉輪零規格值遺失(僅 4 個版本標籤/章號隨行內標註一併移除) + - 日期:2026-07-26 - ID:reward-starpuff-t7c-r3-doc-code-quote-binding - 原因:守門只查「行內取代標註格式」,抓不到「沒有帶任何標註的過期內容」——L8 hint 漏網即此盲區;另 INLINE_SUPERSESSION 漏被動語態「已被」,複審實測可繞過 From d0001a15f443ce20fc54d36ab9b2c60bfed4aac1 Mon Sep 17 00:00:00 2001 From: haotool Date: Sun, 26 Jul 2026 13:29:47 +0800 Subject: [PATCH 14/14] =?UTF-8?q?docs(starpuff):=20rebase=20=E8=87=B3=20ma?= =?UTF-8?q?in=20=E4=B8=A6=E9=87=8D=E7=AE=97=20002=20=E7=B8=BD=E5=88=86?= =?UTF-8?q?=E9=8F=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 併入 main 對 §99 的 SHA 來源鏈修正(#877),依主句紀律改寫並移入 00-foundations - 002 條目雙方時間序全保留零刪除;檔頭重算為 reward 9/neutral 2、淨 +9、累計 +260 測試:002 六項驗算全通過(條目數/前綴計數/N=a-b/T=main 251+9/ID 唯一/零刪除) Co-authored-by: Cursor --- docs/dev/002_development_reward_penalty_log.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index 8e8a3d323..2f9823d42 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -2,7 +2,7 @@ > 版本:outline-v2-ultra > 原則:每筆只保留日期、ID、原因、解法。 -> 本次分數變化:+9(reward 9、penalty 0、neutral 0)|累計總分:+251 +> 本次分數變化:+9(reward 9、penalty 0、neutral 2)|累計總分:+260 ## 新增模板(4 行)