Research 02 / Sprite pipeline

把不會變的解碼,留在 build。

Boss 不是一張 sprite,而是多部件、動畫與 palette 的 miss storm。解法必須保留原版視覺,同時把首次與重複成本切開。

原始 runtime 路徑

Tyrian Sprite2 frame 由多個壓縮 component 組成。早期版本在 cache miss 時 查檔、清除 buffer、做 RLE 解碼、組成 32×32 frame,再逐 pixel 依 GBA palette pack。Boss 同時出現多部件與動畫幀時,一個 tick 可能連續觸發 五次以上 miss,足以跨過單幀預算。

11,552raw components
1,940,736 Blossless raw catalog
64 slotsEWRAM L2

依資料不變性切分

RLE 解壓與 component layout 對同一份 stock shape bank 永遠不變; palette、iced/filter 等映射則會隨關卡與事件變化。因此 build 階段只產生 原始 8-bit index,不烘焙 GBA palette:

  1. build:完整 bank RLE 無損解壓,保留原始 pixel index。
  2. L2 miss:ROM raw → 當前 palette/filter 查表 → EWRAM。
  3. L2 hit、VRAM miss:1 KiB DMA 上傳。
  4. L1 hit:直接沿用已在 VRAM 的 OBJ tiles。

這不是 per-level 圖形表。gameplay 仍從 HDT/LVL/egr 決定 哪一張 graphic;raw catalog 只提供完整且無損的通用表示。

Key、palette 與失效

L2 key 為 (shape_table, graphic, size, filter)。 L2 保存已上色 tile,因此關卡重新設定 enemy palette 時必須 flush; 若只清 VRAM L1,舊關卡色彩仍可能從 EWRAM 被重新上傳。

這個失效規則很小,卻是 cache 正確性的核心:速度來自重用, 視覺 parity 則來自知道何時不能重用。

Boss 段落結果

Episode 1 第一關完整 trace 中,Boss performance window 的 Sprite2 L2 為 100 hits、21 misses、0 fallback;L1/VRAM 仍因動畫 frame 產生 121 uploads,但不再重做 RLE。正式回歸同時要求:

  • raw catalog CRC 與 bytes 正確;
  • L2 raw build 次數必須等於 L2 misses;
  • RLE fallback、cache drop、projectile drop 必須為 0;
  • Boss missed VBlank 維持在明確預算內。

v89 進一步以全 62 關 build-time Boss manifest、runtime instance generation 與 4bpp compact cache 處理血條出現前及移動分離的超大型 Boss。這些 presentation ownership 規則整理於 OAM 與圖形快取資源排程

目前版本多部件 Boss 與最強武器壓力配置彈幕
多部件 Boss 動畫L2 warm path / VRAM DMA