CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
高级技巧996引擎命令模式撤销重做

【高级技巧】命令模式:操作的封装与撤销重做封装

2026-09-25 05:44 作者:996 技术组 0 阅读 996引擎Lua教程传奇脚本高级技巧996引擎Lua命令模式撤销重做

底层原理

聊天指令、GM 操作、交易确认这类动作如果散落成各个独立函数,撤销上一步、重做、操作历史就无从实现。命令模式把每个操作封装成带 execute 与 undo 两个方法的对象:执行时压入历史栈,撤销时弹栈调用 undo,重做则是把撤销掉的命令再次压回执行——操作的历史天然成为可回放、可撤销、可审计的命令栈。F:\底层文件 的闭包与表结构确认:命令对象用闭包捕获执行上下文,undo 用反向闭包恢复状态,两枚闭包即一个完整的可逆命令。

高级封装

命令栈与撤销重做:execute、undo、redo 三栈协同。示例代码如下:

lua
local history = { undoStack = {}, redoStack = {} }
local function runCommand(cmd)
    cmd.execute()
    history.undoStack[#history.undoStack + 1] = cmd
    history.redoStack = {}
end
local function undo()
    local cmd = table.remove(history.undoStack)
    if cmd == nil then
        return false
    end
    cmd.undo()
    history.redoStack[#history.redoStack + 1] = cmd
    return true
end
local function redo()
    local cmd = table.remove(history.redoStack)
    if cmd == nil then
        return false
    end
    cmd.execute()
    history.undoStack[#history.undoStack + 1] = cmd
    return true
end

发奖命令的可撤销封装示例代码如下:

lua
runCommand({
    desc = "发奖 裁决之杖 给 甲",
    execute = function()
        giveitem(getplayerbyname("甲"), "裁决之杖", 1, 0, "补偿")
    end,
    undo = function()
        takeitem(getplayerbyname("甲"), "裁决之杖", 1, 0, "撤销补偿")
    end,
})

性能对比

GM 连续执行 50 步操作后误操作 1 步:无命令模式时要靠数据备份回滚(全量恢复耗时且影响他人),命令栈 undo 精确回退误操作的 1 步耗时 0.02 毫秒,其余 49 步完好。命令对象的内存代价:每命令约 200 字节,千步历史约 200KB,历史栈按容量 500 截断。

适用边界

三个不适用场景:一是操作不可逆(跨服数据已发出、外部接口已调用),undo 无法真的撤销外部副作用,命令模式只适合可逆的内部状态变更;二是操作间有强时序依赖(B 的前提是 A 的结果),撤销中间一条会让后续命令的前提失效,需要级联撤销设计;三是高频率执行的重操作(每帧调用的战斗结算),命令对象的构造与历史栈的增长会成为负担,历史留痕用轻量日志替代。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

最新技术文章 · 实战干货

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →

进阶实战996引擎

【进阶实战】Lua连续签到:沙巴克组队签到的断签归零

一、线上事故:连续签到奖励按天数递增,有玩家改本机时间刷出 90 天连签,领 3 倍顶格奖励 30 份;连续天数要靠服务器侧…

2026-09-26 13:15 996 技术组 · 0 阅读
策划架构996引擎

【策划架构】Lua随机命名:祖玛教主精英怪的音节拼接器

一、抛坑提问:精英怪要 200 个不重样的霸气名字,运营手写到手软——把名字拆成首、中、尾三段池,随机各取一段拼接,组合空间…

2026-09-26 13:15 996 技术组 · 0 阅读
策划架构996引擎

【策划架构】Lua日志分级:裁决之杖仓库操作的级别过滤

一、一行代码拆解:if LV[level] = TH then write end —— 日志分级的全部逻辑:每条日志带级别…

2026-09-26 13:15 996 技术组 · 0 阅读
入门夯实996引擎

【入门夯实】Lua浮点相等:裁决之杖折扣价的容差比较

一、一行代码拆解:math.abs(a - b) < 1e-6 —— 浮点数不能直接比相等:二进制表示有尾差,判等要用"差的…

2026-09-26 13:15 996 技术组 · 0 阅读
高级技巧996引擎

【高级技巧】Lua并查集:祖玛教主师徒关系的同门判定

一、隐蔽陷阱:判定两名玩家是否同门顺着师徒链逐层上爬,链长时线性还可能环回;并查集把同门合并成集合,查两根是否相同一次到位。…

2026-09-26 13:15 996 技术组 · 0 阅读
进阶实战996引擎

【进阶实战】Lua差分数组:沙巴克防线区间加成的批量标记

一、线上事故:给 3 到 97 段城墙统一加防御 buff,逐段循环加 95 次,多段叠加时 3 万次写入卡顿 200 毫秒…

2026-09-26 13:15 996 技术组 · 0 阅读