Skip to content

属性定义

属性文件位于 attributes/*.yml。每个文件通常定义一个属性。属性定义决定一个数值如何被识别、限制、展示和参与战斗。

完整字段参考

字段类型必填默认值说明
idstring属性唯一 ID。其他模块引用属性时使用它。
display_namestringid展示名称。也用于 Lore 匹配时的 %Key% 变量。
value_kindenumFLAT数值类型(见下方枚举说明)。
target_typeenumGENERIC属性目标类型(见下方枚举说明)。
target_idstring""目标 ID。DAMAGE 类型对应伤害类型 ID;RESOURCE 对应资源 ID;VANILLA 对应原版属性名。
mmoitems_statstring""MMOItems stat ID 映射。安装 MMOItems 时用于桥接属性读取。
default_valuedouble0默认基础值。
min_valuedouble无限制最小值限制。聚合后的最终值低于此值会被抬到此值。
max_valuedouble无限制最大值限制。聚合后的最终值高于此值会被压到此值。
allow_negativebooleantrue是否允许负值。为 false 时最终值为负会归零,等效于 min_value: 0
priorityinteger0Lore 匹配优先级。越高越先匹配,避免短名称误匹配长名称。
lore_format_idstring""关联的 Lore 格式 ID(定义在 lore_formats/ 中)。
lore_patternstring单条 Lore 匹配正则表达式。与 lore_patterns 二选一。
lore_patternslist<string>[]多条 Lore 匹配正则表达式。
attribute_powerdouble1.0属性战力权重系数。用于计算装备或玩家总战力。
tagslist<string>[]属性标签列表(如 DEBUFF)。供 MythicMobs 的 emaki_attribute_add_tag / emaki_attribute_clear_tag 按标签批量增删临时属性。标签不区分大小写。
temporary_stack_modeenumREPLACE该属性作为临时属性、在同一效果组内对同一属性重复施加时的叠加模式:REPLACE 覆盖,STACK 数值与剩余时间相加。不同效果组之间的同属性始终并存(ADD 求和),不受此项影响。技能显式传 stack_mode 时以技能为准。
parent_attributebooleanfalse是否作为父级属性参与属性点系统。父级属性也可从物品 Lore / EA 属性 PDC 进入快照,并展开 child_bonuses
child_bonusesmap<string,double>{}每投入 1 点父级属性时,额外贡献到子属性的数值。目标子属性必须存在且不能也是父级属性。
descriptionstring / list""描述文本,可用于 GUI 或帮助展示。

升级须知:值域限制现在作用于最终值

过去 min_value / max_value / allow_negative 只在解析单行物品 Lore 时生效,聚合后的最终值不受任何限制。因此暴击率这类属性可以靠多件装备叠到 150% 并真的按 150% 结算。

现在这三项会在所有来源聚合完毕后统一作用于最终值。随附的 47 个属性定义全部声明了这三项,所以每一个属性都会受影响,其中上限为 100 的 9 个属性(physical_crit_rateprojectile_crit_ratespell_crit_rateblock_rateblock_reductiondodge_chance 与三个 *_crit_evasion)最容易被察觉。

  • 若服主此前依赖越界值生效,上线后会被压回声明区间。需要更高上限就改对应属性的 max_value,不要靠越界叠加。
  • 收敛顺序是缩放曲线 → 派生属性 → 值域限制,所以派生属性的输入不会被提前截断,但派生结果本身也受自己的区间约束。
  • 单件装备的贡献不受限制,只有实体最终值受限。因此「+80 的装备」与「-50 的临时减益」都照常参与计算,减益不会因为中间值越界而失效。
  • 范围值(1-5 形态)只有下界参与收敛,区间宽度保持不变。若下界被抬升,整段区间会随之上移而不是被裁短。

父级属性与属性点

父级属性用于“属性点”玩法:玩家把可用属性点投入 parent_attribute: true 的属性,系统会把投入点数本身计入该父级属性,并按 child_bonuses 计算对子属性的额外贡献。玩家数据保存在 data/parent_attributes/<UUID>.yml,包含 available_pointsreset_pointsallocations

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回复速率。表示每秒或每 tick 的回复量。生命恢复 +2/s、法力恢复 +5/s。
RESOURCE资源上限加成。增加资源的最大值。最大生命 +100、最大法力 +50。
DERIVED派生属性。由其他属性计算得出,不直接从装备读取。综合战力、有效生命。

target_type 目标类型

说明target_id 用途
GENERIC通用属性(默认)。不参与特定系统,供条件、展示或其他模块读取。不需要。
DAMAGE伤害相关属性。参与 damage_types/*.yml 中的伤害计算管线。对应伤害类型 ID,如 physicalspell
RESOURCE资源类属性。影响玩家资源的最大值或回复。对应资源 ID,如 healthmana
VANILLA映射到 Minecraft 原版属性。属性值变化时同步到 Bukkit 原版属性系统。对应原版属性名,使用裸名而非 generic. 前缀,如 max_healthattack_speedscale

示例:物理攻击

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_percent100
default_regen80
default_resource60
default_flat50

优先级越高,在 Lore 中越先匹配。

数值范围设计

百分比属性

本模块统一按 0~100 结算百分比与概率,15 表示 15%。内置属性与配置全部遵循这一尺度:physical_crit_ratemax_value100.0config.ymldefault_profile.attributesphysical_crit_damage: 150.0block_rate / block_reduction: 100.0damage_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