lawless/docs/技术文档/TDD-02-客户端热更新技术方案.md

19 KiB

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. 设计目标

《洪荒大陆》以“概率/机遇驱动 + 玩家自发事件轮换”替代传统赛季重置,意味着活动玩法、事件池、战报文案、地图生成参数必须能高频调整,且尽量绕过应用商店审核。本方案的目标:

  1. 脚本与资源可热更:活动 UI、逻辑脚本、配置、音效、图集等通过 CDN 差量下发,无需整包发版。
  2. 运行时参数可热更:数值平衡、事件概率、经济参数等通过 Nacos 配置中心实时下发,客户端无需重启。
  3. 可灰度、可回滚:支持按设备/账号/服务器百分比灰度,失败时自动或手动回滚到旧版本。
  4. 安全可信manifest 签名校验、资源加密、防二次打包篡改。

核心约束来源TDD-00 §2.3、TDD-00 §3.5Nacos 配置中心、GDD-22 §5事件池动态调参


2. 技术选型

层级 选型 说明
客户端引擎 Cocos Creator 3.x 官方支持 Asset Bundle 热更,覆盖 Android / iOS / 鸿蒙 NEXT
热更协议 HTTP(S) + CDN 差量 Bundle 通过 CDN 边缘节点分发,支持断点续传
版本清单 自定义 manifestJSON 记录版本号、文件列表、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 算法

  1. 文件级 Diff:以文件 MD5 为粒度, manifest 中只列出新增/变更/删除的文件,客户端只下载变更文件。
  2. 二进制 Diff可选:对超过 1MB 的资源文件(如大图集、音效包)使用 bsdiff/xdelta 生成补丁包,进一步减少流量。
  3. 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 用户可选手动回滚

  1. 登录界面提供“修复/清除缓存”入口。
  2. 玩家点击后,客户端删除所有热更 Bundle,只保留首包资源。
  3. 重新走热更流程,拉取当前稳定版本。
  4. 手动回滚事件上报服务端,用于排查问题版本。

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 防篡改

  1. 运行时校验:关键脚本加载前再次校验 MD5。
  2. 文件完整性校验:每次启动时抽查部分 Bundle 文件 MD5。
  3. 非法修改检测:检测到本地文件被改动且无法通过签名验证时,触发“修复”流程。
  4. 反二次打包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.01.5.4.0),仅替换图集时资源版本号递增(1.5.3.01.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 协同及验收标准。

文档结束