完整课程入口:996 全套课程体系 | Lua 学习路径 | 幂尔框架 mirs.cn
经验翻倍、攻城战、节日活动——所有限时活动共享同一套骨架:按时间表开启、进行中接受参与、到点结算发奖。把骨架写成可复用的活动基类,新活动只填三个钩子函数,活动的时序错误(没开就结算、结算两次)从结构上杜绝。
local Activity = {}
Activity.__index = Activity
function Activity.new(cfg)
return setmetatable({ cfg = cfg, state = "closed", players = {} }, Activity)
end
function Activity:open()
if self.state ~= "closed" then return end
self.state = "running"
self.startedAt = os.time()
if self.cfg.onOpen then self.cfg.onOpen(self) end
end
function Activity:finish()
if self.state ~= "running" then return end
self.state = "settling"
if self.cfg.onSettle then self.cfg.onSettle(self.players) end
self.state = "closed"
end
cfg 表携带活动的开启条件、时长、结算函数,基类负责状态流转与重复调用防护(closed 状态下 finish 无效)。
活动进行中接受玩家登记,登记时做资格校验(等级、次数),校验通过加入 players 表。结算时只遍历 players 表发放奖励——"谁参与了"在登记时确定,结算时不重新判定,避免边界争议。入口处同样检查 state,running 之外的进入请求直接拒绝。
活动基类不自带定时器(定时器归统一调度器管),由外层按活动表驱动:调度器每分钟检查活动时间表,到点调用 open,时长到点调用 finish。全服同时只允许一个 running 的同类活动(状态字段天然防重入)。这套骨架在双倍经验、限时 Boss、答题活动三个不同形态的活动上复用,平均每个新活动的接入工作量从一天降到两小时——骨架沉淀一次,活动开发只剩填业务。
活动骨架的调试接口值得预留:给基类加一个 forceState 方法(跳过时间直接切到指定阶段),测试活动流程时不必等待真实计时。调试接口只在测试构建里编译,正式包剔除,避免被误用绕过活动时序。
结算函数里把参与玩家、发放奖励、异常剔除三类数据写入结算日志,活动纠纷的追溯以这份日志为准。留痕接口与邮箱发放共用流水表,奖励可查、发放可对,活动系统的公信力就建立在这份数据上。