伤害公式的每一步除法都会产生小数:取整的方向(向下、四舍五入)决定 1000 次攻击后玩家实际多打或少打多少血。取整的取舍不是代码风格问题,是数值精度的问题——漂移的累计能改写平衡表。
---伤害公式的三处取整点
function Damage.calc(atk, def, multiplier)
-- 第一处:防御减免的取整,向下保护攻击方
local reduced = math.floor(atk * (1 - def / (def + 500)))
-- 第二处:倍率加成,四舍五入保持期望
local boosted = math.floor(reduced * multiplier + 0.5)
-- 第三处:随机浮动,向下取保底
local final = math.max(1, math.floor(boosted *
(0.9 + math.random() * 0.2)))
return final
end
三处取整点各有立场:防御减免向下取整保护攻击方的期望、倍率加成四舍五入维持设计的中值、随机浮动向下取整保证最低伤害的口径。三个方向不统一的后果是漂移:全部向下取整的公式让玩家的实际输出比设计值低 3% 到 5%,万分比的差距在排行榜上是一个身位。漂移的度量用期望对比:公式的理论期望与十万次模拟的实测均值比对,偏差超 1% 即取整方向的策略需要复核。
---百分比的整数化:万分比避免浮点
function Damage.pct(base, permille)
-- 万分比整数乘除,全程无浮点
return math.floor(base * permille / 10000)
end
---累计加成的守恒:分步取整改为末次取整
-- 危险:每一步取整,误差逐步累计
-- local a = math.floor(base * 1.1)
-- local b = math.floor(a * 1.2)
-- 改造:末次统一取整
local function calcFinal(base)
return math.floor(base * 1.1 * 1.2)
end
精度的守恒两条纪律:百分比全程用万分比整数运算(浮点的 0.1 加 0.2 不等于 0.3 在伤害里是实打实的血量);分步取整改末次取整——每步 floor 一次的累计向下偏差在多段加成的公式里放大明显,中间保留小数、只在最终结算时取整,数值的期望与设计对齐。浮动区间的下限保护:伤害的保底 1 点让防御方的极端堆叠不至于百分百免疫,取整与保底共同定义伤害的下边界。期望的验证进数值的验收流程:每个版本的伤害公式跑十万次模拟,期望值与设计值的对齐是版本上线前的必答题。
伤害期望的模拟测试进每日构建,期望漂移超 1% 即阻断发布;玩家实测与设计期望的偏差监控,论坛的数据帖是免费的验证集群。
全部向下取整曾经让烈火剑法的实际伤害比面板低 4%,论坛的算术帖炸版,取整方向按立场分置后修复。浮点的累加曾经用于连击的加成,0.1 的精度噪声让万次连击统计偏差可观测,万分比整数化替换。保底曾经设 0,极端防御的互殴打出零伤死循环,保底 1 点终结。
取整的策略写进数值文档:每处取整的方向与理由,公式的维护者读得懂前辈的立场。模拟测试的种子固定,漂移的对比有可复现的基准。数值的调整走热更时同步跑一次模拟,调整的副作用当场可见。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
学员常见误区 Lua函数可返回多个值,学员用固定变量数接收时如果变量少于返回值,多余返回值被静默丢弃;如果变量多于返回值,多…
设计初衷 行会建筑的死穴是一次全解锁:会员没有逐步建设的过程感。梯度设计让每栋建筑都有前置条件和资源门槛。 数值模型 建筑分…
设计初衷 婚姻系统的属性加成是社交玩法的经济锚点:加成太弱没人结婚,太强则"为了属性被迫结婚"扭曲了社交本质。婚姻边界的设计…
设计初衷 宝箱类玩法的信任危机都源于同一句话:"概率是不是骗人的。"期望公示把概率从事后争议变成事前契约:奖池概率表全量公示…
设计初衷 流拍物(拍卖未成交的退回物品)堆积在卖家背包里成为死资产:低价值物流拍后无人问津,高价值物流拍后卖家不愿降价重拍。…
业务场景 沙巴克战功榜每周结算,玩家提交战功前不知道"再打多少能进前 10、前 10 的奖励是什么"。名次预览:输入自己的战…