11 KiB
活动 ZIP 分包与公共清单
金字塔、黄金矿工和百人赛统一接入。构建扩展位于 packages/activity-bundles,接入名单为 bundles.json:pyramid、coin_madness、art、matching、stage1、stage2、stage3。公共清单只描述资源,不包含活动开放时间、玩家资格或奖励状态。登录成功后提前准备全部受支持远程分包的磁盘缓存,活动开放判断、自动弹窗顺序和业务接口流程不变。
构建与发布
- 重启 Creator 2.4.15,使构建扩展注册。上述七个 Bundle 配置为微信远程 Bundle、合并所有 JSON;百人赛
cloud_rise_home仍为本地分包。其他平台配置不变。 - 在微信构建配置中填写 HTTPS 资源服务器地址,完整构建微信小游戏。扩展自动压缩接入名单中的每个 Bundle,生成 SHA-256、ZIP 大小及解压文件校验清单。
- 默认发布产物在
build/wechatgame-activities/remote/:公共manifest.json,以及七个<bundle>/<bundle>.<SHA-256>.zip。同样输入重复构建,ZIP 和哈希不变。旧哈希 ZIP 保留,方便旧客户端和正在运行的请求继续读取。 - 先上传哈希命名的 ZIP,确认文件可访问后,再更新
remote/manifest.json。清单禁用 CDN 缓存;ZIP 可长期缓存。代码包中的remote目录不上传到微信。ZIP 只含资源,组件脚本仍由src/scripts/<bundle>/index.js随微信代码包发布。 - 同步发布本次客户端代码。后续只改资源可更新 ZIP 和清单;修改脚本或本地依赖仍需要重新发布小游戏代码包。本工具不自动上传或发布。
已有构建目录可单独生成资源包(不编译 TypeScript,也不能替代完整构建):
node packages/activity-bundles/pack.js build/wechatgame
资源地址取自构建产物 src/settings.js 的 server,例如 https://cdn.pay.nika4games.com/remote/manifest.json。运行时不会把业务接口域名当成资源域名。微信需配置该 CDN 的 request/downloadFile 合法域名。
公共清单严格使用以下结构,每个 Bundle 仅包含 file、hash、size。hash 是整个 ZIP 的 SHA-256,size 为 ZIP 字节数。下面省略百人赛五个同结构条目;黄金矿工保留实际 Bundle 名 coin_madness:
{
"schemaVersion": 1,
"bundles": {
"pyramid": {
"file": "pyramid/pyramid.<哈希值>.zip",
"hash": "<ZIP文件的SHA-256>",
"size": 123456
},
"coin_madness": {
"file": "coin_madness/coin_madness.<哈希值>.zip",
"hash": "<ZIP文件的SHA-256>",
"size": 234567
}
}
}
Bundle 配置文件名、版本及逐文件校验信息存于 ZIP 内的 bundle-manifest.json,不加入公共清单。下载后先校验整个 ZIP,再校验内部清单与归档文件是否一致;本地缓存记录保存内部清单哈希,防止内部清单损坏导致完整性检查失效。
加载与缓存
ActivityBundleLoader.ensureBundle("pyramid") 接入 Cocos 的 Bundle 加载方式。微信构建扩展在 boot 前安装公共加载器,既支持该方法,也兼容既有 cc.assetManager.loadBundle(name, callback) 调用。编辑器和浏览器预览继续使用 Creator 原有加载方式。微信构建缺少加载器时明确报错,不悄悄退回远程目录下载。
- 登录成功时,
ActivityScheduleService.afterLogin()调用ActivityBundleLoader.beginCycle(),立即请求公共清单并后台准备接入名单中的全部分包,与活动状态请求并行,不等待活动开放、不阻塞登录完成或进入首页。服务端清单额外列出的未知分包不会下载。 - 提前准备只执行缓存检查、必要的 ZIP 下载、校验、解压及缓存保存,不注册 Bundle、不加载 Prefab 或图片。每次最多准备两个分包;正式打开活动会优先处理该包尚未开始的任务,复用正在准备或已经准备好的结果,不等待其他分包全部完成。
- 登录至首次首页共享一个资源检查周期;之后每次返回首页、切回前台开启新周期并重新后台检查全部分包。一个周期内,各活动共享一个清单请求,同一 Bundle 共享磁盘准备和引擎加载任务;已准备好的文件不在打开时重复校验。持续停留和倒计时不发起网络请求。
- 首页依据活动日程、关卡门槛和已知个人完成状态预加载金字塔 Prefab;其他页面沿用原有引擎加载时机。打开活动复用日程,个人详情单独获取。
- 缓存按资源服务器地址、Bundle 名、ZIP 哈希隔离。哈希相同且每个文件的大小、SHA-256 和 Bundle 配置都正确时使用本地解压目录;缺失或损坏时重新下载。
- ZIP 先下载到新的暂存目录,核对大小、实际 SHA-256 和归档路径后解压,再验证文件和配置。目录按层级创建,父目录先完成,同层最多八个并发;失败停止派发并等待在途 mkdir 完成后清理。全部验证成功才更新该 Bundle 的缓存记录。失败只删除该暂存目录,不覆盖旧记录、不清除其他活动缓存。
- 清单请求、解析或校验失败时,允许使用本地缓存继续加载,但仍校验缓存归属、内部清单哈希及每个文件的完整性;没有有效缓存则失败,不猜测远端版本、不下载或改写缓存记录。同周期共享加载结果,下次返回首页或切回前台重新检查清单。正常清单缺少活动条目或 ZIP 加载失败时仍报错,不回退旧缓存。
- 活动页面与进行中的 Prefab 预加载持有资源引用。新哈希可先下载,但使用中的 Bundle 保持有效,引用释放后下次加载才切换。切换时清理本 Bundle 的旧内存资源,不调用全局清缓存。
- 后台准备失败按包记录,不影响登录和其他活动。正式打开该包时允许一次前台准备重试;前台失败继续在本周期共享失败结果,避免重复渲染造成下载循环。清单失败仍遵守同周期共享和下一周期重查规则。
- 只有一份本次客户端支持的接入名单;未来接入其他活动时添加 Bundle 名、接入其开放判断和页面引用生命周期,再完整构建。
百人赛五包作为一个依赖组:retainGroup("cloudRise") 只保留引用,不发起请求;prepareGroup 在原版本检查位置选择公共清单,本身不下载 ZIP。后台准备可以下载尚未打开的阶段,但不切换内存中的资源组。页面及在途加载持有期间固定该清单,即使返回前台也不会混用新公共美术和旧页面。所有引用释放后,下次资源检查可选新清单;正式激活新版本时依赖页先于公共美术释放。离线时只允许使用与上次保存的组清单一致且校验通过的缓存,缺包就失败。
黄金矿工在登录后的后台阶段准备磁盘缓存。点击入口、每日提醒、结算通知触发时,acquireBundle 复用准备结果后注册 Bundle;若尚未准备完成,则等待其剩余步骤,之后再加载 Prefab。关闭页面后等待在途主面板、说明、结算 Prefab 回调结束及节点销毁,再释放引用;不自行调用 releaseAll/removeBundle。
黄金矿工冷缓存耗时排查
登录成功后即请求公共清单并开始磁盘准备。自动提醒在首页弹窗队列实际执行时获取 Bundle;已经准备完成时仅需引擎注册和主面板 Prefab 加载,未完成时会等待该包的剩余准备步骤。首屏数据请求与打开流程并行,面板需等待数据和资源均完成。
重新构建微信客户端后,[ActivityBundles] init 的 diagnostics 为 login-preparation-v3。按同次运行的 name: coin_madness、cycle 和时间戳查看:
manifest.ready.elapsedMs:公共清单请求及解析耗时;清单已被同周期其他活动获取时不会重复请求。preload.start:本周期全部分包后台准备启动;各包的prepare.ready表示磁盘缓存已经就绪,尚未注册引擎 Bundle。通过时间戳与engine.load对比可判断准备是否提前完成。directory.timing:phase分别记录下载、读 ZIP、ZIP 校验、归档索引、建目录、解压、内部清单、逐文件校验、保存缓存;elapsedMs为本阶段耗时,totalMs为目录准备累计耗时。缓存命中则记录verify-cache。engine.ready.elapsedMs:Cocos 注册 Bundle 耗时。
各条日志包含 timeMs,可在复制后继续对齐时序。Bundle 总耗时包含其内部阶段,统计时不要重复相加。源码计时变更需要重新构建客户端,单独上传资源 ZIP 不会更新这些日志。
从旧版本迁移
packages/cloud-rise-package/main.js 不再注册构建钩子;旧打包工具仅保留供维护旧发布使用。新构建会移除旧 cloud-rise-package 启动注入以及已迁移活动的旧 subpackage 声明。assets/cloud_rise/version.json 不再控制新客户端资源版本,无需递增。
首次迁移必须完整构建并发布新微信客户端,不能只在旧构建上运行 pack。服务器保留旧 remote/cloud_rise/version.json 及原目录服务旧客户端,不用新发布覆盖它们。旧 Cocos 文件缓存由引擎管理,不全局清理;新 ZIP 缓存独立保存。
业务接口请求时机
| 时机 | activityConfig/list |
|---|---|
| 登录成功 | 请求一次 |
| 登录后的首次首页 | 复用登录中的请求或已取得结果 |
| 从关卡等页面返回首页 | 请求一次,刷新通关后的解锁条件 |
| 后台切回前台(包括关卡内) | 请求一次;首页与全局监听共享请求 |
| 抽奖、领奖、支付确认成功 | 不请求;金字塔刷新 pyramid/api action:info |
| 首页持续停留、倒计时变化 | 不请求,按服务器校准时间本地判断 |
| 点击入口、资源预加载 | 复用日程,不额外请求列表 |
首次首页若登录查询失败或结果已失效,允许补取一次;在途请求始终合并。账号或环境变化清空个人日程,资源仍按资源服务器隔离,不按账号重复下载。
本地验证
node --test tools/test-activity-bundles.cjs tools/test-activity-resource-integration.cjs tools/test-pyramid-resource-loader.cjs
node --test tools/test-cloud-rise-bundles.cjs tools/test-cloud-rise-prefab.cjs tools/test-cloud-rise-package.cjs
node --test tools/test-activity-schedule.cjs tools/test-pyramid-entry.cjs tools/test-pyramid-home-reminder.cjs
node tools/check-pyramid-types.cjs HEAD
覆盖确定性 ZIP、SHA-256、全量后台准备与按需激活、准备并发上限与前台优先、目录并发及失败排空、缓存命中及修复、后台失败前台有限重试、下载/解压失败保留旧包、多活动/并发共享清单、环境隔离、前台新周期、旧请求延迟及活动页面持有期间更新。发布前还需在微信开发者工具与真机核对 CDN 配置和本地文件系统加载;Node 测试不能代替微信设备验证。