Phoenix · Block Club · Skin Remote
Tổng hợp luồng tách skin ra khỏi client, đóng gói thành bundle tải từ server, và cách client Cocos tải lại với retry / timeout / fallback. Mô phỏng đúng luồng remote của game gốc Block Blast Classic.
Skin không nhúng hết vào client. Mỗi skin remote (nhóm id 2xxx/3xxx/4xxx/5xxx) là một bundle Cocos riêng nằm trên server. Client chỉ giữ skin cơ bản 10xx; khi cần skin remote thì hỏi server để biết tải skin nào, rồi assetManager.loadBundle kéo bundle về.
config.json + import/ + native/..zip cho bản native.GET /config trả pool skin; GET /remote/... phục vụ file tĩnh.loadBundle có retry/timeout → fallback 1000 nếu lỗi.Bước build bundle thật sự chỉ Cocos Editor làm được. Các script trong repo chỉ sắp xếp asset và đóng gói quanh bước đó.
| Việc | Công cụ | Kết quả |
|---|---|---|
Tách asset per-skin khỏi resources/ vào thư mục bundle riêng remote-bundles/Remote_Skin_Material_<id>/ |
build-remote-bundles.mjs |
Mỗi id một thư mục, đủ format 1 skin: bg + board + shadow + cube_1..7 (skin mượn bg/board của skin khác thì copy kèm) |
| Đánh dấu thư mục là Asset Bundle và build web-mobile | Cocos Editor | Sinh bundle hợp lệ: config.json, import/, native/, index.js |
Đóng gói mỗi bundle thành Remote_Skin_Material_<id>.zip (cho bản native tải zip về giải nén) |
zip-remote-bundles.mjs |
Zip chứa nội dung bundle ở gốc zip → giải nén ra là bundle dùng ngay |
build-remote-bundles.mjs chỉ di chuyển asset đúng chỗ kèm .meta, chạy lại idempotent. Nó KHÔNG tạo được bundle Cocos — phải mở Editor đánh dấu Asset Bundle rồi build mới ra config.json/import/native.# Sắp xếp asset per-skin thành thư mục bundle (2/3/4/5xxx)
node tools/skin-test-server/build-remote-bundles.mjs
node tools/skin-test-server/build-remote-bundles.mjs 2006 3012 4001 # chỉ vài id
node tools/skin-test-server/build-remote-bundles.mjs --dry # xem kế hoạch
# → Mở Cocos Editor: đánh dấu từng thư mục là Asset Bundle, build web-mobile
# Nén bundle đã build thành .zip (cho bản native)
node tools/skin-test-server/zip-remote-bundles.mjs
node tools/skin-test-server/zip-remote-bundles.mjs 2006 3012
tools/skin-test-server/server.mjs · cổng 8099
GET /config?device=<id> — mô phỏng server quyết định: trả { remoteBaseUrl, changeSkinEnabled, rotation, abTest, variant, pool[] }.GET /remote/Remote_Skin_Material_<id>/... — phục vụ file tĩnh của bundle.GET /health → { ok: true }.catalog.available + A/B test (giống trait engine gốc).config.json mỗi request → sửa config có hiệu lực ngay, không restart.fault.mode) để test client: hang, error500, notfound.REMOTE_DIR (env)bundles/ trong folder server (tự đủ, mang đi đâu cũng chạy)game/build/web-mobile/remote (build repo chính)mock/ (config giả, chỉ để test probe)SkinServerClient.ts + SkinBundleLoader.ts
?bundle=1 vào URL, hoặc set window.__SKIN_REMOTE__ = true. Mặc định TẮT (SKIN_REMOTE_ENABLED).SkinServerClient gọi GET /config?device=<id> → nhận pool skin + rotation + cờ đổi skin.rotation (random no-repeat / sequence).SkinBundleLoader gọi assetManager.loadBundle(<base>/Remote_Skin_Material_<id>) với retry + timeout.fflate unzipSync) → loadBundle(thư mục giải nén). Web: loadBundle thẳng từ URL thư mục.GameView._applyThemeCore.Mô phỏng đúng game gốc: tải / áp dụng skin thất bại không crash, không chặn người chơi, revert về skin default 1000.
| Cơ chế | Mặc định | Hành vi |
|---|---|---|
maxRetryCount | 2 (tổng 3 lần) | Số lần thử lại khi engine báo lỗi |
retryIntervalMs | 2000 ms | Khoảng cách giữa các lần thử |
timeoutMs | 8000 ms | Timeout thủ công cả quá trình — tránh treo khi server không đóng kết nối |
Set _failed | per-session | Id đã fail không thử lại ngay → tránh spam server mỗi lần clear bàn |
| Fallback | skin 1000 | Hết retry / timeout / lỗi → callback(null) → caller giữ hoặc revert skin default |
| mode | Test điều gì |
|---|---|
| none | Luồng bình thường |
| hang | Server treo → kiểm tra timeout thủ công của client |
| error500 | Lỗi server → kiểm tra retry + fallback |
| notfound | Bundle không tồn tại → kiểm tra fallback skin 1000 |
Mẫu đã dựng: 2006 (DragonBones), 3012 + 4001 (Spine). Chỉ skin có asset trong resources và map được THEMES mới đổi nhìn thấy được.
# 1. Chạy server
node tools/skin-test-server/server.mjs # http://127.0.0.1:8099
PORT=8099 node tools/skin-test-server/server.mjs # đổi cổng
# 2. Mở client web kèm cờ bật remote
# <url game>?bundle=1 → tải 3 skin remote 2006/3012/4001
# <url game>?bundle=1&device=deviceA → nhánh A/B test
# 3. Sửa config.json → F5 client (server đọc lại mỗi request, không cần restart)
?bundle=1, hỏi config, chọn skin, loadBundle có retry/timeout, fallback 1000 khi lỗi. (4) Native tải zip giải nén, web load thẳng URL.