完整课程入口:996 全套课程体系 | Lua 学习路径 | 幂尔框架 mirs.cn
新功能上线想先对 5% 玩家开放、活动出问题时想 30 秒内关闭入口、按渠道区分功能可见性——这些都不该靠改代码热更。feature flag(功能开关)把这些决策变成一份服务端配置,客户端与脚本按开关名取状态。适用于:活动入口、新玩法灰度、付费功能分层、应急止血。
开关集中存一份文本或数据库记录,每行 开关名|状态|参数,脚本启动与定时刷新时加载:
local Flags = { map = {}, version = 0 }
function Flags.load(text)
Flags.map = {}
for line in (text or ""):gmatch("[^\n]+") do
local name, on, arg = line:match("^(%S+)|(%S+)|?(.*)$")
if name then Flags.map[name] = { on = on == "1", arg = arg } end
end
Flags.version = Flags.version + 1
end
function Flags.enabled(name)
local f = Flags.map[name]
return f ~= nil and f.on
end
业务侧一行判断:if Flags.enabled("boss_rush") then openBossRush() end。开关关闭时入口直接不可见,已进入的玩家由 arg 里的宽限参数控制是否强制退出。
灰度策略写进参数:boss_rush|1|percent:5 表示对 5% 玩家开放,判断用玩家 uid 取模(uid % 100 < 5),同一玩家结果稳定,不会出现刷新界面时开关忽开忽关。放量节奏 5% → 20% → 50% → 100%,每档观察错误上报与性能曲线 30 分钟。
应急止血是开关的第一价值:活动脚本异常时,把对应开关置 0 并推送(文本文件改一行或调用后台接口),入口 30 秒内从所有客户端消失,远快于热更修复。开关记录全部留痕:谁在何时改了哪个开关、从什么值改成什么值。
开关只控制"入口与路径",不控制"数据正确性"——奖励计算这类核心逻辑不允许被开关跳过校验。开关数量定期清理,下线功能的开关连同旧代码一起删除,半年不清理的开关表会变成无人敢动的考古现场。开关名同时进团队常量表统一管理,与事件总线的事件名同一套命名纪律。
开关功能上线前核对三项:开关读取失败时的默认行为已定义(建议默认关闭);灰度取模规则与玩家 uid 的对应关系已测试;应急止血流程已演练一次,从发现问题到开关生效的实测时间记录在案。三项齐备后,这个开关才算真正可交付。