主题
表达式求值错误定位
版本要求: HNAttribute 2.4.0+
概述
从 2.4.0 版本开始,当表达式求值失败时,会输出详细的错误信息,帮助你快速定位问题所在的配置文件和位置。
错误信息格式
[WARN] 表达式求值失败 [节点ID] mode=表达式模式, script=表达式内容, error=错误原因示例错误信息
[WARN] 表达式求值失败 [combat.stages[4].combo.formula] mode=EXPRESSION, script=damage * (1 + combo_bonus / 200), error=Unknown variable: combo_bonus错误信息解读
节点 ID
- 格式:
combat.stages[索引].阶段ID.字段名 - 例如:
combat.stages[4].combo.formula表示第 4 个战斗阶段的 combo 效果的 formula 字段 - 可以根据索引和阶段 ID 快速定位到具体的配置文件
表达式模式
EXPRESSION: 简单表达式模式(支持数学运算、函数调用)GROOVY: Groovy 脚本模式(支持完整的 Groovy 语法)
表达式内容
- 显示实际的表达式字符串
- 可以直接看到是哪个表达式出了问题
错误原因
- 显示具体的错误信息
- 常见错误:
Unknown variable: xxx- 变量未定义Syntax error- 语法错误Division by zero- 除零错误Type mismatch- 类型不匹配
常见问题排查
问题 1:变量未定义
错误信息:
[WARN] 表达式求值失败 [combat.stages[4].damage_bonus.formula] mode=EXPRESSION, script=damage * (1 + damage_amplify / 250), error=Unknown variable: damage_amplify原因: 表达式中使用了 damage_amplify 变量,但该属性未在 attributes/combat.yml 中定义。
解决方案: 在 attributes/combat.yml 中添加该属性定义:
yaml
damage_amplify:
display: "&c增伤率"
names:
- "增伤率"
- "伤害增幅"
read-pattern: default
default: 0.0
min: 0.0
max: 300.0问题 2:语法错误
错误信息:
[WARN] 表达式求值失败 [combat.stages[2].hit.formula] mode=EXPRESSION, script=accuracy - victim_dodge), error=Syntax error: unexpected token ')'原因: 表达式中括号不匹配,多了一个右括号。
解决方案: 修正表达式:
yaml
formula: "accuracy - victim_dodge"问题 3:除零错误
错误信息:
[WARN] 表达式求值失败 [combat.stages[5].reduction.formula] mode=EXPRESSION, script=damage / defense, error=Division by zero原因: 当 defense 为 0 时会触发除零错误。
解决方案: 使用 max() 函数避免除零:
yaml
formula: "damage / max(1, defense)"问题 4:类型不匹配
错误信息:
[WARN] 表达式求值失败 [combat.stages[3].condition] mode=EXPRESSION, script=attacker.player, error=Type mismatch: expected number, got boolean原因: 条件表达式应该返回数值(> 0 为真),但返回了布尔值。
解决方案: 使用三元运算符或 IF 函数:
yaml
condition: "attacker_player > 0 ? 1 : 0"
# 或
condition: "IF(attacker_player > 0, 1, 0)"定位配置文件
根据节点 ID 定位配置文件:
战斗管线 stage
- 节点 ID:通常是
pipeline.validate.<stageId>或pipeline.stage.<stageId> - 配置文件:
pipelines/<stageId>.yml
示例:
- 错误:
pipeline.validate.damage - 可能的文件:
pipelines/damage.yml
属性定义
- 节点 ID:
attributes.<属性ID>.字段名 - 配置文件:
attributes/<分类>.yml
示例:
- 错误:
attributes.damage_amplify.formula - 可能的文件:
attributes/combat.yml
Buff 定义
- 节点 ID:
buffs.<buff_key>.字段名 - 配置文件:
buffs/<分类>.yml
示例:
- 错误:
buffs.speed_boost.condition - 可能的文件:
buffs/default.yml
周期效果定义
- 节点 ID:
periodic.<effect_key>.字段名 - 配置文件:
periodic/<分类>.yml
示例:
- 错误:
periodic.bleed.tick_condition - 可能的文件:
periodic/dot-demo.yml
调试技巧
1. 使用简单表达式测试
先用简单的常量测试,确认配置格式正确:
yaml
formula: "100" # 先用常量测试2. 逐步添加变量
一次添加一个变量,确认每个变量都可用:
yaml
formula: "damage" # 先测试 damage
formula: "damage * 2" # 再测试运算
formula: "damage * (1 + damage_amplify / 100)" # 最后添加复杂逻辑3. 检查变量名
确保变量名与属性 ID 完全一致(区分大小写、下划线):
- ✅
damage_amplify - ❌
damageAmplify - ❌
damage-amplify
4. 使用 max/min 函数防御性编程
避免除零、负数等异常情况:
yaml
formula: "damage / max(1, defense)" # 防止除零
formula: "max(0, damage - reduction)" # 防止负数5. 查看完整日志
在服务器启动时查看完整的配置加载日志,可能会有更多提示信息。
