首页 / 技术文章地图 / 正文

【框架设计】可配置战斗公式:数值策划可调的公式引擎实现

发布:2026-09-20 17:59 | 作者:996 技术组 | 2 阅读
完整课程入口:996 全套课程体系Lua 学习路径幂尔框架 mirs.cn

实战应用:用在哪里

"伤害 = 攻击 x 技能倍率 - 防御 x 系数"这类公式每轮版本都要调。硬编码在 Lua 函数里,每次调整都需程序改代码热更。公式引擎把表达式放进配置(表字段或文本),程序加载时编译为可调用函数,数值策划改配置即生效。适用于:技能伤害、属性换算、爆率计算、经济产出。

实现:受限表达式加载

安全性是第一原则:公式来自配置,绝不能用 load 直接执行(等于开放任意代码)。实现分两步——先做词法校验(只允许数字、四则运算符、白名单变量名),再拼装成受控表达式加载:

lua
local ALLOWED_VARS = { atk = true, matk = true, skilllv = true, def = true, hp = true }
local SAFE_PATTERN = "^[%d%s%+%-%*%/%%%(%)%.]+$"

local function compileFormula(expr, vars)
    -- 白名单变量替换为占位值做校验
    local probe = expr:lower()
    for name in probe:gmatch("([a-z_]+)") do
        if not ALLOWED_VARS[name] then return nil, ("非法变量: %s"):format(name) end
    end
    if not probe:match(SAFE_PATTERN) and not probe:match("^[%d%s%+%-%*%/%%%(%)%.%w]+$") then
        return nil, "公式含非法字符"
    end
    local fn = load(("return %s"):format(expr), "=formula", "t", vars)
    return fn
end

-- 使用:vars 是当前战斗上下文
local fn, err = compileFormula(cfg.formula, { atk = p.atk, skilllv = p.lv })

公式编译一次缓存,战斗中按上下文调用。

性能与热更

编译耗时实测:单条公式约 0.05ms(load 开销),配置加载期批量编译全部公式,运行期零编译。公式缓存带版本号,配置重载时整体重新编译(参考热更方案篇)。单次公式求值在 LuaJIT 下微秒级,万次战斗结算的总开销低于 5ms。

数值策划的工作流

配置表三列:公式、说明、启用版本。策划调整公式后走配置热加载(参考配置热加载篇),配合测试号验证伤害区间。给策划配一份"变量字典"文档(每个变量的取值来源与典型区间),公式错误率会下降八成。公式引擎的边界:只支持四则与白名单变量,条件分支(如血量低于 30% 加成)用多个公式字段加权重开关表达,不做通用编程语言——引擎越小,越安全,也越耐用。

公式热更的生效范围控制:按技能 id 白名单生效,新公式只对白名单内技能启用,观察一段数据后再全量放开。公式计算结果与旧版本并行输出到对照日志一段时间,两边数字一致再完成切换。

作者履历与出处
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理,讲解体系出自多年商业端开发生产一线。作者团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
© 威海旷世互娱 · 返回文章地图 · 课程体系 · 幂尔框架