CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
进阶实战游戏功能996引擎

Lua+元方法__lt:排序比较的自定义本质

2026-09-29 18:02 作者:996 技术组 996引擎Lua教程传奇脚本进阶实战游戏功能996引擎

【语法算法】

元方法 __lt 的触发就这一行:

lua
setmetatable(t, { __lt = function(a, b) return a.score < b.score end })

两个表做 < 比较时——Lua 调用 __lt——排序比较的全部机制就这一行。可这一行的前后各有一个细节:前面是"两个操作数必须类型相同",后面是"table.sort 内部会反复调用"。今天拆开。

一、触发、排序、反复三段

__lt 的三段。触发:两个表做 < 比较时——Lua 查左操作数的元表有没有 __lt——没有再查右操作数的——查到了就调用并返回布尔值。排序:table.sort(t) 内部反复调用 < 比较相邻元素——如果表中的元素是带 __lt 的表,排序就按自定义规则走——排序的稳定性取决于比较函数是否严格弱序。反复:table.sort 的比较次数是 O(n log n)——__lt 会被反复调用——每次调用都要分配栈帧——__lt 函数里不要做复杂操作。三段连起来:__lt 玩的是"把排序规则从内置类型扩展到自定义类型"——表的排序从此可以按任何自定义规则进行。

mermaid
graph TD
    A["table.sort(t)"] --> B["比较 t[i] < t[j]"]
    B --> C{"t[i]有__lt?"}
    C -->|是| D["调用__lt(t[i], t[j])"]
    D --> E["返回true: 交换"]
    D --> F["返回false: 不交换"]
    C -->|否| G["报错: attempt to compare"]

二、排序的正确写法

lua
local Skill = {}
Skill.__index = Skill

function Skill.new(name, cd, priority)
    return setmetatable({ name = name, cd = cd, priority = priority }, Skill)
end

Skill.__lt = function(a, b)
    return a.priority < b.priority
end

local skills = {
    Skill.new("火球", 3, 2),
    Skill.new("冰箭", 2, 1),
    Skill.new("雷电", 5, 3),
}

table.sort(skills)

for _, s in ipairs(skills) do
    print(s.name, s.priority)
end
-- 冰箭 1
-- 火球 2
-- 雷电 3

table.sort(skills) 自动走 __lt——排序结果按 priority 升序——不需要传比较函数——排序规则封装在元方法里。

三、严格弱序与比较的纪律

严格弱序是排序的数学要求:如果 a < b 且 b < c,则 a < c——不满足严格弱序的比较函数会导致 table.sort 报错 "invalid order function"——这是排序最常见的坑。避免的方法是比较函数只看一个字段——如果需要多字段排序,先按第一字段比较,相等再按第二字段——不要在比较函数里做复杂的逻辑判断。最后一条纪律:__lt 只处理 < 操作——> 和 >= 会自动用 < 取反——但 == 走的是 __eq 不是 __lt——三个比较元方法各管各的,不能混用。

作者履历与出处

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

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

幂尔框架 · 实战干货 · 接口调用

LATEST ARTICLES

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

进阶实战游戏功能

吞劲奇纹:喂它五拳,它自己噎住

【游戏功能】 上一版藏了条只在长战斗里露头的隐蔽报错:吞劲的计数器跨场不清零——第一场怪喂满了五拳把它噎住,第二场新怪刚出手…

2026-10-01 21:23 996 技术组
进阶实战游戏功能

蚀本血纹:一刀削它两分命,血条越打越短

【游戏功能】 再抛一个坑:血条的长短是天生的吗?一只怪的命根子一千点,打完就满,下回见面还是一千点——命根是它自己的,跟你的…

2026-10-01 21:23 996 技术组
进阶实战游戏功能

顺劈余纹:杀过头的刀,落到下一只头上

【游戏功能】 var over=d-before ——先拆这一行。刀额减去落刀前的血,多出来的那一截就是杀过头的余劲。顺劈纹…

2026-10-01 21:23 996 技术组
进阶实战游戏功能

血注豪纹:押上二十滴血,八秒内定输赢

【游戏功能】 上一轮的线上事故出得难看:有玩家押了二十滴血没在限期内斩掉怪,注被纹收走了,直接在频道里喊"强买强卖"。复盘下…

2026-10-01 21:23 996 技术组
进阶实战游戏功能

偷时快纹:它的刀慢半拍,你的刀快一倍

【游戏功能】 上一版留了个查了半天的隐蔽报错:战斗统计里玩家的出招间隔写着一秒四,实际手感却是一秒整——两套计时账对不上,运…

2026-10-01 21:23 996 技术组
进阶实战游戏功能

存刀神纹:最强一刀存起来,八秒后再砍一遍

【游戏功能】 先抛一个坑:你砍出去的最强一刀,去哪了?暴击三千的天胡刀,数字蹦完就散,下一刀又是从零起算——最强的那一击在战…

2026-10-01 21:23 996 技术组