沙巴克战功榜每周结算,玩家提交战功前不知道“再打多少能进前 10、前 10 的奖励是什么”。名次预览:输入自己的战功,实时返回预计名次与对应奖励档位——预期透明化让玩家自己决定“冲一把还是躺平”,结算投诉随之下降。
名次计算与奖励映射:排序定位名次,按档位映射奖励。示例代码如下:
local REWARDS = { { min = 1, gold = 5 }, { min = 10, gold = 2 }, { min = 50, gold = 1 } }
local function previewRank(actor, myPts)
actor = getplayvar(actor, "HUMAN", "x") and actor or actor
local board = tostring(getsysvar("WarPtsBoard") or "")
local higher = 0
for e in string.gmatch(board, "[^|]+") do
local pts = tonumber(string.match(e, ":(%d+)$") or "0")
if pts > myPts then
higher = higher + 1
end
end
local rank = higher + 1
local reward = 0
for _, r in ipairs(REWARDS) do
if rank <= r.min then
reward = r.gold
break
end
end
sendmsg(actor, 1, "当前战功预计第 " .. rank .. " 名,奖励 " .. reward .. " 根金条。")
return rank, reward
end
奖励档位查询:单独的档位映射函数,预览与结算共用同一张表。示例代码如下:
local function rewardOf(rank)
for _, r in ipairs(REWARDS) do
if rank <= r.min then
return r.gold
end
end
return 0
end
WarPtsBoard 全局变量存“名字:战功”竖线分隔的榜单快照,预览只读快照不打扰结算。string.match(e, ":(%d+)$") 锚定行尾取数字,防名字里的数字干扰。REWARDS 档位表按 min 升序排列,rewardOf 与 previewRank 共用——预览与结算的口径单点化,避免“预览说 5 根、结算发 2 根”的口径分裂。
名次预览踩过三个坑:一是预览读实时榜而结算读一小时前的快照,两个口径差出十几名,预览与结算必须同源(都用快照);二是档位表无序存放,前 10 名的档位排在第 50 名档位后面,先匹配先得的逻辑把高奖发给了低名次,档位表必须按 min 升序初始化;三是并列战功的先后没定义,两个第 9 名都以为自己是第 9,并列时按达成时间先者优先并公示规则。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
设计初衷 生存向属性的堆法单一:全堆血防就能站桩——挨打没有反馈,进攻方也没有取舍。反伤与荆棘设计:引入"被打反伤"机制并配…
设计初衷 活动做过就下架:老玩家念着当年的中秋灯会,新玩家永远错过——内容资产利用率极低,新玩法的开发压力却全压在增量上。活…
底层原理 一条业务请求(聊天、交易、入队)前面总挂着同样的横切逻辑:鉴权、限频、日志——每个入口各写一遍必然重复。中间件模式…
底层原理 求区间和(第 3 到 17 名的战力总和):前缀和预处理后查询 O(1),但单点更新要 O(n) 重算整张前缀表;…
设计初衷 玩家的江湖故事散落在各系统的角落:成就页有里程碑、战绩页有击杀、名人堂有荣誉——拼不出一个完整的"人"。玩家传记设…
业务场景 玩家跑商只能身上背货:负重有限、路线自己跑、货物分站下不去。马车货运封装:驿站雇马车按固定线路多点卸货,载重按马车…