讨伐沃玛教主的活动链路是:接任务、杀怪、领奖、领进度奖励,每一步都有前置条件。散装写法用一堆 if 嵌套判断,跳步领奖、重复领奖的口子越修越多。工程化做法是把流程收敛成状态机:状态、合法迁移、迁移奖励全部收敛到一张表里,流程推进只有一个入口。
状态机用"当前状态 => 迁移函数"的表驱动,推进函数只认表不认分支。先定义状态表与推进器:
local FSM = {
start = { next = "hunting" },
hunting = { next = "rewarded" },
rewarded = { next = nil },
}
local function fsmPush(actor, ev)
actor = getplayerbyname(actor)
local cur = getplayvar(actor, "HUMAN", "WomaFsm")
if cur == "" then cur = "start" end
local node = FSM[cur]
if node == nil or node.next == nil then
sendmsg(actor, 1, "讨伐任务已完成,无法重复领取。")
return
end
setplayvar(actor, "HUMAN", "WomaFsm", node.next, 1)
sendmsg(actor, 1, "讨伐进度推进:" .. cur .. " => " .. node.next)
end
再挂业务动作:状态到达 rewarded 时发奖,奖励只在这一处出现,天然防重复。
local function onWomaDead(actor)
actor = getplayerbyname(actor)
local cur = getplayvar(actor, "HUMAN", "WomaFsm")
if cur == "hunting" then
fsmPush(actor, "kill")
giveitem(actor, "沃玛号角", 1)
end
end
getplayvar(actor, model, varName):读自定义变量,model 取 HUMAN(人物)或 GUILD(行会),变量不存在返回空串。setplayvar(actor, varType, varName, varValue, isSave):写变量,isSave 传 1 才落库,不传只驻内存,重启即丢——任务进度必须传 1。giveitem(actor, itemname, num, bind, desc):发物品,bind 传 1 为绑定,desc 写来源便于审计。sendmsg(actor, type, msg):聊天框消息,注意是三个参数,没有颜色位。
状态机上线后踩过三个坑:一是状态键没加活动期次后缀,第二期活动老玩家状态残留,接不了新任务,键名必须拼上期次号如 WomaFsm_S3;二是迁移动作写在两处,杀怪与交任务各写了一遍发奖逻辑,双杀触发两次发奖,收口成"奖励只在目标状态到达处发一次";三是 isSave 漏传,停机维护后全员进度清零,补偿邮件发了一千七百封。状态机的价值不在写法漂亮,而在把所有合法路径收敛到一张表,非法路径天然走不进去。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
设计初衷 行会系统的通病是"人多力量大"只体现在攻城:日常没有人人有份的参与结构,普通成员对行会缺少归属感与参与点。科技树把…
设计初衷 打怪掉装、强化失败、版本更替,都在往玩家背包里塞过渡装备,卖不掉、扔了心疼,压在包里发臭。回收系统的价值两条:给过…
底层原理 性能优化不靠猜,靠剖析。os.clock 返回脚本进程占用的 CPU 时间(秒,小数),两次取值之差就是中间代码的…
设计初衷 满级是长线游戏的分水岭:不转生,毕业玩家无事可做、数值通胀无处吸收;硬开新等级,老装备一夜贬值。转生系统的价值在于…
业务场景 石墓阵里 6 个精英点位驻着白野猪王,被清掉后要按周期补位。散装写法把地图、坐标、怪物名硬编码在脚本里,开新区要复…
底层原理 闭包是函数与其捕获环境的绑定:内层函数引用外层局部变量时,这份数据随函数体一起存活,外部既访问不到也改不掉。限频器…