完整课程入口:996 全套课程体系 | Lua 学习路径 | 幂尔框架 mirs.cn
脚本热更新成熟之后,下一个难题是工程化:几百个客户端手里的脚本版本五花八门,怎么让每个人安全地升到最新?没有版本管理机制的热更,等于在裸奔状态下给行驶中的车换轮子。本文给出一套可持续的热更发布流程。
服务器维护一份版本清单(manifest):每一行是一个文件的"路径 + 内容 MD5 + 版本号 + 是否强制"。客户端启动时拉清单,逐个比对本地文件的 MD5,不一致的文件进入待更新列表。用 MD5 而不是文件修改时间,是因为时间戳在各类打包、传输环节太容易被破坏;MD5 相同即内容相同,判定可靠。
-- manifest 片段(示意)
-- path,md5,ver,force
-- script/item.lua,3fa8c21...,107,1
-- script/activity.lua,bb12d40...,23,0
全量重发一个几百 MB 的资源包不现实,差分是标配。脚本类文件小,直接整文件替换即可;大资源(图集、音频)用差分算法(如 bsdiff 思路)只下发差异块,客户端与本地旧文件合成新文件。合成必须校验:合成结果的 MD5 与清单一致才允许替换,避免半途断网留下损坏文件。
灰度发布:新版本先对 1% 玩家开放,观察错误上报曲线平稳,再逐步放量到 100%。热更引入线上事故的概率永远不为零,灰度是唯一后悔药。
回滚预案:上一版全量包常驻服务器,一键回切清单指向。回滚演练要在上线前做一次,出事时才发现回滚脚本有 bug 就太讽刺了。
清单不可变:已发布的清单文件永不修改,发新版本生成新清单文件,版本号递增。改历史清单会让缓存与 CDN 全部失灵。
兼容窗口:新脚本上线后,旧客户端可能在跑旧逻辑、发旧协议。服务端至少在一个灰度周期内同时兼容新旧协议字段,处理完老版本请求再收紧。
发布记录:每次热更记录时间、变更文件列表、操作人与原因。回滚与追责全靠它。
这套流程搭建成本大约两三天,此后每次紧急修复都能安全落地——对比一次"热更引发全服故障"的损失,这是游戏运维里回报率最高的基建投资。
addtextlist (path,str,line)
写入指定文本文件,版本清单与差分记录按行维护
| 参数 | 类型 | 说明 |
|---|---|---|
| path | string | 文件路径(必填参数) |
| str | string | 写入文本(必填参数) |
| line | integer | 行数(0-65535)(必填参数) |
addtextlist('..\\QuestDiary\\abc.txt','aaa',0)
addtextlist('..\\QuestDiary\\abc.txt','bbb',1)
getliststring(path, str, result1, result2)
获取文本文件指定行的内容,按行读取清单里的版本号
| 参数 | 类型 | 说明 |
|---|---|---|
| path | string | 文件路径(必填参数) |
| str | string | 指定行(必填参数) |
| result1 | string | 字符串(必填参数) |
| result2 | string | 返回值2当有内容穿在:时,会将:号后的字符分割返回(必填参数) |
deltextlist(path,line,model)
删除文本文件的内容,清理过期版本记录
| 参数 | 类型 | 说明 |
|---|---|---|
| path | string | 文件路径(必填参数) |
| line | integer | 指定行(0-65535)(必填参数) |
| model | integer | 删除模式0=删除行1=清空行2=删除随机行(参数2失效)(必填参数) |
md5str(str)
MD5加密,每个资源算摘要,差分只下发变化项
| 参数 | 类型 | 说明 |
|---|---|---|
| str | string | “需要加密的文本 |
checkcontainstextlist(path, str,model, result)
检查字符串是否在指定文件中,下发前先确认该版本是否已存在,避免重复更新
| 参数 | 类型 | 说明 |
|---|---|---|
| path | string | 文件路径(必填参数) |
| str | string | 字符串(必填参数) |
| model | integer | 检测模式0=列表中,是否包含被检测的字符1=被检测的字符是否包含列表中的某一行内容(必填参数) |
| result | bool | ture=在文件中false=不正文件中(必填参数) |
require(path)
加载文件,更新完成后重载脚本模块
| 参数 | 类型 | 说明 |
|---|---|---|
| path | any | 文件名两种加载接口起始路径不同 |
qfloadbegin(sysobj)
QFunction-0重载前触发,重载前做一次旧资源引用清理
| 参数 | 类型 | 说明 |
|---|---|---|
| sysobj | object | 系统对象 |