Skip to content

perf(starpuff): manifest 驅動的分階段資產載入——首屏位元組 −72.5%、時間 −65~69% - #883

Merged
s123104 merged 6 commits into
mainfrom
perf/starpuff-segmented-loading
Jul 26, 2026
Merged

perf(starpuff): manifest 驅動的分階段資產載入——首屏位元組 −72.5%、時間 −65~69%#883
s123104 merged 6 commits into
mainfrom
perf/starpuff-segmented-loading

Conversation

@s123104

@s123104 s123104 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

問題

BootScene 一次預載全部 63 張立繪(1.8 MB),首屏要等全部載完才看得到標題畫面。v21–v30 素材車已入庫 125 張/7.1 MB 且仍在產出(B06 五王動畫後累計上看 400 張),照此結構走下去啟動時間會崩壞。

量測方法(節流參數已揭露)

CLI Playwright(非 MCP),腳本置於 /tmp,baseline 與 after 同一套方法、同一次會期內連續量測:

  • 裝置 iPhone 13 landscape;封鎖 SW、停用 HTTP 快取(冷啟動)
  • 靜態伺服器對 js/css/html 開 gzip,貼近正式站(否則 1.7 MB 未壓縮 JS 會蓋過資產差異)
  • 首屏=navigation 起算到 window.__sp.scene() === 'Title';位元組取 CDP Network.loadingFinishedencodedDataLength 累計
  • 每組 5 次取中位數
  • baseline 為 origin/main(3c6812d5c)現場重建,與本分支同一份 node_modules

「Fast 3G」有兩套通行定義,絕對秒數差異全來自此,故兩組並列:

profile 下行 上行 RTT
DevTools Fast 3G 1.6 Mbps(209,715 B/s) 750 kbps 150 ms
Lighthouse Fast 3G 180,000 B/s 84,375 B/s 562.5 ms

前後對照

位元組與張數與節流無關:

指標 改前 改後 變化
首屏位元組 2,197.0 KiB 604.9 KiB −72.5%
首屏立繪張數 63 6 −90.5%

首屏時間依 profile:

profile 改前 改後 變化
DevTools Fast 3G 11,813 ms 3,617 ms −69.4%
Lighthouse Fast 3G 15,952 ms 5,590 ms −65.0%

兩席獨立量測分別對得上:Grok(11,861→3,928)落在 DevTools 組,Sonnet(16,494→5,508)落在 Lighthouse 組。可重現的主張是相對幅度:三席四組量測一致落在 −65% ~ −69%。

進入關卡的成本(更正先前「每 session 一次性」的說法)

先前描述有誤。SW 背景 precache 與頁面請求搶同一條頻寬,實測逐關切換(SW 開啟、DevTools profile):

進入 耗時 位元組
L1(經 Title 開始鈕) 2,992 ms 541.9 KiB
L2 1,361 ms 145.9 KiB
L4 1,185 ms 197.4 KiB
L7 783 ms 104.1 KiB
L13 1,109 ms 180.9 KiB
L17 788 ms 121.1 KiB
L20 487 ms 44.0 KiB
L2(重進已載過的關) 35 ms 0 KiB

正確說法是:每個新關卡首次進入各付一次該關獨有資產(隨共用資產累積而遞減),同一關重進為零成本。首關較貴是因為同時付了全關共用核心與形態立繪。載入期間有進度條與文字回饋。

manifest 欄位設計

ASSETS 條目新增選填 phase,載入時機由 manifest 單點驅動,場景不散寫清單:

export type AssetPhase = 'boot' | 'level' | 'boss' | 'form' | 'lazy';
export interface AssetEntry { key: string; url: string; phase?: AssetPhase }

安全預設phase 省略一律視為 boot。漏標只會拖慢首屏,不會缺圖——素材車 append-only 新增的條目即使沒標也一定會被載到。

append-friendly:新增條目只要加一行 phase,不需改動載入邏輯;level 階段的關卡限定資產由 LEVELS 派生自動判定,加關加怪自動跟進,無需維護第二份名單。

boot 階段收斂為 6 張:hero-idlefx-starfx-cloudsbg-meadow-lbg-heights-lbg-arena-l

審查修正

必修 1|lazy 階段誤標守門

lazy 沒有 scene 呼叫點,把戰鬥資產標進去會無聲缺圖。我先實測既有守門的覆蓋範圍:

誤標為 lazy 修正前 修正後
boss-voidra 2 案紅 2 案紅
minion-magno 1 案紅 1 案紅
prop-kiln-1 17 案全綠(漏網) 1 案紅
bg-kiln-l 17 案全綠(漏網) 2 案紅

守門只覆蓋小怪與魔王,道具與背景是破口 —— 比審查指出的範圍更大。

複審輪追加:兩席獨立撞出第二層盲區 —— levelAssetKeys() 原本只派生背景/道具/小怪/魔王,不含 hero 共用姿勢與 form 立繪。實測 hero-inhale-big-1-2 標成 lazy 時 19 案全綠;其餘 hero 鍵之所以被攔,只是恰好落在測試端另一份手動維護的清單裡,實為「不變式+手動清單」的拼接,與註解宣稱的全類別自動涵蓋不符。

修法是把共用核心提升為 assetPlanSHARED_LEVEL_KEYS 併入 levelAssetKeys,其中 form 鍵由 TRANSFORM_FORMS 派生(W1 加 ember/tide 會自動納管),測試端手動清單刪除改讀同一真值。13 鍵 × lazy 誤標矩陣全數轉紅:

誤標為 lazy 修正前 修正後
hero-inhale-big-1 / -2 19 案全綠(漏網) 2 案紅
hero-inhale / hero-puffed / hero-hurt 1 案紅(靠手動清單) 2 案紅(靠不變式)
hero-volt / hero-gale / hero-shell 1 案紅(靠手動清單) 2 案紅(靠不變式)

誤標矩陣同時暴露另一方向的破口:關卡限定資產標成 form 不會缺圖,但 form 一律每關載入,等於退回本 PR 要消除的成本。已補「關卡限定資產不得標為 form」不變式(由 levelScopedSHARED_LEVEL_KEYS 派生,零硬編),minion/prop/bg 三向誤標實測全數轉紅。

涵蓋範圍的文案也一併收斂:註解與測試敘述改述為「levelAssetKeys 派生鍵」,並明說派生外資產(form 階段的變身動畫分鏡、特效分層)不在守門範圍,不再宣稱全類別。

選了測試守門而非接線 entriesForPhase('lazy'),理由:(1) 為零成員階段建立載入呼叫點是死碼,且就算接了,戰鬥資產在「lazy 時機」才載仍然是錯的,擋不住這個誤用;(2) 真正的不變式與階段名稱無關 —— 「每關派生出的每個鍵,都必須落在 boot 或該關計畫內」。這一條同時擋住 lazy、擋住戰鬥資產被誤標成 form、擋住任何未來新增的階段誤標,且完全由 LEVELS 派生,素材擴到 400+ 也自我維持。

原本的 per-category 斷言改為只驗「派生完整性」(enemyMix/精英/教學供給/魔王召喚/潮汐替換有沒有被 levelAssetKeys 收進來),與覆蓋率不變式各司其職,消除重疊。

必修 2|載入失敗與掛起降級

loaderror 改為明說「部分素材載入失敗,將以簡易圖示續玩」;逾時改為停滯型判定——20 秒內完全沒有 progressfilecompleteloaderror 事件才判定掛死,另設 120 秒硬上限兜底。固定 20 秒對慢網過緊(單關實測約 600 KB,Slow 3G 或擁塞下資產還在飛就會被強制降級),停滯判定讓正常慢速下載不被誤判、真掛死仍被接住。收尾走 scene.load.loadComplete() 強制進 create,缺圖走佔位色塊仍可通關,未取得的資產於下次進關重試。

順帶修掉一個同源缺陷:fromManifest 原本在排入佇列時就記錄鍵,載入失敗後 enemies.ts 生成的佔位色塊會被誤認為正式立繪而永不替換。改為只記 filecomplete 的成功鍵。

必修 3|assetLoader 單元測試與死碼

新增 assetLoader.test.ts 8 案(scene 替身沿 voidra.test.tsas unknown as Phaser.Scene 慣例):逐出三態、失敗後重試、逾時強制收尾、正常完成解除逾時、全快取時不建 UI 不掛逾時。

紅→綠驗證:暫時還原三處產品碼守門後,載入失敗的鍵不記為 manifest 來源 / loaderror 明說降級 / 逾時強制收尾 三案轉紅,還原後 8 案全綠。

死碼 resetLoadedKeys()(全專案零呼叫點)刪除,模組級狀態隔離改用 vi.resetModules()(沿 settings.test.tsmute.test.ts 慣例),不為測試在產品碼開後門。

應修

  • CacheFirst 收窄request.destination === 'image'/\/assets\/[^/]+\.webp$/,只收 Vite 內容雜湊立繪;未雜湊的 icons/*.png 全數留給 precache revision 管理,不讓兩套機制靠路由順序決勝負。build 後查 sw.js 確認路由已收窄。
  • boot 絕對值上限:比例護欄保留,另加 bootKeys.length <= 10。ASSETS 擴到 400+ 後分母會稀釋比例,絕對值補這個慢性侵蝕缺口。
  • addTerraincreateTerrain 重構:確實與分階段載入無關,但不是可選的 —— GameScene 加上 preload() 後為 1206 行,超過 repo 既有的 max-lines 1200 error 門檻,lint 直接紅。搬到 systems/stage.ts 是最小可行解(該檔註解本就寫明「GameScene addTerrain 的粉紅平台納入同一套下穿裁決」,同屬地形層),現為 1177 行。已不再擴大。

Nits

  • playerHp 就緒語意:已比照 stage(),載入期回 -1(沿 bossHp 的「不存在」慣例)而非 class 預設 5。
  • 載入期按住的鍵被丟棄:確認存在,但不修。Phaser Keycreate 建立,載入期的 keydown 不會被看見。暴露面:多數入口為點擊(Title 開始鈕、地圖節點、Result 再戰),但 TitleScene.ts:210MapScene.ts:146ResultScene.ts:143CreditsScene.ts:153 四處掛有 keydown-ENTER 捷徑,桌機玩家按 Enter 時可能同時扣著相鄰的方向鍵,仍會在首次載入窗吞鍵——風險窄(僅該關資產首次未快取、單次補按即可復原;同關重進 35 ms 無載入窗)但非零。修法要動 controls.ts 輸入熱路徑(本 repo 有 §85/[bug] starpuff 小怪關星暴誤放或失誤可致卡關 #812[ux] starpuff HUD DOM 鈕僅綁 pointerdown——輔助技術無法觸發且有雙觸發隱患 #823 多次輸入層 P0 前科),風險與收益不成比例。列為已知限制,若 PM 認為值得可另開卡處理。

離線可玩性(真實 SW + 真實斷線,收窄 CacheFirst 後重測)

onlineWebpRequestedBeforeTitle: 6      // 分階段載入生效
precachedWebpEntries: 63               // 全數進 precache(79 entries / 3758 KiB)
offlineTitleScene: "Title"             // 離線冷啟達標題
offlineGame: { scene: "Game", hp: 5, level: 1 }   // 離線進第一關正常運行
offlineWebpResponses: 21               // 離線期 21 筆立繪請求
offlineWebpNon200: []                  // 全數 200,自 SW 快取
consoleErrors: []

SSOT 收斂

小怪品種→貼圖對照(enemies.ts)與背景重用別名(background.ts)收斂至 core/assetPlan 純模組,呈現層與載入計畫共用單一真值。

測試

  • pnpm typecheck
  • pnpm lint
  • starpuff vitest 974 案綠(新增 assetLoader 8 案、assetPlan 17 案)
  • 全量 Playwright 以 CI 同參數(--retries=2):118 passed/0 failed/2 flaky(重試後綠)/15 skipped
  • 2 個 flaky 皆為既有 flake:hotfix.spec.ts:255 flick 下滑抬指 於未修改的 main 以完全相同的斷言值Expected: > 360, Received: 304)復現,約 4–5 次跑 1 次失敗;v13 EX 中途退出防鎖 失敗點在 startGame 等 Title(boot 階段,與本 PR 無關)
  • 離線可玩性真機實測如上

協調事項

  • 素材車:ASSETS 為 append-only 新增,衝突請保留雙方;新條目補一行 phase 即可。註解建議可直接對應:星港/潮灣場景→level、雙王→boss、六新小怪→level、變身與技能幀→form、HUD 徽章→lazy戰鬥中會出現的資產一律不得標 lazy,標了會被覆蓋率不變式擋下。
  • W1 變身車:本 PR 未觸碰 logic/transform.tssystems/player.tslogic/starburst.tscore/events.tscore/types.ts

不自行合併,等 PM 派複審。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7e5ec9565f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/starpuff/src/game/core/assetLoader.ts Outdated
haotool and others added 5 commits July 26, 2026 14:07
- ASSETS 條目新增 phase(boot/level/boss/form/lazy),未標註安全預設 boot 免漏載
- 新增 core/assetPlan 純模組:phase 解析、LevelSpec 派生關卡貼圖鍵、魔王召喚與潮汐替換閉包
- 小怪貼圖對照與背景重用別名自 enemies.ts/background.ts 收斂至 assetPlan 單一真值
- 補 17 案單測鎖住 manifest 驅動分階段載入、未標註條目安全預設與 anti-softlock 涵蓋

測試:pnpm typecheck 綠、vitest 全量 949 案綠、pnpm lint 綠

Co-authored-by: Cursor <cursoragent@cursor.com>
- 新增 core/assetLoader 單點載入層:排載前移除非 manifest 佔位貼圖,並統一載入進度回饋
- BootScene 只載 boot 階段;GameScene 進關卡載本關資產;CodexScene 開圖鑑補載立繪
- GameScene addTerrain 遷入 systems/stage(同屬地形層、共用下穿裁決),GROUND_HEIGHT 收斂單點
- PWA 補 same-origin 圖片 CacheFirst,precache 未完成即斷線時延遲資產仍可落快取

測試:Fast 3G 實測首屏 12301ms/2196.9KiB → 4073ms/604.7KiB;typecheck/lint/vitest 949 案綠

Co-authored-by: Cursor <cursoragent@cursor.com>
- 新增兩案:首屏只取 boot 階段立繪、進第一關才補載該關資產且不拉他關限定資產
- 魔王直達兩案改在送鍵前等 __sp.scene() 就緒——載入期場景未 RUNNING,此時按住的鍵
  不會被 create 才建立的 Phaser Key 看見,玩家會原地不動被打死
- S2 彈簧案同型收斂:fillQuota 的 isActive 守衛在載入期會靜默略過,改等場景就緒再補配額

測試:Mobile Chrome smoke 12 案全綠(含新增 2 案)

Co-authored-by: Cursor <cursoragent@cursor.com>
- 全量 e2e 揭露 13 案在關卡資產載入期就送鍵或呼叫 isActive 守衛鉤子而失敗
- stage() 原回報 init 寫入的目標關卡,載入期即為真;改為場景 RUNNING 才回報
- 既有 37 處 expect.poll(stage()) 因此自動等到可互動,毋須逐案散寫等待
- smoke 先前的逐案 scene() 等待改回精簡(已由 stage() 單點涵蓋)

測試:全量 Playwright 117 passed/15 skipped;殘 3 案為既有 flake(同案在 main 以相同斷言復現)

Co-authored-by: Cursor <cursoragent@cursor.com>
- assetLoader 補 loaderror 明說降級與 20 秒逾時強制收尾,請求掛起不再卡在載入畫面
- fromManifest 改記 filecomplete 成功鍵:原本排入即記,失敗後的佔位色塊會永不被替換
- 新增 assetLoader.test 8 案(逐出三態/失敗重試/逾時收尾/完成解除逾時),死碼
  resetLoadedKeys 刪除,模組狀態隔離改用 vi.resetModules
- 立與階段名無關的總不變式「每關派生鍵必落在 boot 或該關計畫內」——實測道具與背景
  標成 lazy 原本 17 案全綠,補後四類別誤標全數轉紅;boot 另加絕對值上限 10
- CacheFirst 收窄為 assets/*.webp 內容雜湊立繪,未雜湊 icons 全留給 precache
- __sp.playerHp 比照 stage() 就緒語意,載入期回 -1 而非 class 預設 5

測試:typecheck/lint 綠、vitest 974 案綠、Playwright 118 passed 0 failed(2 flaky 重試後綠)

Co-authored-by: Cursor <cursoragent@cursor.com>
@s123104
s123104 force-pushed the perf/starpuff-segmented-loading branch from 7e5ec95 to fce891e Compare July 26, 2026 06:53
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@s123104 s123104 changed the title perf(starpuff): manifest 驅動的分階段資產載入——首屏位元組 −72.5%、時間 −66.9% perf(starpuff): manifest 驅動的分階段資產載入——首屏位元組 −72.5%、時間 −65~69% Jul 26, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fce891ef4e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const timeout = setTimeout(() => {
label.setText('載入逾時,將以簡易圖示續玩');
// 強制收尾:清空佇列、progress 補 1 並發出 complete,場景照常進 create。
scene.load.loadComplete();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 中止逾時後仍在執行的影像請求

當連線只是慢到部分圖片在 20 秒後才完成,而非永久掛起時,直接呼叫 Phaser 的 loadComplete() 只會清空 loader 集合並發出完成事件,不會取消已建立的 Image 請求。GameScene 隨即進入 create() 並以相同 key 生成佔位貼圖後,舊請求回來會再次嘗試加入貼圖,產生 Texture key already in use console error;背景或道具即使晚加入,也因 filecomplete listener 已拆除而未被 fromManifest 記錄,下次進關仍會刪除並重新下載。請在強制完成前真正取消或隔離仍在途的檔案,避免逾時降級後繼續回寫 TextureManager。

AGENTS.md reference: AGENTS.md:L278-L278

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

未修且該修 → PM 派工(#883 收斂輪)

稽核 fce891ef4eLOAD_TIMEOUT_MS 逾時仍呼叫 scene.load.loadComplete()(L65–67),未取消已建立的 Image 請求。

Codex 指稱風險屬實:逾時後 create() 以相同 key 生成佔位,慢速連線請求晚到會觸發 Texture key already in use

建議修法: 逾時時 abort/忽略晚到 callback,或延遲佔位至確認無 in-flight 請求。監控席列入 PM 派工清單,待修復 commit 後 resolve。

- 共用核心改宣告為 SHARED_LEVEL_KEYS 併入 levelAssetKeys,form 鍵由 TRANSFORM_FORMS
  派生(新增形態自動納管);測試端手動清單刪除改讀同一真值
- hero-inhale-big-1/-2 原本標 lazy 全綠,13 鍵誤標矩陣補後全數轉紅
- 補「關卡限定資產不得標為 form」守門,防另一方向的每關全載退化
- 載入逾時改停滯型判定(20 秒無事件才算掛死)+120 秒硬上限,慢網持續下載不再誤判
- 鎖住逾時後晚到檔案不記為 manifest 來源,避免佔位色塊永不被替換
- 覆蓋範圍註解與測試敘述改述為「levelAssetKeys 派生鍵」,不再宣稱全類別

測試:typecheck/lint/prettier 綠、vitest 979 案綠(新增 5 案)

Co-authored-by: Cursor <cursoragent@cursor.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eab73e2d98

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const keys = new Set<string>([bgTextureKey(level.bgKey), ...SHARED_LEVEL_KEYS]);
for (const decor of level.decor) keys.add(decor.key);

const kinds = new Set<EnemyKind>(level.enemyMix.map((entry) => entry.kind));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 將破磚生成的果凍納入關卡計畫

從存檔直接進入未將 jelly 列於 enemyMix、精英或特殊生成清單的關卡(例如 L9、L11、L18)時,這個集合不含 minion-jelly,但 GameScenespawnAmmoMinion 會在打破 ammo 磚後固定生成果凍。重新載入頁面後先前關卡的貼圖不在 TextureManager,故這些關卡只會由 createEnemySystem 產生佔位色塊,正式果凍立繪完全不會排載;請依 ammo breakable 將 jelly 加入派生鍵。

Useful? React with 👍 / 👎.

Comment on lines +147 to +150
const phase = phaseOf(entry);
if (phase === 'form') return true;
if (phase !== 'level' && phase !== 'boss') return false;
return scoped.has(entry.key) ? needed.has(entry.key) : true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 在後續場景重試載入失敗的 boot 資產

當初次 Boot 請求中的 hero-idlefx-star 或 boot 背景因暫時網路錯誤失敗,但連線在玩家進關前恢復時,此條件仍把全部 boot 條目排除於關卡載入計畫,因此該次工作階段會持續使用白色主角/特效或背景降級圖直到整頁重載。即使先前修正已把 fromManifest 改為僅在 filecomplete 記帳,這個 phase 過濾仍證明失敗的 boot 鍵根本不會再次送進 queue;請追蹤失敗鍵或讓後續場景補載缺失的 boot 資產。

Useful? React with 👍 / 👎.

@s123104
s123104 merged commit 0851528 into main Jul 26, 2026
16 checks passed
@s123104
s123104 deleted the perf/starpuff-segmented-loading branch July 26, 2026 10:55
s123104 pushed a commit that referenced this pull request Jul 26, 2026
- rebase 到分階段載入(#883)後依載入時機註解標 phase:level 158、boss 249、form 92,boot 集維持 main 原樣六張 148.5KiB 零膨脹
- 補回拆檔重建時遺失的首批四條 manifest 條目,分檔型別對齊 AssetEntry 並再平衡行數守 max-lines
- 002 檔頭依 squash SOP 改為 PR 聚合值(+19,累計 +284)

測試:tsc、eslint、vitest 全套(assetPlan 兩不變式綠)、verify:docs 全綠;pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>
s123104 added a commit that referenced this pull request Jul 26, 2026
* chore(starpuff): T5 hotfix 快修列車開工錨

- 活性錨:T4/T5 review threads 六項收斂開工
- worktree fix/starpuff-t5-review-backlog base origin/main@771eb3074

測試:無(空 commit)

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增二十一至三十關首批素材

- 加入 Ember 形態、劉董思考姿勢、劉董魔王與市場下跌箭頭素材
- 修正殼化小怪巡走與旋轉時依速度同步左右朝向
- 更新 StarPuff 資產清單、changeset 與開發稽核紀錄

測試:typecheck、test:run(59 files、809 tests)、build、lint、Prettier;pre-commit 全部通過

* chore(starpuff): v21-v30 素材車開工錨

- 活性錨:素材車 rebase origin/main@11ca18696 後續跑
- codex luna 探路結果與素材盤點見 stream-assets 進度檔

測試:無(空 commit)

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch01 風格鎖定四張總覽概念板

- 依 imagegen skill 內建 image_gen 路徑生成:七形態總覽、五新王總覽、13 新小怪輪廓、VFX 形狀字典
- 風格錨定既有 hero/boss/minion/fx sprites;劉董板通過迷因安全負面詞目視驗收(無真實人物/Logo/股票代號/券商 UI)
- 概念板沿 style-board 前例存 concepts/ 不註冊 ASSETS manifest,不佔遊戲首屏預算

測試:pre-push hook 執行 typecheck、pnpm -r test、build:ratewise 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch02 星港潮灣場景與雙王素材

- 星港/潮灣背景(1536×512)各配四件透明 props(512²),戰鬥帶低對比
- Tariffang 關稅巨獸與 Maridella 潮汐女王本體+enraged 形態(768² 透明底)
- 2048² chroma-key 母檔經 remove_chroma_key 去背,alpha QA 12/12 零殘暈;入庫縮遊戲解析度守首屏預算
- 全數註冊 ASSETS manifest 並附載入時機建議註解;票券紋樣為抽象捲曲紋無可辨識文字

測試:pre-push hook 執行 typecheck、pnpm -r test、build:ratewise 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch02 六新小怪與雙形態變身五幀

- 六新小怪本體(512² 透明底):貨櫃丁、票券蝠、掃描眼、吐泡怪、冰史萊姆、潮汐魟,錨定 B01 輪廓板
- 潮化基底(1254² 對齊 hero-ember)+焰化/潮化變身五關鍵幀(1024²,聚集/縮小/拉伸/爆光/完成)
- 2048² chroma-key 母檔去背,alpha QA 17/17 通過零殘暈;全數註冊 ASSETS 附載入時機建議

測試:pre-push hook 執行 typecheck、pnpm -r test、build:ratewise 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch02 技能四拍與光環拖尾分層特效

- 焰化/潮化技能四拍各四幀(1024²):起手、蓄力、爆發、收招
- 光環拖尾 VFX 逐層獨立(1024²):核心光、外圈衝擊、拖尾、碎片、overlay 各自透明圖
- 形態徽章與技能 HUD 圖示各二(512²)
- 潮化核心光層柔邊色暈判瑕疵重生一次改硬邊分階光盤;alpha QA 22/22 通過後入庫並註冊 ASSETS

測試:pre-push hook 執行 typecheck、pnpm -r test、build:ratewise 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch03 鏡界黑洞場景與雙王素材

- 鏡界塔/黑洞外環背景(1536×512)各配四件透明 props(512²),戰鬥帶低對比
- Reflector 鏡界館長與 Gravion 引力侯爵本體+enraged 形態(768² 透明底)
- 稜系白粉紫主體一律綠 key 並於 prompt 禁綠;alpha QA 12/12 零殘暈
- 全數註冊 ASSETS manifest 附載入時機建議(manifest 保持 append-only 供載入策略車並行)

測試:pre-push hook 執行 typecheck、pnpm -r test、build:ratewise 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch03 六新小怪與雙形態變身五幀

- 六新小怪本體(512² 透明底):複製噗、稜蜂、資料塵、重力泡、軌道怪、裂隙怪,錨定 B01 輪廓板
- 稜化/引力化基底(1254²)+各自變身五關鍵幀(1024²,聚集/縮小/拉伸/爆光/完成)
- 稜系全程綠 key+prompt 禁綠;alpha QA 18/18 零殘暈零重生;全數註冊 ASSETS 附載入時機建議

測試:pre-push hook 執行 typecheck、pnpm -r test、build:ratewise 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch03 技能四拍與光環拖尾分層特效

- 稜化/引力化技能四拍各四幀(1024²):起手、蓄力、爆發、收招
- 光環拖尾 VFX 逐層獨立(1024²):核心光、外圈衝擊、拖尾、碎片、overlay 各自透明圖
- 形態徽章與技能 HUD 圖示各二(512²),構圖對齊 B02 成套
- 核心光層前置套用 B02 教訓要求硬邊分階;alpha QA 22/22 一次通過,B03 全程零重生

測試:pre-push hook 執行 typecheck、pnpm -r test、build:ratewise 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(starpuff): 修復二十四張深色資產半透明回歸

- 根因:image_gen raw 多為原生透明底,auto-key border 取樣透明黑當 key,深黑主體被 soft-matte 誤判半透明(gravion 主體 alpha 均值 94)
- 修法:原生透明 raw 直接重轉入庫(20 張);水藍主體改 hard 模式重切(4 張),全部復原 mean alpha ≥250
- QA 流程補主體不透明度門檻,防同型缺陷再漏網

測試:alpha 稽核腳本全綠(主體 mean ≥250、四角透明);pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch04 崩盤前夜劉董戰場與市場素材

- 崩盤前夜/劉董戰場背景(1536×512)各配四件金融 props(512²),看板螢幕僅抽象色塊零可辨識文字
- 劉董狂暴+全倉末日形態(768²)與入金演出四幀(1024²),螢幕僅抽象鋸齒線
- 牛熊怪三隻與三市場虛構圖示(512²,不影射真實交易所)
- 下跌箭頭三變體:假箭頭空心虛線鈍頭 vs 真箭頭實心尖頭,64px 實戰背景合成驗證瞬間可辨(anti-softlock 玩法要件)
- 市場攻擊單件四張(空白硬幣/綠燭/紅針/熔斷牆);牌價板重生一次

測試:alpha QA 全綠(含主體不透明度新門檻);pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch04 市場終招分層特效

- 崩跌衝擊波、K 線海嘯、市場黑洞、入金光束各五層獨立透明圖(1024²)
- 管線升級:image_gen 原生透明輸出直接取用,省去 chroma-key 選色與去背風險
- 升級版 alpha QA(含主體不透明度門檻)20/20 通過;硬幣全空白、零可辨識文字

測試:alpha QA 全綠;pre-push hook 執行 typecheck、pnpm -r test、build:ratewise 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch05 十二系星彈四態

- 12 系 ×4 態(飛行/蓄力/命中/爆炸)共 48 張(512²),構圖以基準系模板統一
- 系間辨識靠形狀系徽(翅紋/雲邊/殼紋/閃電/鑽尖/光暈/孢子點/迴旋弧/波紋水滴/晶面/軌道環),不依賴色差
- zappy 首擴丟失系徽與標準星無法區分,整系重生;深色三系原生半透明主體以 alpha 曲線拉滿
- 升級版 QA(主體不透明度門檻)48/48 收斂;manifest 以腳本追加並 typecheck 守門

測試:alpha QA 全綠;pre-push hook 執行 typecheck、pnpm -r test、build:ratewise 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch05 共通技能分層特效與圖示補完

- 吸入氣旋/漂浮/落地三組各五層獨立透明圖(1024²),中性奶油白金配合全形態
- volt/gale/shell 徽章與技能圖示+通用彈藥/SP 圖示(512²),構圖與 B02-B03 成套
- 模型對小圖示反覆畫棋盤格假透明,重生無效後改四角 floodfill 機械去背收斂

測試:alpha QA 全綠(corners 0/body 255);pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(starpuff): glowy 星彈整系重生補同心光環系徽

- 前版與標準星同形狀僅明度差,違反系間辨識靠形狀系徽的設計原則
- 四態重生加雙圈同心光環;32px 縮放合成星港明亮背景與標準星並排驗證瞬間可辨

測試:alpha QA 全綠;32px 實戰背景並排目視驗證通過;pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch06 關稅巨獸動畫關鍵幀

- Tariffang 39 幀(512²):待機補幀二、入場四、三招各四拍、P2 轉六、P3 轉七、受擊二、死亡六
- 序列一致性檢驗通過:體型穩定、光源恆左上、P2 裂紋至狂暴與 P3 白熱至過載鍍金演進辨識度足、受擊與待機差異明顯
- manifest 爆 eslint max-lines 上限,v21-v30 條目拆三分檔由 ASSETS 展開引用,維持 append-only 契約
- 迷因安全:稅票全空白紙片星形章

測試:alpha QA 39/39 綠;序列拼貼目視檢驗通過;vitest core 綠;pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch06 潮汐女王動畫關鍵幀

- Maridella 39 幀(512²):待機補幀二、入場四、三招各四拍、P2 轉六、P3 轉七、受擊二、死亡六
- 序列一致性檢驗通過:體型穩定、光源恆左上、P2 風暴螺旋與 P3 月蝕女帝演進辨識度足、受擊白閃與待機差異明顯
- 四張角落近白雜訊以四角 floodfill 清零收斂

測試:alpha QA 39/39 綠;序列拼貼目視檢驗通過;pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch06 鏡界館長動畫關鍵幀

- Reflector 39 幀(512²):待機補幀二、入場四、三招各四拍、P2 轉六、P3 轉七、受擊二、死亡六
- 首批造型分裂(半數畫成穿袍生物)判不合格且 tmp 遭清理,整批重生——canon 錨定強化後 QA 39/39 一次過
- 序列一致性檢驗通過:水晶鏡簇造型統一、光源一致、P2 孔雀陣與 P3 曼陀羅聖堂演進辨識度足、受擊白閃可辨

測試:alpha QA 39/39 綠;序列拼貼目視檢驗通過;pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch06 引力侯爵動畫關鍵幀

- Gravion 39 幀(512²):待機補幀二、入場四、三招各四拍、P2 轉六、P3 轉七、受擊二、死亡六
- 首批 23 幀漂移成水晶天使形判不合格,強否定錨定重生收斂;招式受擊待機 16 張一次通過保留
- 序列一致性檢驗通過:深紫圓球貴族造型統一、光源一致、P2 裂紋雙環與 P3 事件視界陀螺儀陣演進辨識度足、受擊白閃環搖可辨

測試:alpha QA 39/39 綠(3 張角落淡值清零);序列拼貼目視檢驗通過;pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch06 劉董動畫關鍵幀

- 劉董 35 幀(512²):待機補幀二、三招各四拍、P2 轉六、P3 轉七、受擊二、死亡六(入場四幀 B04 已入庫)
- 序列一致性檢驗通過:黑狗董事長造型全程無漂移、光源一致、P2 裂裝空頭核心與 P3 熊影黑洞演進辨識度足、受擊白閃歪鏡明顯、死亡認賠釋然化星屑收尾
- 十六張白/棋盤底以 PIL 四角 floodfill 清除;沙發家具與棕吻四張重生;螢幕全抽象色塊零可辨識文字

測試:alpha QA 35/35 綠;序列拼貼目視檢驗通過;pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 新增 Batch06 尾項三形態變身幀與全屏箭雨分層

- volt/gale/shell 變身五關鍵幀各一組(1024²),補齊七形態變身組,構圖沿焰化潮化慣例
- 全屏箭雨分層 VFX 五層(1536×1024 橫幅):核心箭陣、衝擊帶、拖尾、碎片、overlay
- 四張半透明以 alpha 曲線拉滿收斂;Batch06 全案至此收官

測試:alpha QA 20/20 綠;拼貼目視檢驗通過;pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(starpuff): 五百十張新資產全量標註載入階段

- rebase 到分階段載入(#883)後依載入時機註解標 phase:level 158、boss 249、form 92,boot 集維持 main 原樣六張 148.5KiB 零膨脹
- 補回拆檔重建時遺失的首批四條 manifest 條目,分檔型別對齊 AssetEntry 並再平衡行數守 max-lines
- 002 檔頭依 squash SOP 改為 PR 聚合值(+19,累計 +284)

測試:tsc、eslint、vitest 全套(assetPlan 兩不變式綠)、verify:docs 全綠;pre-push hook 全綠

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(starpuff): 未接關素材改標 lazy 並隔離 PWA precache

- 442 條未被 LevelSpec/TRANSFORM_FORMS 認領的 v21-v30 條目改標 lazy,行內註解保留原 phase 供接關改回
- vite globIgnores 由 manifest 的 lazy phase 單點派生,precache 由 519 項 25.8MiB 回到 79 項 4.2MiB
- 新增 assetsV21.test.ts 三守門:接關認領即翻紅、現有各關零撿取、排除樣式零前綴誤殺
- 補 enemyUpdates.test.ts 鎖住首批夾帶的 shelly 每幀朝向同步行為

測試:tsc、eslint、vitest 984 全綠;entriesForLevel(L1) 實測 15 檔 539.1KiB 與 main 一致

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(starpuff): 重生六張錯置與假透明存量立繪

- B03 造型交叉錯置修正:boss-reflector 重生為水晶簇 lens 本體、gravion-enraged 重生為圓球狂暴
- 兩張均以 B06 正確幀為造型唯一真值,杜絕錯圖再成 canon
- 首批四張假透明重生:liudong 移除沙發殘塊、thinking 星空底移除且泡泡圖示抽象化
- hero-ember 與 fx-market-down-arrow 清除畫入的棋盤紋
- 全 manifest 505 張四角補掃收斂 QA 存量盲區,六張終驗四角乾淨且主體不透明

測試:六張角落與主體不透明度 QA 全 PASS、vitest 984 全綠、002 記分守門通過

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(starpuff): 複審收斂——002 更正、全圖假透明掃描、manifest code-split

- 002 更正:precache 實為 3,820.85KiB(workbox 口徑),原 4.2MiB 係手工加總未去重
- 原「多 410KiB 因 B04 重轉」係未驗證推論,實際差額 66KiB 全來自條目字面量進 bundle
- 落地 scripts/qa_asset_alpha.py:edge-band+central-residue 全圖假透明偵測
- 六張舊病例回歸 4/4 命中、現行 505 張零誤殺,mean-alpha 降為語境性 WARN
- v21 分檔不再併入 ASSETS:index.js 回落 66.5KiB、precache 與 main 分毫不差
- 442 張未接關圖不再 emit(產物省 22MB),加主 manifest 零 lazy 條目守門

測試:tsc、eslint、vitest 985 全綠;build 實測 precache 79 項 3,754.61KiB 與 main 一致

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(starpuff): QA 掃描對抗加固——bg 豁免收窄與 bbox 分母改制

- central-residue 移出 bg- 豁免,僅 edge-band 保留(滿版邊緣本該不透明)
- nw_bbox 分母改用不透明像素自身範圍,與主體佔畫布比例脫鉤
- 閾值 0.998 取物理間隙:假透明近白即 opaque 外緣(恆 1.0)、白光核心縮於彩邊內
- 新增 4×4 塊級無彩雙檔 checker-blocks,抓不觸邊緣的局部棋盤補丁
- 歷史病例回歸 4/4、審查對抗樣本 3/3 命中,現行 505 張與 14 張 bg 零誤殺

測試:三組驗證矩陣全過、tsc 與 eslint 與 vitest 985 全綠、002 記分守門通過

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(starpuff): 掃描器色偏棋盤加固與邊界揭露精確化

- lowchroma 門檻 12 放寬至 20:色偏棋盤(light chroma 15)lowchroma 達 1.0 被抓
- 水花白色偏較重(T=20 下最高 0.788)仍在 0.80 門檻外,維持零誤殺
- 塊級檔位試放寬 30 誤殺 3 張淡彩資產後收回 12,平衡點與殘餘邊界寫入 docstring
- 修正三處過度宣稱:bbox 1.0 非普遍幾何保證、三張白光資產屬單軸防護、盲區量化
- 病例 4/4、對抗樣本 4/4(含色偏)、現行 505 張與 14 張 bg 零誤殺

測試:三組回歸矩陣全過、tsc 與 eslint 與 vitest 985 全綠、002 記分守門通過

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: haotool <haotool.org@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant