简体中文
属性定义
属性定义文件要写清的内容如下: 一个属性有哪些字段, 每个字段起什么作用, 数值类型有哪几种, 以及属性 ID 和数值范围怎么设计
属性文件放在 attributes/*.yml, 一个属性一个文件. 你写的这份定义决定一个数值怎么被识别, 怎么限制, 怎么展示, 以及怎么参与战斗
完整字段参考
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
id | string | 是 | — | 属性的唯一 ID, 其他模块引用这个属性时就用它 |
display_name | string | 否 | 同 id | 展示用的名称, 也用在 Lore 匹配的 %Key% 变量里 |
value_kind | enum | 否 | FLAT | 数值类型 (见下方枚举说明) |
target_type | enum | 否 | GENERIC | 属性目标类型 (见下方枚举说明) |
target_id | string | 否 | "" | 目标 ID. DAMAGE 类型对应伤害类型 ID; RESOURCE 对应资源 ID; VANILLA 对应原版属性名 |
mmoitems_stat | string | 否 | "" | MMOItems stat ID 的映射; 装了 MMOItems 时用它把属性读取接过去 |
default_value | double | 否 | 0 | 默认基础值 |
min_value | double | 否 | 无限制 | 最小值限制. 聚合后的最终值低于这个值会被抬到这个值 |
max_value | double | 否 | 无限制 | 最大值限制. 聚合后的最终值高于这个值会被压到这个值 |
allow_negative | boolean | 否 | true | 要不要允许负值; 填 false 时最终值如果是负的会归零, 效果等同 min_value: 0 |
priority | integer | 否 | 0 | Lore 匹配的优先级; 越高越先匹配, 避免短名称抢在长名称前面被误匹配 |
lore_format_id | string | 否 | "" | 关联的 Lore 格式 ID (定义在 lore_formats/ 中) |
lore_pattern | string | 否 | — | 单条 Lore 匹配正则表达式, 与 lore_patterns 二选一 |
lore_patterns | list<string> | 否 | [] | 多条 Lore 匹配正则表达式 |
attribute_power | double | 否 | 1.0 | 属性战力权重系数, 用来算装备或玩家的总战力 |
tags | list<string> | 否 | [] | 属性标签列表 (如 DEBUFF). 供 MythicMobs 的 emaki_attribute_add_tag / emaki_attribute_clear_tag 按标签批量增删临时属性. 标签不区分大小写 |
temporary_stack_mode | enum | 否 | REPLACE | 该属性作为临时属性, 在同一效果组内对同一属性重复施加时的叠加模式: REPLACE 覆盖, STACK 数值与剩余时间相加. 不同效果组之间的同属性始终并存 (ADD 求和), 不受此项影响. 技能显式传 stack_mode 时以技能为准 |
parent_attribute | boolean | 否 | false | 要不要作为父级属性参与属性点系统. 父级属性也可以从物品 Lore / EA 属性 PDC 进入快照, 并展开 child_bonuses |
child_bonuses | map<string,double> | 否 | {} | 每投入 1 点父级属性时, 额外贡献到子属性的数值. 目标子属性必须存在, 而且不能也是父级属性 |
description | string / list | 否 | "" | 描述文本, 可以用在 GUI 或帮助展示里 |
升级须知: 值域限制现在作用于最终值
过去 min_value / max_value / allow_negative 只在解析单行物品 Lore 时生效, 聚合后的最终值不受任何限制. 因此暴击率这类属性可以靠多件装备叠到 150% 并真的按 150% 结算
现在这三项会在所有来源聚合完毕后统一作用于最终值. 随附的 47 个属性定义全部声明了这三项, 所以每一个属性都会受影响, 其中上限为 100 的 9 个属性 (physical_crit_rate, projectile_crit_rate, spell_crit_rate, block_rate, block_reduction, dodge_chance 与三个 *_crit_evasion) 最容易被察觉
- 若服主此前依赖越界值生效, 上线后会被压回声明区间. 需要更高上限就改对应属性的
max_value, 不要靠越界叠加 - 最终值稳定下来的顺序是缩放曲线 → 派生属性 → 值域限制, 所以派生属性的输入不会被提前截断, 但派生结果本身也受自己的区间约束
- 单件装备的贡献不受限制, 只有实体最终值受限. 因此"+80 的装备"与"-50 的临时减益"都照常参与计算, 减益不会因为中间值越界而失效
- 范围值 (
1-5形态) 只有下界参与稳定, 区间宽度保持不变. 若下界被抬升, 整段区间会随之上移而不是被裁短
父级属性与属性点
父级属性对应"属性点"玩法: 玩家把可用属性点投进 parent_attribute: true 的属性, 系统会把投入的点数计入该父级属性, 再按 child_bonuses 算出对子属性的额外贡献. 玩家数据存在 data/parent_attributes/<UUID>.yml, 里面有 available_points, reset_points 和 allocations
yaml
id: strength
display_name: '<red>力量'
value_kind: FLAT
parent_attribute: true
child_bonuses:
physical_attack: 1.0
projectile_attack: 0.5父级属性会进入属性追踪和最终快照, 也可以像普通数值属性一样从物品 Lore 或 ea_attribute.ea_attributes PDC 读取. 物品上的父级值会保留自身 ID, 并按 child_bonuses 叠加到对应子属性 ID; Lore 与 PDC 中的同一父级属性先按普通来源相加, 再展开子属性. 系统不内置固定的父级或子级 ID, 也不会在缺少父级定义时创建备用属性; 所有关系都来自当前加载的属性 YAML. EmakiItem 的 variables 仍只负责文本占位, 不会自动成为 EA 属性. child_bonuses 指向不存在的属性或另一个父级属性时, /ea lint 会报告配置问题
value_kind 数值类型
| 值 | 说明 | 典型用途 |
|---|---|---|
FLAT | 平坦数值 (默认), 就是直接加减的固定值 | 物理攻击 +10, 防御 +5 |
PERCENT | 百分比数值; Lore 匹配时会自动处理 % 后缀 | 物理伤害 +8%, 防御加成 +12% |
CHANCE | 概率数值, 和 PERCENT 类似, 都按百分比处理 | 暴击率 +15%, 闪避率 +10% |
REGEN | 回复速率, 表示每秒或每游戏刻回复多少 | 生命恢复 +2/s, 法力恢复 +5/s |
RESOURCE | 资源上限加成, 增加资源的最大值 | 最大生命 +100, 最大法力 +50 |
DERIVED | 派生属性, 由其他属性算出来, 不直接从装备读取 | 综合战力, 有效生命 |
target_type 目标类型
| 值 | 说明 | target_id 用途 |
|---|---|---|
GENERIC | 通用属性 (默认), 不参与特定系统, 供条件, 展示或其他模块读取 | 不需要 |
DAMAGE | 伤害相关属性, 参与 damage_types/*.yml 中的伤害计算管线 | 对应伤害类型 ID, 如 physical, spell |
RESOURCE | 资源类属性, 影响玩家资源的最大值或回复 | 对应资源 ID, 如 health, mana |
VANILLA | 映射到 Minecraft 原版属性, 属性值变化时同步到 Bukkit 原版属性系统 | 对应原版属性名, 用裸名而不是 generic. 前缀, 如 max_health, attack_speed, scale |
示例: 物理攻击
yaml
id: physical_attack
display_name: '<red>物理攻击'
value_kind: FLAT
target_type: DAMAGE
target_id: physical
default_value: 0
min_value: 0
max_value: 999999
allow_negative: false
priority: 100
lore_format_id: default_flat
attribute_power: 1.0
description:
- '提高物理伤害。'示例: 暴击率
yaml
id: physical_crit_rate
display_name: '<yellow>物理暴击率'
value_kind: CHANCE
target_type: DAMAGE
target_id: physical
default_value: 0
min_value: 0
max_value: 100
allow_negative: false
priority: 90
lore_format_id: default_percent
attribute_power: 1.0
description:
- '提高物理暴击触发概率。'
- '数值范围 0~100,15 表示 15%。'示例: 生命值 (资源上限)
yaml
id: health
display_name: '<green>生命值'
value_kind: RESOURCE
target_type: RESOURCE
target_id: health
default_value: 0
min_value: 0
max_value: 1000000
allow_negative: false
priority: 100
lore_format_id: default_resource
attribute_power: 1.0若需要同步到 Bukkit 的原版生命上限, 改用 target_type: VANILLA 并把 target_id 写成裸名 max_health (内置 max_health_vanilla.yml 即此写法)
示例: 移动速度
yaml
id: movement_speed
display_name: '<aqua>移动速度'
value_kind: FLAT
target_type: GENERIC
target_id: movement_speed
default_value: 0.0
min_value: -1000
max_value: 1000
allow_negative: true
priority: 51
lore_format_id: default_flat
attribute_power: 1.0示例: 法力恢复
yaml
id: mana_regen
display_name: '<blue>法力恢复'
value_kind: REGEN
target_type: RESOURCE
target_id: mana
default_value: 0
min_value: 0
max_value: 100
allow_negative: false
priority: 60
lore_format_id: default_regen
attribute_power: 0.8
description:
- '每秒恢复的法力值。'区间随机值
Attribute 支持把单个属性贡献写成区间值. 解析时会得到最小值, 最大值和本次实际取值, 正好用在"随机攻击力""随机百分比加成"这类装备词条上
常见写法示例:
yaml
ea_attributes:
physical_attack: "10-20"
physical_crit_rate: "5%-12%"使用建议:
- 整数或普通数值区间适合攻击, 防御, 资源上限这类平坦属性
- 百分比区间适合
PERCENT/CHANCE类型属性; 系统内部仍建议统一用同一个数值尺度, 避免 0.15 与 15 混用 - 区间最终会写入快照贡献, 调试时要同时看最小值, 最大值和实际取值
- 新装备系统仍优先通过 PDC 属性 payload 写入区间结果, 不建议只依赖 Lore 文本
Lore 解析
lore_pattern 模板变量
你在 lore_pattern / lore_patterns 里可以用下面这些模板变量:
| 变量 | 展开为 |
|---|---|
%Key% / %key% | 属性 display_name 的正则转义字符串 |
%Value% / %value% | 数值捕获组 ([+-]?\d+(?:\.\d+)?)(?:\s*[-~~]\s*([+-]?\d+(?:\.\d+)?))?. 一共两个捕获组: 第一组是数值本身, 第二组是可选的区间上界, 区间分隔符支持 -, ~ 与全角 ~. 只匹配到第一组时, 上下界相同 |
示例
yaml
lore_patterns:
- '%Key%:%Value%'
- '%Key% \\+%Value%'如果 display_name 为 物理攻击, 上面的模式会匹配:
物理攻击:15物理攻击 +15
Lore 解析的局限性
lore_patterns 是从已有物品 Lore 里读出属性的, 适合兼容旧物品或外部插件物品. 但做新装备系统时别把它当主要数据来源, 原因是:
- 文本解析容易受颜色, 语言, 格式影响
- 玩家或其他插件可能修改 Lore
- 性能和稳定性不如 PDC
- 正则匹配可能误匹配到相似的文本
新系统建议让 EmakiItem, Forge, Strengthen, Gem 等模块直接把属性写进 PDC 属性 payload
lore_format_id 优先级
内置 Lore 格式的默认优先级:
| 格式 ID | 优先级 |
|---|---|
default_percent | 100 |
default_regen | 80 |
default_resource | 60 |
default_flat | 50 |
优先级越高, 在 Lore 中越先匹配
数值范围设计
百分比属性
记住, 本模块统一按 0~100 结算百分比与概率, 15 就是 15%. 内置属性与配置全部遵循这一尺度: physical_crit_rate 的 max_value 为 100.0, config.yml 的 default_profile.attributes 里 physical_crit_damage: 150.0, block_rate / block_reduction: 100.0, damage_types/physical.yml 的表达式也统一写成 (%multiplier% / 100). 概率类输入在结算时会被夹到 [0, 100]
yaml
# 推荐: 统一使用 0~100
min_value: 0
max_value: 100 # 100% 上限
# 不推荐: 混用 0~1 尺度
min_value: 0
max_value: 1 # 结算按 0~100 处理, 这里的 1 只相当于 1%攻击和防御
建议设置合理上限, 防止数值膨胀:
yaml
# 攻击
max_value: 999999
# 防御 (通常不应超过攻击上限)
max_value: 999999
# 穿透 (通常不应超过防御上限)
max_value: 999999