Skip to content

fix(unity): serve WebGL build from versioned directories - #85

Merged
MustaverseDigital merged 1 commit into
mainfrom
fix/unity-build-versioned-urls
Sep 2, 2026
Merged

fix(unity): serve WebGL build from versioned directories#85
MustaverseDigital merged 1 commit into
mainfrom
fix/unity-build-versioned-urls

Conversation

@chile109

@chile109 chile109 commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Problem

新版推上 Vercel 後玩家卡在 90%,必須清快取 / cookie 才能進遊戲:

Not implemented: Class::FromIl2CppType
RangeError: Maximum call stack size exceeded

四個產物(loader / data / framework / wasm)檔名固定,搭配 Cache-Control: public, max-age=86400,變成四個各自過期的快取項目。瀏覽器可能湊出「新 loader + 舊 wasm」的組合,版本錯配在 wasm 實例化時炸開 —— 90% 正是那個位置。清快取之所以有效,就是因為強制重新抓到一致的四個檔案。

Fix

改成每次 build 一個 /Build/<buildId>/ 目錄,四個檔案同進同出,不可能混搭。

  • scripts/deploy-unity-build.mjs — 搬檔進版本目錄、正規化副檔名、寫 version.json、保留最近 3 版(pnpm deploy:unity <unity-build-output-dir>)。buildId = <YYYYMMDD>-<HHMM>-<git short sha>
  • useUnityBuildVersion — 以 cache: "no-store"version.json
  • battle.tsx 拆成 BattlePage(閘門)+ UnityGame
  • 快取標頭 — 版本目錄 immutable 一年、version.json no-storevercel.jsonnext.config.js 兩邊同步)
  • .gitignore 擋掉舊的無版本檔名,避免手滑複製回來

為什麼要拆元件,不能只改 URL 字串

useUnityContext 是用 useRef首次 render 就把四個 URL 定住的,mount 之後再改 URL 完全無效(靜默失效,不會報錯)。所以必須等 buildId 到手才掛載 UnityGame,並用 key={buildId} 強制重建整棵子樹。

順帶修掉的第二個快取層

webGLDataCaching 目前是開的,loader 會把 43MB 的 data 存進 IndexedDB。它以 companyName + productName + productVersion 為命名空間,cleanUpCache() 只淘汰 version 不符的項目 —— 而原本 battle.tsx 這三個欄位一個都沒帶,所有版本共用預設 "1.0",舊 data 永遠不會被淘汰。

光做 URL 版本化解不掉這層,因此一併補上 productVersion: buildId

快取契約

Path Cache-Control
/Build/<buildId>/* public, max-age=31536000, immutable
/Build/version.json no-store, must-revalidate
/Build/*.unityweb 另加 Content-Encoding: br

version.json 必須維持不快取 —— 它就是用來查「現在最新是哪一版」的查詢點。版本目錄下的內容不會再變(改內容 = 換 buildId = 換 URL),所以可以放心 immutable 存一年:回訪玩家零下載,比原本的 24 小時更快,且不可能拿到錯配組合。

⚠️ 維持不要對這些檔案設 Content-Type: application/wasm,framework 檔名也不要留 .js —— 兩種型別都在 Vercel CDN 的自動壓縮 MIME 清單內,會在已經是 Brotli 的內容上再壓一層而破壞解碼。中性的 .unityweb 副檔名就是為了避開這件事(由 deploy 腳本自動處理)。

發版流程

pnpm deploy:unity <unity-build-output-dir>
git add public/Build && git commit && git push

Testing

  • pnpm tsc --noEmit 乾淨
  • pnpm next lint 改動檔案無新問題
  • pnpm build 通過
  • 標頭規則以 Next 自己的 pathToRegexp 逐條比對四個實際路徑,immutable / no-store / br 都落在正確的檔案上(.unityweb 規則在版本目錄下仍然命中,Brotli 沒斷)
  • 線上 header 與無痕視窗快取行為已驗證通過

Reviewer 請注意

本 PR 已驗證設定層與線上 header/快取行為,但尚未走過一次完整發版(舊版進快取 → 推新版 → 不清快取重整)。那才是「玩家不用再清快取」的最終證明,建議 merge 後首次發版時確認。

Diff 大小說明

public/Build/ 底下的產物是從固定路徑搬進版本目錄,git 判定為 pure rename,沒有新增重複 blob。

🤖 Generated with Claude Code

新版推上 Vercel 後,玩家常卡在 90%,必須清快取才能進遊戲,
console 噴 `Not implemented: Class::FromIl2CppType` 與
`RangeError: Maximum call stack size exceeded`。

原因是四個產物(loader / data / framework / wasm)檔名固定,
搭配 `Cache-Control: public, max-age=86400` 變成四個各自過期的
快取項目。瀏覽器可能湊出「新 loader + 舊 wasm」的組合,版本
錯配在 wasm 實例化時就炸開 —— 90% 正是那個位置。

改成每次 build 一個 `/Build/<buildId>/` 目錄,四個檔案同進同出,
不可能混搭:

- scripts/deploy-unity-build.mjs:搬檔、正規化副檔名、寫
  version.json、保留最近 3 版(`pnpm deploy:unity <dir>`)
- useUnityBuildVersion:以 `cache: "no-store"` 讀 version.json
- battle.tsx 拆成 BattlePage(閘門)+ UnityGame。useUnityContext
  用 useRef 在首次 render 就把 URL 定住,mount 後再改無效,
  因此拿到 buildId 才掛載,並用 key={buildId} 強制重建
- 一併補上 companyName / productName / productVersion:Unity 內建的
  IndexedDB 快取以這三者為命名空間,並清掉 version 不符的項目。
  過去沒帶,所有版本共用預設 "1.0",舊的 43MB data 永不淘汰
- 快取標頭:版本目錄 immutable 一年、version.json no-store
  (vercel.json 與 next.config.js 兩邊同步)
- .gitignore 擋掉舊的無版本檔名,避免手滑複製回來

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
aurayale-web Ready Ready Preview Sep 2, 2026 6:02am UTC

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

Dependency Review

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

Scanned Files

None

@MustaverseDigital
MustaverseDigital merged commit 23366fa into main Sep 2, 2026
8 checks passed
@MustaverseDigital
MustaverseDigital deleted the fix/unity-build-versioned-urls branch September 2, 2026 06:22
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.

2 participants