996引擎 - 【任务系统】和【cfg_newtask.xls】

发布时间:2026/10/31 6:41:05
996引擎 - 【任务系统】和【cfg_newtask.xls】

996引擎 - 【任务系统】和【cfg_newtask.xls】

  • 总结
  • 测试NPC界面
  • cfg_newtask.xls 表
  • 坑1:【新建任务接口】 对应 【接取任务触发】
  • 坑2:增加系统任务计时 `dsfuncall` 除了角色对象,不支持任何其他参数
    • 抢救一下
  • 坑3: 修改 cfg_newtask.xls 必须重启引擎才能生效
  • 参考资料

总结

  1. 996这个任务系统是一个仅用于控制主界面左上角的【任务列表】UI刷新,交互状态通知,不含具体业务逻辑。,不持久化任何数据
  2. 任务列表有多个任务时支持上下滑动,可以调用接口将指定任务【置顶】
  3. 任务列表中,每个任务一行,分标题和(当前状态对应的)内容两部分,点击能触发clicknewtask事件
  4. 具体的任务系统业务逻辑,需要自己写代码实现。(配合996提供的任务接口和触发,实现更新任务列表)

任务系统提供的接口,仅为会话内任务UI与轻量状态控制工具,不涉及任何自动持久化机制。
真实任务进度、完成状态、条件判断等,必须通过开发者在触发器或接口调用中,显式读写引擎变量,才能实现跨会话持续存在。
cfg_newtask.xls 是配置源头,actor 是运行时载体,引擎变量是持久化桥梁——三者缺一不可。

测试NPC界面

对应【任务系统】的 5 个接口,每行对应一个任务。

localnpc={}npc.title="任务系统";npc.paramsAndFuncs={};fori=1,18dotable.insert(npc.paramsAndFuncs,{"领取任务"..i,function(player)newpicktask(player,i,"领取参数A");end});table.insert(npc.paramsAndFuncs,{"刷新任务"..i,function(player)newchangetask(player,i,"刷新参数A","刷新参数B");end});table.insert(npc.paramsAndFuncs,{"完成任务"..i,function(player)newcompletetask(player,i);end});table.insert(npc.paramsAndFuncs,{"删除任务"..i,function(player)newdeletetask(player,i);end});table.insert(npc.paramsAndFuncs,{"任务置顶"..i,function(player)tasktopshow(player,i);end});endreturnnpc;

cfg_newtask.xls 表

为了测试简单填了下。

  1. 支持富文本。支持<u>、<br>
  2. 支持给(接取任务前、任务进行中、完成任务时)分别置不同的特效。
  3. 支持设置排序字段

坑1:【新建任务接口】 对应 【接取任务触发】

也不知什么脑回路能想出这种命名风格。
调用新建任务接口newpicktask,服务端触发接取任务触发picktask,任务列表中当前内容显示newtask表的接取任务前内容。

其他的接口和触发都还好见名知意。

坑2:增加系统任务计时dsfuncall除了角色对象,不支持任何其他参数

--QFunction-0.luafunctiondingshicf_1(actor)enddsfuncall(actor,"dingshicf_1",10*1000,1,1)

直接放弃,996所有的定时、延迟类的接口,都坑的一B。

抢救一下

如果一定想用系统任务计时要又不想声明 dingshicf_1,dingshicf_2,dingshicf_3… 一堆回调
可以考虑封装一下 dsfuncall 搞个支持直接传回调函数的版本。

--QFunction-0.lua--- 系统任务计时扩展版 (支持匿名函数)--- @param actor object 玩家对象--- @param func function 回调函数 (匿名函数或局部函数)--- @param time number 倒计时时间 (毫秒) 默认1000--- @param model number|nil 0=上线需重新开启, 1=上线直接执行 (默认0)--- @param isClear number|nil 0=开启新的, 1=上线刷新当前时间 (默认0)functiondsfuncallEx(actor,func,time,model,isClear)iftype(func)~="function"thenrelease_print("[Error] dsfuncallEx: func must be a function!")returnendtime=timeor1000-- 生成唯一的全局调度函数名-- 使用 os.clock() 配合随机数,防止在同一毫秒内生成重复 KeylocaldispatcherName=string.format("dingshicf_EX_%d_%d",gettcount64(),math.random(1000,9999))-- 注册到全局 _G_G[dispatcherName]=function()-- 使用 pcall 保护,确保即使业务代码报错,也能清理掉全局变量localok,err=pcall(func,actor)ifnotokthenrelease_print("[Timer Error] "..tostring(err))end-- 执行完毕后立即销毁,释放内存_G[dispatcherName]=nilend-- 调用 64_23.10.24 引擎原生接口dsfuncall(actor,dispatcherName,time,modelor0,isClearor0)end

可以直接传匿名方法,匿名方法中可以访问闭包上下文的变量。坑爹的限制解除啦

locala=1;localb=2;-- 比如玩家触发某个机关,3秒后检查状态dsfuncallEx(actor,function(p)release_print("系统任务计时完成,访问闭包变量: a = "..a.." b = "..b)end,3000)

坑3: 修改 cfg_newtask.xls 必须重启引擎才能生效

修改cfg_newtask.xls表后,必须关闭 M2 并重启引擎才能生效

参考资料

996引擎 - 任务系统