脚本的坏提交混进主线,当晚的更新就带着语法错误上线——全服回档的代价教会团队一件事:校验必须在提交时发生。CI 流水线把语法检查、触发器名白名单、冒烟用例串成门禁,坏提交在合并前被拦下。
---提交校验:语法 + 触发器名白名单
function CI.check(files)
for _, f in ipairs(files) do
-- 语法检查:加载失败即拦截
local ok, err = loadfile(f)
if not ok then
return false, f .. " 语法错误: " .. tostring(err)
end
-- 触发器名白名单:拼写错误在这里现形
local src = CI.read(f)
for name in src:gmatch("function%s+([%w_]+)") do
if TRIGGER_HINT[name] == nil and QF_NAMES[name] == nil
and not ENGINE_APIS[name] then
return false, f .. " 未登记的函数名: " .. name
end
end
end
return true
end
第一道门是 loadfile 的语法检查,语法不过直接拒绝合并。第二道门是函数名白名单:QF 触发器(beginmagic、attack、killmon 等真名表)与引擎接口名(mapmove、rangeharm、sendmail 等)集中登记,拼错的触发函数不会报错但永远不执行——这类静默故障靠白名单在提交期现形。
---冒烟:起服跑关键用例
setontimerex(50, 5)
function CI.smoke()
local cases = {
"登录并移动到比奇省",
"召唤祖玛教主并击杀结算掉落",
"mapmove 传送沙巴克并回城",
"sendmail 发送测试邮件并领取",
}
for _, c in ipairs(cases) do
local ok, msg = BotRunner.run(c)
if not ok then
CI.fail(c, msg)
return
end
end
CI.pass()
end
静态检查过了就起一个临时服跑冒烟用例:登录移动、召唤祖玛教主击杀验证掉落结算、传送沙巴克验证地图加载、发邮件验证附件流转,12 个关键用例覆盖主链路。用例全绿门禁放行,任意一红阻断合并并通知提交者。门禁的总耗时控制在 90 秒内——超过三分钟开发者就开始绕过门禁,速度是纪律的生命线。
门禁的拦截率与误拦率周报,误拦超过 5% 规则回炉;流水线自身的成功率监控,CI 挂掉比没有 CI 更伤士气。
白名单曾经只有触发器名,引擎接口的拼写错误漏网,接口表并进白名单。冒烟用例曾经共享一套存档,用例间的脏数据让绿与红随机翻转,用例隔离到独立存档。流水线曾经串行跑检查,90 秒的目标跑出 4 分钟,语法与白名单并行后达标。
门禁的规则版本化,规则的变更与代码同评审。红了的提交修复优先级最高,绕过门禁的权限只给管理员并全量留痕。冒烟用例随线上事故扩充:每次线上事故回补一条对应用例,门禁的覆盖面与事故教训同步生长。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 全服 400 多个 NPC 脚本在开服瞬间集中加载,引擎进程启动耗时 47 秒,值班期间重启就是 47 …
实战应用:用在哪里 行会跨图集合靠世界喊话,从比奇赶到沙巴克动辄三分钟,集合效率低。行会驿站给每个行会一个专属传送网络:驿站…
实战应用:用在哪里 跨服战场周日结算夜出了双事故:30 名玩家积分凭空翻倍,随后 12 名玩家积分变成负数。两条线索指向同一…
实战应用:用在哪里 烈火剑法点到一半想换逐日剑法,没有遗忘功能只能养小号,新手加点点废的投诉长期霸榜。技能遗忘与重修框架管三…
实战应用:用在哪里 战斗日志全量滚动,烈火剑法暴击、治疗、拾取一场下来上千条,列表越长滑动越卡。改造分两件事:内存里只留最近…
实战应用:用在哪里 夏季活动缺一个全服参与的轻竞速,选定龙舟:五人一队从白日门河道上游划向盟重码头,河道布设障碍与顺流带,全…