CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
Lua实战二叉堆排行榜伤害

【Lua实战】二叉堆:伤害排行榜的有序插入

2026-09-23 10:18 作者:996 技术组 0 阅读 996引擎Lua教程传奇脚本Lua实战二叉堆排行榜伤害

实战应用:用在哪里

世界首领战里玩家最关心的是伤害前十名:榜单要求随时插入、随时能按序取出,每来一条伤害记录都重新排序一次太浪费。二叉堆只保证堆顶有序,插入与替换的开销都是对数级,配合固定容量的"只留前十"策略,千人格斗也能稳定刷新榜单。本文给出服务端 Lua 的堆实现,以及首领战伤害榜的接入写法。

堆本体:上浮与下沉两个动作

小顶堆配合容量上限是取前十的常用做法:堆里最多留十条,新纪录比堆顶还小就直接丢弃,否则替换堆顶后下沉。核心只有上浮、下沉两个函数,代码如下:

lua
-- 小顶堆:容量固定,只保留最大的十条记录
local heap = {n = 0}
local function siftUp(h, i)
    while i > 1 do
        local p = math.floor(i / 2)
        if h[p].dmg <= h[i].dmg then break end
        h[p], h[i] = h[i], h[p]
        i = p
    end
end
local function siftDown(h, i)
    while i * 2 <= h.n do
        local c = i * 2
        if c + 1 <= h.n and h[c + 1].dmg < h[c].dmg then c = c + 1 end
        if h[i].dmg <= h[c].dmg then break end
        h[i], h[c] = h[c], h[i]
        i = c
    end
end

接入首领战:记录伤害并广播榜单

首领受到攻击时把伤害累加到攻击者名下,再走一次"进堆或丢弃"的判定;广播用定时器按周期拉取堆内数据,排序后一次性发出,不需要每刀都推送。示例代码如下:

lua
-- 伤害入堆:超过容量先和堆顶比较
local function pushDamage(name, dmg)
    local item = {name = name, dmg = dmg}
    if heap.n < 10 then
        heap.n = heap.n + 1
        heap[heap.n] = item
        siftUp(heap, heap.n)
    elseif dmg > heap[1].dmg then
        heap[1] = item
        siftDown(heap, 1)
    end
end
-- QF触发: killmon 首领倒下后广播榜单
local player = class(actor)
local snap = {}
for i = 1, heap.n do snap[i] = heap[i] end
table.sort(snap, function(a, b) return a.dmg > b.dmg end)
local lines = {}
for i = 1, #snap do
    lines[#lines + 1] = snap[i].name .. ":" .. snap[i].dmg
end
sendmsg(player, 1, 0, table.concat(lines, " "))

验证与监控

先写十组随机数据做单元对照:与 table.sort 的结果逐一比对名次,容量边界各跑一遍,第十一条、第十二条数据进来时确认堆容量恒为十。线上监控首领战期间的内存曲线与榜单刷新耗时,若刷新耗时随人数增长明显,通常是伤害累加表没有按首领分桶,全服记录写进了同一张表。

踩坑记录

有次榜单把已离队玩家的旧纪录也显示出来,追查发现伤害累加表按名字做键,玩家改名将导致同一人占两条纪录。改为进本时记录角色编号,榜单展示时再取当前名字,改名不再影响名次。另一处是堆比较函数里写了取反逻辑,小顶堆被写成了大顶堆,前十名变成了前十名开外,上线前的对照测试把这类问题挡在了测试环境,代价只是一次冒烟。

堆结构在整场战斗内复用,首领重置时只清计数不清结构,避免反复建表带来的内存抖动;多首领并行时按首领编号各建一份,禁止共用,防止榜单串场。

作者履历与出处

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

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

最新技术文章 · 实战干货

LATEST ARTICLES

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

Lua实战选择排序装备评分排行榜

【Lua实战】选择排序:装备评分榜的局部有序

实战应用:用在哪里 装备回收商 NPC 每天按评分收购玩家的装备,裁决之杖、骨玉权杖按攻击、持久加权打分,榜上只要前五名。数…

2026-09-23 10:57 996 技术组 · 0 阅读
玩法策划沙巴克攻城皇宫归属

【玩法策划】沙巴克攻城:城门耐久与皇宫归属的规则设计

实战应用:用在哪里 沙巴克攻城是全服行会战的最高舞台:攻方砸开城门、抢占皇宫,守方依托城墙与复活点反打。规则设计的关键是节奏…

2026-09-23 10:57 996 技术组 · 0 阅读
玩法策划影分身分身真身识别

【玩法策划】影分身:分身嘲讽与真身识别的玩法设计

实战应用:用在哪里 影分身玩法给法师职业补上生存短板:危急时刻召唤四个影分身分担仇恨,敌人需要在六格范围内分辨真身,猜错就浪…

2026-09-23 10:57 996 技术组 · 0 阅读
网络通信消息重试退避信令

【网络通信】消息重试:关键信令的确认与退避重发

实战应用:用在哪里 组队邀请、行会宣战这类关键信令丢了没有兜底,玩家只能反复手点,高峰期体验很差。重试机制给信令加确认回执:…

2026-09-23 10:57 996 技术组 · 0 阅读
运维发布开区队列预热

【运维发布】滚动开区:分批开服的队列与预热流程

实战应用:用在哪里 新资料片上线首日预约量常是日常十倍,一口气全开会让数据库与登录网关同时过载。滚动开区把开区动作排成队列:…

2026-09-23 10:57 996 技术组 · 0 阅读
性能调优广播节流合帧

【性能调优】广播节流:跑动动作的合帧下发

实战应用:用在哪里 百人同屏的沙巴克外围战场,每个玩家每秒跑动会触发数次位置更新,全部即时下发时广播量随人数平方增长,网关先…

2026-09-23 10:57 996 技术组 · 0 阅读