TDD-02 客户端热更新技术方案
文档类型:技术设计方案(Technical Design Document)
版本:v1.0
日期:2026-06-30
关联文档:TDD-00《挂机手游技术栈方案.md》、TDD-04《数据库表结构设计》、PRD-03《热更新与活动系统需求文档》(待创建)、GDD-06《经济系统设计》、GDD-08《大陆地图与区域开放系统》、GDD-18《世界地图副本遗迹生成引擎》、GDD-22《开放世界随机事件与玩家可交互内容层》
1. 设计目标
《洪荒大陆》以“概率/机遇驱动 + 玩家自发事件轮换”替代传统赛季重置,意味着活动玩法、事件池、战报文案、地图生成参数必须能高频调整,且尽量绕过应用商店审核。本方案的目标:
- 脚本与资源可热更:活动 UI、逻辑脚本、配置、音效、图集等通过 CDN 差量下发,无需整包发版。
- 运行时参数可热更:数值平衡、事件概率、经济参数等通过 Nacos 配置中心实时下发,客户端无需重启。
- 可灰度、可回滚:支持按设备/账号/服务器百分比灰度,失败时自动或手动回滚到旧版本。
- 安全可信:manifest 签名校验、资源加密、防二次打包篡改。
核心约束来源:TDD-00 §2.3、TDD-00 §3.5(Nacos 配置中心)、GDD-22 §5(事件池动态调参)。
2. 技术选型
| 层级 |
选型 |
说明 |
| 客户端引擎 |
Cocos Creator 3.x |
官方支持 Asset Bundle 热更,覆盖 Android / iOS / 鸿蒙 NEXT |
| 热更协议 |
HTTP(S) + CDN |
差量 Bundle 通过 CDN 边缘节点分发,支持断点续传 |
| 版本清单 |
自定义 manifest(JSON) |
记录版本号、文件列表、MD5、依赖关系、diff 包地址 |
| 差量生成 |
服务端 diff 工具 |
基于文件级 MD5 对比生成差异包;大文件使用 bsdiff 二进制差分 |
| 运行时配置 |
Nacos 2.x |
经济、战斗、事件、地图参数实时下发,无需客户端重启 |
| 灰度控制 |
服务端版本接口 + Nacos |
按 device_id / account_id / server_id / 百分比控制可见版本 |
| 回滚 |
本地缓存旧 Bundle + 服务端回切版本号 |
自动检测到异常后回退;玩家也可在登录界面手动选择“修复” |
不采用 Cocos 官方 cc.AssetManager 内置热更整包(project.manifest),而是基于 Asset Bundle 远程加载 + 自定义 manifest 的轻量方案,避免全量 manifest 体积过大,并支持更灵活的灰度策略。
3. 热更范围
3.1 可热更资源(无需商店发版)
| 资源类型 |
存放位置 |
示例 |
说明 |
| TypeScript/JavaScript 脚本 |
bundles/game-core/scripts/ |
活动玩法逻辑、战斗结算、随机事件处理 |
脚本以 Bundle 形式发布,运行时被 import() |
| JSON/Excel 导出配置 |
bundles/configs/ |
掉落表、技能参数、地图事件池、经济参数(运行时仍优先 Nacos) |
作为本地兜底与离线缓存 |
| UI 预制体 |
bundles/ui/ |
活动面板、战报详情、交易行界面 |
支持新增/替换 Prefab |
| 图集与纹理 |
bundles/atlases/ |
活动图标、种族头像、地图地块 |
按功能分包,减少下载量 |
| 音效与音乐 |
bundles/audio/ |
事件音效、背景音乐 |
可按平台选择格式 |
| 战报文案 |
bundles/i18n/ |
战斗日志模板、事件描述 |
支持多语言热更 |
3.2 必须整包更新的资源(需商店发版)
| 资源类型 |
原因 |
| 引擎版本升级 |
Cocos Creator 引擎核心库变更,无法通过 Bundle 替换 |
| 原生插件 / Native Bridge |
支付、推送、登录 SDK 等原生代码变更 |
| 启动场景(首包) |
启动器本身不能依赖待下载资源 |
| 应用图标 / 启动图 / 权限声明 |
商店包元数据变更 |
| 重大协议变更 |
protobuf 结构体不兼容旧客户端,必须强更 |
原则:能热更就不发版。每次发版前由技术负责人确认是否属于“必须整包更新”范围。
4. 版本号与清单
4.1 版本号规则
采用四级版本号:主版本.次版本.热更版本.资源版本
| 位 |
名称 |
变更时机 |
示例 |
| 第 1 位 |
主版本 |
大版本迭代、引擎升级、重大架构重构 |
2.0.0.0 |
| 第 2 位 |
次版本 |
新增系统、玩法里程碑、商店强更 |
1.5.0.0 |
| 第 3 位 |
热更版本 |
通过热更发布的逻辑/配置更新 |
1.5.3.0 |
| 第 4 位 |
资源版本 |
仅资源替换(图集、音效、文案),无脚本变更 |
1.5.3.12 |
- 兼容性规则:主.次 不一致视为不兼容,必须整包更新;热更.资源 不一致可通过热更修复。
- 版本比较:按位逐次比较,高位优先。
4.2 Manifest 格式
{
"version": "1.5.3.12",
"min_compatible_version": "1.5.0.0",
"bundle_name": "game-core",
"release_note": "修复战报文案;新增端午节活动",
"grayscale_group": "all",
"grayscale_ratio": 1.0,
"files": [
{
"path": "scripts/activity/dragon-boat.js",
"size": 12480,
"md5": "a1b2c3d4e5f6...",
"compressed": true,
"download_url": "https://cdn.example.com/bundles/game-core/1.5.3.12/scripts/activity/dragon-boat.js.lz4"
},
{
"path": "configs/event-pool.json",
"size": 8192,
"md5": "f6e5d4c3b2a1...",
"compressed": true,
"download_url": "https://cdn.example.com/bundles/game-core/1.5.3.12/configs/event-pool.json.lz4"
}
],
"deleted": ["scripts/activity/spring-festival.js"],
"signature": "SHA256-RSA-SIGNATURE-HERE"
}
4.3 Diff 算法
- 文件级 Diff:以文件 MD5 为粒度, manifest 中只列出新增/变更/删除的文件,客户端只下载变更文件。
- 二进制 Diff(可选):对超过 1MB 的资源文件(如大图集、音效包)使用 bsdiff/xdelta 生成补丁包,进一步减少流量。
- Bundle 级 Diff:每个 Asset Bundle 独立生成 manifest;不同 Bundle 之间无依赖时允许并行下载。
5. 热更流程
5.1 文字流程图
客户端启动
│
▼
读取本地 manifest(各 Bundle 当前版本)
│
▼
请求服务端版本接口 /hotfix/version
携带:当前主.次版本、各 Bundle 热更/资源版本、device_id、account_id、server_id、渠道号
│
▼
服务端返回目标版本 + 灰度标识 + manifest_url
│
▼
版本兼容性检查
├─ 主.次版本 < min_compatible_version ──→ 弹强更提示,跳转商店下载
│
└─ 主.次版本兼容 ──→ 继续
│
▼
灰度判定(服务端已按设备/账号/百分比计算)
├─ 未命中灰度 ──→ 使用 CDN 上旧版本 manifest_url,跳过更新
│
└─ 命中灰度 ──→ 使用新版本 manifest_url
│
▼
下载新 manifest
│
▼
比对本地与新 manifest 文件列表
│
▼
生成待下载文件列表(新增 + MD5 变更)
│
▼
并行下载差分包(支持断点续传、失败重试 3 次)
│
▼
逐文件校验 MD5 与数字签名
├─ 校验失败 ──→ 标记该文件失败,重试;连续失败则回滚到旧版本
│
└─ 校验通过 ──→ 写入临时目录
│
▼
所有文件就绪后原子移动到正式 Bundle 目录
│
▼
更新本地 manifest
│
▼
若涉及脚本/配置变更:
├─ 可在运行时重载的 ──→ 即时生效(如 Nacos 配置、战报文案)
├─ 需要重新加载 Bundle 的 ──→ 触发 Bundle 重载,回到登录界面
└─ 涉及启动逻辑的 ──→ 提示“重启游戏生效”
│
▼
进入游戏
5.2 关键时序说明
| 阶段 |
责任方 |
关键动作 |
| 版本决策 |
服务端 /hotfix/version |
根据客户端版本、灰度策略、渠道包返回目标版本 |
| 清单分发 |
CDN |
manifest 与差分包均走 CDN,源站故障时不影响已缓存资源 |
| 下载校验 |
客户端 |
MD5 + 签名双重校验,失败文件不入正式目录 |
| 原子应用 |
客户端 |
先写入 {bundle}/_temp/,全部成功后再 rename 到 {bundle}/ |
| 生效方式 |
客户端 + 服务端 |
运行时配置走 Nacos;Bundle 级变更走重载/重启 |
6. 灰度与回滚
6.1 灰度策略
| 维度 |
说明 |
优先级 |
| 设备分组 |
按 device_id 尾号 / UUID hash 分桶 |
高 |
| 账号分组 |
按 account_id 尾号 / 白名单 |
高 |
| 服务器分组 |
仅对指定 server_id 开放 |
中 |
| 渠道分组 |
Android / iOS / 鸿蒙 / 特定渠道包 |
中 |
| 百分比 |
0% → 5% → 20% → 50% → 100% 阶梯放量 |
低(兜底) |
- 灰度控制存储于 Nacos
hotfix.grayscale 配置项,可在不重启服务端的情况下调整。
- 客户端请求
/hotfix/version 时,服务端实时查询 Nacos 灰度配置并计算是否命中。
- 灰度命中后,服务端返回新版本 manifest_url;未命中则返回当前稳定版本。
6.2 自动回滚
客户端检测到以下任一情况
│
├─ 新 Bundle 加载后连续崩溃 3 次
├─ 关键接口(登录/拉取角色)失败率 > 30%
├─ 校验失败文件数 > 阈值
└─ 启动阶段热更流程异常中断
│
▼
自动将本地 manifest 回退到上一稳定版本
删除/隔离异常 Bundle 文件
│
▼
下次启动时向服务端上报 rollback_event
服务端根据上报动态降低该版本灰度比例或关闭灰度
6.3 用户可选手动回滚
- 登录界面提供“修复/清除缓存”入口。
- 玩家点击后,客户端删除所有热更 Bundle,只保留首包资源。
- 重新走热更流程,拉取当前稳定版本。
- 手动回滚事件上报服务端,用于排查问题版本。
7. 异常处理
| 异常场景 |
处理策略 |
用户体验 |
| 下载失败 |
单文件重试 3 次;失败文件加入重试队列;全部失败则回滚 |
显示“资源更新失败,正在恢复” |
| 校验失败(MD5/签名) |
删除该文件,重新下载;连续 3 次失败则标记版本异常 |
提示“资源校验失败,尝试重新下载” |
| 存储不足 |
下载前预估所需空间;空间不足时提示清理缓存或只下载必要 Bundle |
提示“存储空间不足,请清理后重试” |
| 网络中断 |
支持断点续传;网络恢复后继续下载 |
显示“等待网络连接” |
| 版本不兼容 |
主.次版本低于 min_compatible_version 时强更 |
弹窗“请前往商店下载最新版本” |
| CDN 节点异常 |
客户端回退到备用 CDN 域名或源站 |
无感切换(最多 1 次重试可见) |
| 灰度配置冲突 |
服务端返回明确的目标版本,客户端不自行决策 |
以服务端返回为准 |
所有异常均需上报埋点,字段包括:错误码、版本号、设备型号、网络类型、失败文件、重试次数。
8. 安全
8.1 Manifest 签名
- manifest 文件由 CI/CD 流水线使用服务端 RSA 私钥签名,客户端使用内置公钥验签。
- 签名覆盖 manifest 全部字段(version、files、deleted、grayscale 等),防止中间人篡改下载地址或版本号。
- 公钥随首包硬编码,不通过热更下发。
8.2 资源加密
| 资源类型 |
加密方式 |
说明 |
| 脚本(JS/TS 编译后) |
XXTEA / AES-128-CBC |
下载后解密再加载,防止直接读取源码 |
| 配置文件(JSON) |
同上 |
策划配置不外泄 |
| 图集/纹理 |
可选轻度混淆 |
美术资源优先级较低,视情况加密 |
| 音效 |
不加密或简单 XOR |
降低运行时解密开销 |
- 密钥派生:由客户端内置主密钥 + 当前版本号派生,每个版本密钥不同。
- 加密密钥不直接出现在客户端源码中,采用 Native 层安全存储或代码混淆。
8.3 防篡改
- 运行时校验:关键脚本加载前再次校验 MD5。
- 文件完整性校验:每次启动时抽查部分 Bundle 文件 MD5。
- 非法修改检测:检测到本地文件被改动且无法通过签名验证时,触发“修复”流程。
- 反二次打包:Native 层校验 APK/IPA 签名与包名;签名不一致则拒绝启动。
9. 与 Nacos 的协同
9.1 运行时配置热更(无需客户端重启)
TDD-02 处理的“客户端热更”主要指 Bundle 资源/脚本更新;而数值参数、事件概率、经济参数等应优先通过 Nacos 实时配置下发,无需下载 Bundle 也无需重启客户端。
| 配置命名空间 |
用途 |
示例 |
关联 GDD |
economy |
经济参数 |
掉落倍率、交易行税率、货币兑换比例 |
GDD-06 |
combat |
战斗参数 |
技能伤害系数、ATB 速度公式、渡劫难度 |
GDD-03 / GDD-12 |
event |
事件参数 |
随机事件触发权重、事件链分支概率 |
GDD-22 |
map_gen |
地图生成 |
副本/遗迹刷新间隔、资源点密度 |
GDD-08 / GDD-18 |
drop |
掉落配置 |
怪物掉落表、宝箱掉落池 |
GDD-19 / GDD-21 |
hotfix |
热更控制 |
版本目标、灰度比例、强制更新开关 |
TDD-02 |
9.2 客户端 Nacos 长轮询流程
客户端登录成功后
│
▼
建立 Nacos 长轮询 / 监听指定 dataId + group
│
▼
Nacos 配置变更时推送通知
│
▼
客户端拉取最新配置
│
▼
配置合法性校验(JSON Schema / 范围检查)
├─ 不合法 ──→ 丢弃并告警
│
└─ 合法 ──→ 应用到本地配置缓存
│
▼
触发相关模块重载(战斗计算器、经济计算器等)
9.3 与数据库 dynamic_configs 的关系
- 运行时主配置源:Nacos。
- 本地快照/审计:
dynamic_configs 表(见 TDD-04 §5.13)仅用于记录配置历史、灰度记录、回滚审计。
- 服务端逻辑直接从 Nacos 读取;
dynamic_configs 不用于实时决策。
10. CDN 与热更服务架构
┌─────────────────────────────────────────────────────────────┐
│ CI/CD 流水线 │
│ 构建 Bundle → 生成 manifest → diff → 签名 → 上传 CDN 源站 │
└───────────────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ CDN 边缘节点 │
│ manifest.json / diff bundles / 全量 bundles │
└───────────────────────────┬─────────────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────────────────────────┐
│ 客户端(Cocos Creator 3.x) │
│ 启动器 → /hotfix/version → 下载 manifest → diff → 校验 → 应用 │
│ 登录后 → Nacos 长轮询 → 运行时配置热更 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 服务端(Nakama / Gin) │
│ /hotfix/version:版本决策 + 灰度计算 │
│ Nacos 配置中心:运行时参数 + 灰度策略 │
└─────────────────────────────────────────────────────────────┘
11. 验收标准
| 编号 |
验收项 |
可测试标准 |
| AC-01 |
版本号管理 |
修改脚本后热更版本号正确递增(如 1.5.3.0 → 1.5.4.0),仅替换图集时资源版本号递增(1.5.3.0 → 1.5.3.1) |
| AC-02 |
差量下载 |
两次热更之间仅下载变更文件;删除文件在本地被正确移除 |
| AC-03 |
校验机制 |
篡改 manifest 签名或文件 MD5 后,客户端拒绝应用并触发回滚 |
| AC-04 |
灰度放量 |
配置 5% 灰度后,约 5% 设备命中新版本;调整至 100% 后全部命中 |
| AC-05 |
自动回滚 |
模拟新版本脚本崩溃 3 次,客户端自动回退到上一稳定版本并能正常启动 |
| AC-06 |
存储不足 |
在存储不足设备上触发更新,客户端给出明确提示并不进入死循环 |
| AC-07 |
Nacos 运行时配置 |
修改 Nacos economy.drop_rate 后,客户端在 30 秒内生效且无需重启 |
| AC-08 |
跨平台一致 |
Android / iOS / 鸿蒙 NEXT 三端使用同一 manifest 与 CDN 地址,热更行为一致 |
12. 与现有文档的冲突与说明
| 编号 |
检查项 |
结论 |
| C01 |
与 TDD-00 热更方案是否一致 |
✅ 一致。TDD-02 在 TDD-00 基础上细化 manifest、diff、灰度、安全、Nacos 协同。 |
| C02 |
与 TDD-04 dynamic_configs 表是否一致 |
✅ 一致。TDD-02 明确 Nacos 为主配置源,dynamic_configs 仅做审计快照。 |
| C03 |
与 PRD-03 活动/事件热更需求是否对齐 |
⚠️ PRD-03 尚未创建。TDD-02 已预留接口:事件池配置既可通过 Nacos 实时调参,也可通过 Bundle 热更下发完整事件脚本。 |
| C04 |
与 GDD-22 随机事件系统是否冲突 |
✅ 无冲突。GDD-22 要求事件池动态维护,TDD-02 提供 Bundle 热更 + Nacos 调参两种手段。 |
| C05 |
版本号规则是否覆盖 GDD-21 数值版本 |
✅ GDD-21 为数值设计文档,不定义版本号;TDD-02 四级版本号专门用于客户端/资源版本管理。 |
13. 版本记录
| 版本 |
日期 |
修改人 |
变更说明 |
| v1.0 |
2026-06-30 |
- |
初稿:完成技术选型、热更范围、版本号与 manifest、热更流程、灰度回滚、异常处理、安全、Nacos 协同及验收标准。 |
文档结束