寄售行一笔 0.1 金币手续费的单据让账目差了 1:货币字段里混进了小数,累计 3000 笔后对账差出 300 金币,财务对不上账。根因是货币运算没有纪律:有人用浮点算折扣、有人除法除出小数直接落库。货币运算规范封装:一切货币值整数化、除法向下取整、余数归属明确,三类纪律写进公共函数,全服货币路径统一走这一套。
三类公共货币函数:加权扣费、比例分成、安全累加。示例代码如下:
local function chargeFee(amount, feeRate)
amount = math.floor(tonumber(amount) or 0)
local fee = math.floor(amount * feeRate / 10000)
return amount - fee, fee
end
local function splitLoot(total, n)
total = math.floor(tonumber(total) or 0)
n = math.max(math.floor(n) or 1, 1)
local each = math.floor(total / n)
local left = total - each * n
return each, left
end
local function addGold(actorName, delta)
local actor = getplayerbyname(actorName)
delta = math.floor(tonumber(delta) or 0)
local gold = math.floor(tonumber(getplayvar(actor, "HUMAN", "Gold")) or 0)
local nv = math.max(gold + delta, 0)
setplayvar(actor, "HUMAN", "Gold", nv, 1)
return nv
end
手续费五菱分之一的费率走万分比整数:示例代码如下:
local left, fee = chargeFee(300001, 500)
300001 金币按 5% 费率(万分之 500)收 15000 手续费,落库值与手续费都是整数,对账分毫不差。
chargeFee 的费率用万分比整数(500 即 5%),乘法后 math.floor 向下取整,手续费永远不超出应收。splitLoot 把不能整除的余数显式返回,余数给队长或入公会池,规则由调用方定但余数绝不悄悄消失。addGold 读改写全程 math.floor,任何上游传进来的小数在入口被压平,落库值恒为整数。
货币运算踩过三个坑:一是折扣用 0.85 这类浮点系数连乘 30 次,5000 万金币的总额差出 2 金币,全链路改万分比整数乘加 floor 后归零;二是均分 301 金币给 4 人时各 75 元余 1 元,余数被四舍五入凭空蒸发,累计成对账缺口,余数必须显式入账;三是 Gold 变量被活动脚本写成 "50000" 字符串形态,下次 addGold 里 tonumber 兜住没报错但另一处直接算术的代码炸了——货币读写的公共函数是唯一入口,旁路访问一律在评审时拦下。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
设计初衷 帮会活动只有攻城与聚餐两板斧:非攻城日帮会频道冷清,成员缺乏共同目标。帮会试炼场设计:帮会自有试炼场(限时挑战波次…
设计初衷 帮会资金靠少数大佬捐献:金主一走帮会资金断崖,普通成员没有参与感也不会珍惜帮会资源。帮会会费设计:成员按职位每周缴…
设计初衷 帮会扩张靠熟人拉人:增长有天花板、新人质量参差、老人不愿带新。募兵编制设计:帮会发布募兵任务包(新人完成入帮任务即…
底层原理 协程体内出错时 resume 返回 ok=false 与错误对象,但协程体若死循环则 resume 永久挂起——错…
底层原理 coroutine.resume 的实参会在协程内成为首个 yield 的返回值;coroutine.yield …
业务场景 挂摊卖药每小时断货:玩家下线前上满货,两小时后摊位空转。摊位自动补货封装:上摊时设定补货仓库(背包或帮会仓),定时…