活动期的掉率要翻倍、BOSS 的血量要回调、补偿要立刻发——这些改动等不了下一次停服。配置热更新让数值的调整在线上滚动生效:文件一改、几十秒后全服生效,运营的手感与玩家的体验同频。
---定时器扫描配置文件的修改时间
setontimerex(82, 15)
function HotCfg.tick()
for name, path in pairs(HotCfg.paths) do
local mtime = HotCfg.mtimeOf(path)
if mtime ~= HotCfg.loadedAt[name] then
local ok, tbl = HotCfg.load(path)
if ok then
HotCfg.tables[name] = tbl
HotCfg.loadedAt[name] = mtime
Ops.log("热更生效: " .. name)
else
Ops.alert("热更失败(格式错): " .. name)
end
end
end
end
定时器每 15 秒扫一轮配置文件的修改时间,mtime 变化即重载:加载成功替换内存表并记录时间戳,加载失败告警且保留旧表——坏的配置文件在半路被拦,线上跑着的永远是上一份完好的配置。生效的窗口 15 到 30 秒,运营改完掉率去打一只祖玛教主验证,反馈的回路比发版快一百倍。
---业务读表:永远走代理入口
HotCfg.tables = { drop = {}, mon = {}, shop = {} }
function HotCfg.get(name)
return HotCfg.tables[name]
end
---掉落结算:每次读表拿到最新值
function Drop.roll(monName)
local tbl = HotCfg.get("drop")
local cfg = tbl[monName]
if not cfg then return nil end
for _, d in ipairs(cfg.items) do
if math.random(1, 10000) <= d.rate then
return d.item
end
end
return nil
end
生效的语义靠读的纪律:业务代码不缓存配置表的引用,每次结算走 HotCfg.get 的代理入口——热更换的是 tables 里的表,持有旧引用的代码读不到新值,这是热更失效的头号原因。引用的替换是原子的(整表换新),读侧不会见到半新半旧的配置。热更的边界同样要立规矩:结构性的变更(加字段、改格式)不走热更,热更只承诺值的调整,结构与值的分界写进配置文档。每次热更留痕:谁改的、改了哪个表、生效时刻,配置的变更史与版本库同步归档。
热更的生效延迟监控,从文件落盘到内存替换的耗时分布;配置的读侧扫描,缓存旧引用的代码在评审与静态检查双重拦截。
业务曾经缓存了掉率表的局部引用,热更后全服还是旧掉率,排查两小时定位到引用缓存,代理入口的规范执行。mtime 的秒级精度曾经让一分钟内的两次修改只生效一次,内容哈希的比对辅助判断。热更的失败曾经静默,运营以为改了实际没生效,失败的告警与生效的日志双通道。
热更的白名单只含数值表,逻辑表(触发、脚本)的变更走发布流程。热更的权限收敛到运营主管,变更的审计按人归档。活动期的配置变更提前公告,玩家对数值变化的知情权是信任的一部分。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 战士的烈火剑法一击熄火后要等八秒冷却,连招断档感强烈。疾风烈火斩在烈火剑法命中后给一次连击窗口:三秒内再…
实战应用:用在哪里 阵营对抗打到中期容易疲软:打赢没有额外好处,输掉也没有代价。阵营声望体系给阵营战装上荣誉刻度:个人与阵营…
实战应用:用在哪里 拿下沙巴克之后呢?城主除了名字挂在城墙上,对城市毫无影响。城主施政玩法让占领变成治理:城主每周获得市政令…
实战应用:用在哪里 主线路光缆被挖断的深夜,全服掉线 20 分钟,玩家以为游戏倒闭。备用线路方案给接入层配第二条出口:主线路…
实战应用:用在哪里 行会官员由帮主任命的老模式弊端明显:任人唯亲、能上不能下。行会选举接口把官员换届做成投票制:每两个月一次…
实战应用:用在哪里 烈火剑法的伤害加成、冷却时间、下一级提升,全靠玩家记忆或去官网查。技能说明悬浮卡片在鼠标悬停技能图标零点…