Skip to content

物品定义与套装 ​

物品定义与套装的写法: 怎么写 items/*.yml 与 sets/*.yml 这两个目录里的文件, 各个字段分别起什么作用

物品文件放在 items/ 下 (可以带子目录, 深度由 data_directories.max_depth 控制), 套装文件放在 sets/ 下. 你用物品定义决定一个稳定的物品 ID 怎样生成游戏内的物品 (ItemStack), 用套装定义决定多件装备同时穿戴时额外提供什么效果

注意 items/ 下有一个例外文件名: pack.yml 不是物品定义, 它描述所在目录作为物品包在浏览界面里的外观, 会被物品加载器跳过. 字段见物品浏览 GUI

物品定义字段 ​

顶层字段 ​

看表前先记住: 「必填」一列问的是插件缺了这个键时会不会自己顶上默认值, 「取值范围」写插件实际的限制, 插件不校验的写「—」

字段类型必填默认值取值范围说明示例
idstring是——物品的唯一 ID, 其他模块要引用时用的就是它. 留空或缺失时跳过该文件example_item
itemobject是——基础物品定义, 这里只认 source 与 components. 缺失时因为构造不出基础物品, 该定义会被跳过并输出警告见"item 与 item.components"
effectslist否—type 取值见"效果系统"业务效果的唯一入口: 变量, EmakiAttribute 属性, EmakiSkills 技能, 饰品槽声明与名称/Lore 动作链都写在这里见"效果系统"
equip_slotstring否allall / hand / main_hand / off_hand / helmet / chestplate / leggings / boots业务属性和技能生效的装备槽, 不管原版拖拽穿戴的拦截. 不支持的值会回退成 all 并输出警告main_hand
setobject否——套装归属, 含 id 与 piece见"set"
conditionobject否——装备条件配置, 字段见"条件配置"见"条件配置"
repairobject否——修复配置, 字段见物品修复系统见"修复配置"
updateobject否——自动更新配置, 字段见物品更新策略见下
actionsobject否——触发动作配置; 这里的 key 必须写成触发器页列出的触发器名right_click: [...]

已下线的字段与写法

下列写法已停止读取: 写了不再产生任何效果, 只在加载时输出一条 WARN (含键名与文件路径). 请按下表改写

已下线写法位置改写为
variables, ea_attributes, es_skills, accessory_slots根级effects 中对应的 type 条目
es_skill_triggers, skill_triggers根级type: "es_skill" 效果里的 es_skill_triggers
name_actions, lore_actions根级type: "name_action" / type: "lore_action" 效果
source, components根级移入 item.source / item.components
amount根级与 item.amount定义不再携带数量; 用 /ei give <player> <id> [amount] 指定, 省略时为 1
material, display_name, item_name, lore根级item.components 下的 custom_name / item_name / lore 等组件
item_source, itemrepair.materials 条目内item_sources
skill_triggerstype: "es_skill" 效果内es_skill_triggers

为什么要下线? 效果简写与 effects 是同一份数据的两个入口, 同时书写时的合并结果按字段不同 (覆盖, 并集或动作重复执行), 你无法从配置本身判断哪一份生效; amount 则因数量可在给予时指定而不再由定义承担

set 与 update 的子字段:

字段类型必填默认值取值范围说明示例
set.idstring否""—所属套装 ID, 对应 sets/*.yml. 为空时不参与套装计算example_set
set.piecestring否""—这件物品在套装里是哪个部件, 要和套装定义 pieces 的 key 对上blade
update.enabledboolean否falsetrue / false是否启用物品更新; 必须为 true 且 version >= 1 才生效true
update.versioninteger否0>= 0 (>= 1 才生效)物品版本号; 大于物品 PDC 里记录的版本时才重建1
update.preserve_amountboolean否truetrue / false更新时是否保留物品数量true
update.preserve_damageboolean否truetrue / false更新时是否保留耐久损耗true
update.preserve_unknown_attribute_sourcesboolean否truetrue / false更新时是否保留来自未知来源的属性true
update.triggersobject否—见物品更新策略更新触发器开关; 没写出来的项默认为 truejoin: true

现在物品定义只有两个入口: item (item.source + item.components) 与 effects, 上面清单里的旧写法一律不再被读取. 定义也不再声明堆叠数量 -- 用 /ei give <player> <id> [amount] 发放时, 省略数量给 1 个; 浏览界面单击给 1 个, Shift 单击给一整叠; 其他模块按自身需要传入数量

item 与 item.components ​

字段类型必填默认值取值范围说明示例
item.sourcestring否—CoreLib 已注册的任意 ItemSource基础物品来源 (用 CoreLib 的 ItemSource 短横线写法). 缺失或创建不出来时, 这个定义不会被缓存minecraft-diamond_sword
item.componentsmap否——原版 Data Component 覆盖. 键可以是命名空间组件 ID, 也可以是下表的 EmakiItem 简写键见下方

下面是 item.components 的简写键 (会被转换为对应的命名空间组件):

字段类型必填默认值取值范围说明示例
custom_model_data标量/map否——自定义模型数据. 标量会包装为 floats: [值]; 已含 floats/flags/strings/colors 的 map 原样使用floats: [1001.0]
item_modelstring否""—物品模型 ID; 空值不写入minecraft:custom/example_blade
tooltip_stylestring否""—提示框样式 ID; 空值不写入minecraft:custom/rare_tooltip
enchantmentsmap否空值须为正整数附魔 ID → 等级; 非正数或无法解析的条目被丢弃minecraft:sharpness: 5
item_flagslist否空见下旧版隐藏 flag; 会映射为 minecraft:tooltip_display.hidden_components- HIDE_ATTRIBUTES
hide_tooltipboolean否falsetrue / false是否在提示框中隐藏全部信息 (tooltip_display.hide_tooltip)true
unbreakableboolean否falsetrue / false是否写入 minecraft:unbreakabletrue
enchantment_glint_overrideboolean否无true / false是否强制附魔光效; 不写则不覆盖true
max_stack_sizeint否无原版组件允许的范围最大堆叠数1
raritystring否""原版稀有度名物品稀有度; 空值不写入rare
damageint否无原版组件允许的范围初始耐久损耗值0
max_damageint否无原版组件允许的范围最大耐久值1561
enchantableint否无—可附魔值, 写为 minecraft:enchantable.value15
attribute_modifierslist否空—原版属性修饰符列表. 简写形式条目字段为 attribute (属性 ID), amount, operation (默认 add_number), slot (默认 any), name (默认 emakiitem:<物品 ID>/<属性>); 命名空间组件形式则使用标准 type/id/amount/operation/slot 结构见"item 与原版组件"
rawstring否""—保留键: 源码会读取, 但当前版本不据此生成任何组件—

下面是 item_flags 到组件的映射: HIDE_ENCHANTS→enchantments, HIDE_ATTRIBUTES→attribute_modifiers, HIDE_UNBREAKABLE→unbreakable, HIDE_DESTROYS→can_break, HIDE_PLACED_ON→can_place_on, HIDE_ADDITIONAL_TOOLTIP (或 HIDE_POTION_EFFECTS) →potion_contents, HIDE_DYE→dyed_color, HIDE_ARMOR_TRIM→trim; 其他值按原样当作组件 ID

旧版物品定义自动迁移已下线 ​

升级后要注意: items/*.{yml,yaml} 不再在 definition 解析前执行 configured-item 迁移: CoreLib 已移除 item.migration.configureditem 包与运行时 LegacyConfiguredItemConverter, EmakiItem 的加载入口也不再调用迁移执行器.文件改写式迁移已下线, 根级 source / amount / components 的读取兼容也已一并下线 -- 基础物品现在只能写在 item 下:

  • 物品来源写 item.source, 例如 minecraft-diamond_sword
  • 名称, Lore, 模型数据, 附魔与其它组件写 item.components
  • 堆叠数量不写在定义里, 改由 /ei give <player> <id> [amount] 指定

你要按上面的结构手工改写配置, 并在升级前自行备份配置目录. 改写后旧字段不会被改写或补齐, 也不会不声不响就生效 -- 写了会在加载时输出一条 WARN. plugins/EmakiItem/migration-backups/configured-item-format/ 备份目录不会再生成, 迁移期写入的旧备份仍留在该目录下, 可自行清理

effects, equip_slot, set, condition, repair, update, actions 等业务字段含义不变

效果系统 (effects) ​

物品效果统一写在 effects 列表里, 用 type 字段区分类型:

type说明
variables表达式引擎变量, 用于渲染名称与 Lore 里的占位符; 数据使用 variables map
ea_attributeEmakiAttribute 的 PDC 属性, 写入物品 PDC; 数据使用 ea_attributes map
es_skillEmakiSkills 技能附加, 装备时获得技能; 数据使用 es_skills 列表, 可选 es_skill_triggers map
accessory_slot饰品槽声明: 把这件物品可以放进哪些饰品槽写入物品 PDC, 供 EmakiAccessory 判断能不能放进饰品栏; 数据使用 accessory_slots 列表
name_action名称处理动作链; 数据使用 name_actions (或 name_action) 列表
lore_actionLore 处理动作链; 数据使用 lore_actions (或 lore_action) 列表

除了这六个内置 type, 你还可以用 EmakiItemApi.extensions().registerEffectType(...) 注册自定义类型; 写了没注册处理器的 type, 条目会被不报错地跳过. 见 API

yaml
effects:
  - type: "variables"
    variables:
      physical_attack: 12
      physical_crit_rate: 5
  - type: "ea_attribute"
    ea_attributes:
      physical_attack: 12.0
      physical_crit_rate: 5.0
  - type: "es_skill"
    es_skills:
      - "fireball"
      - "flame_dash"
    es_skill_triggers:
      fireball: "right_click"
  - type: "accessory_slot"
    accessory_slots:
      - "ring"

es_skill 效果支持可选的 es_skill_triggers, 格式为 技能 ID: 触发器 ID. 写了它, 该技能在装备时就由指定触发器释放, 不占用玩家技能槽

想要真实属性输出, 把属性值写进 type: ea_attribute 效果的 ea_attributes; 当前配置线不再使用 ea_attribute_meta. variables 只作为显示文本和占位符上下文, 不会自动变成 Attribute PDC 属性

写入技能 ID 与技能触发器时, 插件不检查 EmakiSkills 是否启用; 相关键由独立的协议模块统一持有

饰品槽声明 (accessory_slot) ​

accessory_slot 只回答一个问题: 这件物品能放进哪些饰品栏格. 它不参与原版装备槽判定, 也不改变 equip_slot 的含义. 列表取值有两种细致程度:

取值含义示例
饰品部位 id该部位的任意一格都接受ring 表示 ring_1, ring_2 都能放
槽位实例 id只有指定的那一格接受ring_2 只接受第二格

部位 id 写在 EmakiAccessory 的 parts.yml 里 (<部位ID>_<序号> 展开为槽位实例 id). 取值会被规范化 (去空白, 转小写), 重复项合并; 空列表等于没有声明

声明写在物品 PDC 的 emakiitem:accessory_slots 键里 (字符串列表). EmakiAccessory 只认这个键, 把它作为唯一的物品自带声明来源:

  • 没写这个键的物品一律放不进饰品栏, 提示 gui.not_declared;
  • 写了键, 但当前格不在列表内的物品同样被拒绝, 提示 gui.slot_mismatch;
  • 已经放在槽里, 之后又不匹配的物品, 关闭饰品栏时会自动退回玩家背包并提示

这取代了旧行为: 以前物品没显式指定槽位时按 all 处理, 任何 EmakiItem 物品都能放进任意饰品格. 你手上的已有物品要在 update 触发时被重写 (见物品更新) 或重新发放, 才会带上新的声明键; 饰品槽声明参与定义签名, 因此定义新增该声明后会被判定为需要更新

饰品栏侧的完整判据, 条件判定与耐久度含义见属性与技能接入

item 与原版组件 ​

yaml
item:
  source: minecraft-netherite_sword
  components:
    custom_name: '<gradient:red:gold>%name%</gradient>'
    lore:
      - '<gray>攻击:%physical_attack%</gray>'
    item_model: emaki:flame_blade
    custom_model_data:
      floats: [1001.0]
    attribute_modifiers:
      - type: minecraft:attack_damage
        id: emakiitem:flame_blade/attack_damage
        amount: 12.0
        operation: add_value
        slot: mainhand
    rarity: rare
    max_stack_size: 1
    $unset:
      - repairable
    $reset:
      - enchantments

components 里的键用 Minecraft 命名空间组件 ID; 没写命名空间时默认补 minecraft:, 例如 custom_name 等价于 minecraft:custom_name, 显式写的其他命名空间保持不变. 该规则同样适用于 $unset / $reset 列表. map/list/scalar 直接按 JSON 等价结构写成 YAML; 普通值表示 SET, $unset 删除组件, $reset 恢复材质原型默认值. 文本组件允许 MiniMessage 字符串简写; 极少数 JSON 无法无损表达的 NBT 可使用受控 {$snbt: '...'} 逃生口

错误与版本策略:

  • 未知组件 ID: 配置错误, 定义不会进入有效缓存
  • 当前版本支持但值非法: 配置错误, 定义不会进入有效缓存
  • 已知但高于服务器版本: 跳过该组件并记录警告, 其余组件继续处理
  • 第三方 ItemSource: 保留来源身份, PDC 和未知组件, 只应用当前 Paper 能安全传递的组件

item.source 不限于 Bukkit Material, CoreLib 当前注册的所有 ItemSource 都能用. 如果 resolver 不存在, 插件未安装或来源创建不出来, 这个 EmakiItem 定义就不会被缓存. 最低支持 Paper 26.1+; 组件目录与运行时 capability 共同决定当前服务器能用哪些能力

物品示例 ​

基础武器 ​

yaml
id: "beginner_blade"
item:
  source: minecraft-iron_sword
  components:
    minecraft:custom_name: "<white>新手长剑</white>"
    minecraft:lore:
      - "<gray>一把稳定可靠的基础武器。</gray>"
      - ""
      - "<gray>攻击力:<white>+10</white></gray>"
    minecraft:unbreakable: {}
    minecraft:tooltip_display:
      hidden_components:
        - minecraft:unbreakable
effects:
  - type: "ea_attribute"
    ea_attributes:
      physical_attack: 10.0
set:
  id: "beginner_set"
  piece: "weapon"

带变量的高级装备 ​

yaml
id: "flame_blade"
item:
  source: minecraft-netherite_sword
  components:
    minecraft:custom_name: "<gradient:red:gold>%name%</gradient>"
    minecraft:lore:
      - "<dark_gray>━━━━━━━━━━━━━━━━━━</dark_gray>"
      - "<red>⚔ 物理攻击:<white>+%physical_attack%</white></red>"
      - "<yellow>✦ 暴击率:<white>+%physical_crit_rate%%</white></yellow>"
      - "<dark_gray>━━━━━━━━━━━━━━━━━━</dark_gray>"
      - "<gray>传说中由龙焰锻造的神兵。</gray>"
    minecraft:item_model: "emaki:flame_blade"
    minecraft:enchantment_glint_override: true
    minecraft:rarity: "rare"
    minecraft:max_stack_size: 1
effects:
  - type: "variables"
    variables:
      name: "烈焰之刃"
      physical_attack: 45
      physical_crit_rate: 12
  - type: "ea_attribute"
    ea_attributes:
      physical_attack: 45.0
      physical_crit_rate: 0.12
  - type: "es_skill"
    es_skills:
      - "flame_slash"
set:
  id: "flame_set"
  piece: "weapon"

消耗品 ​

yaml
id: "health_potion_large"
item:
  source: minecraft-potion
  components:
    minecraft:custom_name: "<red>大型生命药水</red>"
    minecraft:lore:
      - "<gray>右键使用,恢复 50 点生命。</gray>"
      - "<dark_gray>使用后消耗。</dark_gray>"
    minecraft:max_stack_size: 16
    minecraft:custom_model_data:
      floats: [1001.0]
actions:
  right_click:
    - 'heal amount=50'
    - 'play_sound sound=minecraft:entity.generic.drink volume=1 pitch=1'
    - 'clear_item slot=mainhand source=emakiitem-health_potion_large'
    - 'send_message text="<green>恢复了 50 点生命。</green>"'

写 actions 时, key 必须是触发器页列出的触发器名, 例如 right_click, consume, attack, give; 没列出的 key 不会被执行

条件配置 ​

你可以给物品配装备条件, 玩家不满足时, 这件物品对他整体失效:

yaml
condition:
  type: "at_least"
  entries:
    - "%player_level% >= 10"
    - "%player_class% == 'warrior'"
  required_count: 2
  invalid_as_failure: true
  on_pass:
    actions:
      - 'send_message text="<green>装备条件满足,属性已生效。</green>"'
  on_fail:
    message: "<red>你不满足装备条件!</red>"
    actions:
      - 'send_message text="<red>需要等级 10 以上的战士才能装备此武器。</red>"'
字段类型必填默认值取值范围说明示例
typestring否all_ofall_of / any_of / none_of / at_least / exactly条件组合方式at_least
entrieslist否空—条件表达式列表. 键名只能是 entries- "%player_level% >= 10"
required_countint否0—需要满足的条件条数; 只有 at_least, exactly 会读它, 其他组合方式完全不读这个字段2
invalid_as_failureboolean否truetrue / false表达式解析失败时是否算作不满足true
on_pass.actionslist否空—条件满足时执行的动作- 'send_message ...'
on_fail.messagestring否""—不满足时的提示消息<red>你不满足装备条件!</red>
on_fail.actionslist否空—不满足时执行的动作—
on_fail.block_outputboolean否falsetrue / false不满足时是否拦截该物品的输出传递false

WARNING

条件列表的键名必须写成 entries. 写成其他名称时解析会得到空的条件组, 物品条件整体失效且不会告警

required_count 只在 type 为 at_least 或 exactly 时被读取. all_of 与 any_of 完全忽略这个字段, 写上它不会把 any_of 变成"至少 N 条"

门控范围 ​

没满足条件时, 下面这些内容全部不生效:

传递面数据来源
EA 属性Lore 词条与 PDC 属性两条来源同时失效
装备技能Lore 与 PDC 两条来源同时失效
套装属性emakiitem 与 emakiitem_set 两个 PDC 来源
触发器动作该次触发被拦截
饰品贡献同物品戴在饰品栏时, 属性, 技能与套装件数一并失效 (由 EmakiAccessory 求值)

不受这个条件门控, 仍然生效的是: EmakiGem 宝石, EmakiForge 锻造, EmakiStrengthen 强化各自写入的 PDC 属性. 它们由对应模块拥有, 不随宿主物品条件失效

什么时候算? 触发器动作在每次触发执行前求值; 属性与技能在每次装备收集时 按玩家实时求值, 所以等级, 职业一变就立即生效, 不用重新装备. 属性与技能的门控求值不发送 on_fail.message, 不执行 on_pass/on_fail 动作, 这些只在触发器路径产生

属性与技能门控由 EmakiAttribute 承载, 前提是 EmakiAttribute 已启用; 只装了 EmakiItem 时, 条件只门控触发器动作

饰品这边的门控走 EmakiItemApi 的条件查询 (conditionSatisfied), 查询本身不产生任何提示, 也不依赖 EmakiAttribute; 它在饰品贡献重算时求值, 所以条件变化要等到下一次重算 (装备/换页/GUI 编辑/上线加载/reload/取回/耐久扣满) 才反映到饰品栏, 而装备路径是每次收集时实时求值. 饰品栏中的条件未满足 标识见饰品栏界面

修复配置 ​

物品耐久耗尽后, 你可以用材料或金币把它修好:

yaml
repair:
  enabled: true
  materials:
    - item_sources:
        - "minecraft-diamond"
      amount: 1
      restore: 250
  economy:
    enabled: true
    restore: "100%"
    currencies:
      - provider: "vault"
        currency_id: ""
        base_cost: 100
        cost_formula: "base_cost + missing_durability * 0.25"
        display_name: "金币"
  on_disabled:
    - 'send_message text="<red>你的武器已损坏!</red>"'
  on_repaired:
    - 'send_message text="<green>武器已修复!</green>"'

字段含义与完整流程见物品修复系统

套装定义 ​

套装字段 ​

字段类型必填默认值取值范围说明示例
idstring是——套装唯一 ID. 缺失或非法 (规范化后为空) 时跳过该文件example_set
display_namestring否套装 ID—套装显示名 (MiniMessage 格式); 空值时回退为套装 ID<aqua>示例守护者套装</aqua>
piecesmap否空—套装部件定义 (key 为部件标识)见"部件定义"
loreobject否见"Lore 显示配置"—套装 Lore 显示格式配置见"Lore 显示配置"
thresholdsmap否空key 必须为正整数件数阈值效果配置; 非正数或非 section 的条目被跳过2: {...}

把套装文件放进 sets/ 下即可, 支持子目录递归加载. id 重复时只保留第一个定义并输出警告

状态计算与错误槽位 ​

套装的可见性和激活件数是分开算的. 只要物品定义里写了有效的 set.id, 当前状态就保留这个套装; 就算所有候选件都因为槽位不匹配而无效, Lore 也会显示 0/%total%, 而不是当成"缺少套装定义"的空状态

只有同时满足下面三个条件的装备, 才计入 activeCount 和激活阈值:

  1. 能唯一解析到 sets/*.yml 中的真实部件;
  2. 当前装备槽匹配物品定义的 equip_slot;
  3. 当前装备槽同时匹配套装部件的 slot

缺失或无法加载的套装定义会被安全隔离: 不进入可见状态, 不触发奖励, 也不做破坏性 Lore 写回; 运行时会为每个缺失套装 ID 输出一次警告, 启用 set DEBUG 时还会输出 [DEBUG:SET_STATE] state=missing_definition action=preserve. Folia 与 Paper 都使用同一套纯状态构造规则, Folia 只改变 owner-thread 调度边界

部件定义 (pieces) ​

yaml
pieces:
  blade:
    item: "example_item"
    slot: "main_hand"
    display: "示例之刃"
  helmet:
    item: "example_guardian_helmet"
    slot: "helmet"
    display: "守护者头盔"
字段类型必填默认值取值范围说明示例
itemstring否部件 key—对应的物品 ID (items/ 目录下的物品定义)example_item
slotstring否部件 keymain_hand / off_hand / helmet / chestplate / leggings / boots (默认回退为部件 key 本身)装备槽位main_hand
displaystring否部件 key—在套装 Lore 中显示的部件名称示例之刃

部件也可以简写成 部件key: 物品ID, 此时槽位与显示名都回退为部件 key

Lore 显示配置 ​

yaml
lore:
  header: "<dark_gray>—— <aqua>套装名</aqua> <gray>(%active%/%total%)</gray> ——</dark_gray>"
  equipped_format: "<green>✔ %piece%</green>"
  missing_format: "<gray>✘ %piece%</gray>"
  active_threshold_format: "<green>%line%</green>"
  inactive_threshold_format: "<dark_gray>%line%</dark_gray>"
  separator: ""
字段类型必填默认值取值范围说明示例
headerstring否<dark_gray>—— %set_name% <gray>(%active%/%total%)</gray> ——</dark_gray>—套装 Lore 头部行模板见上方片段
equipped_formatstring否<green>✔ %piece%</green>—已装备部件的显示模板见上方片段
missing_formatstring否<gray>✘ %piece%</gray>—未装备部件的显示模板见上方片段
active_threshold_formatstring否<green>%line%</green>—已激活阈值行的显示模板见上方片段
inactive_threshold_formatstring否<dark_gray>%line%</dark_gray>—未激活阈值行的显示模板见上方片段
separatorstring否""—行分隔符; 空串表示不插入分隔行""

阈值效果 (thresholds) ​

阈值 key 就是激活需要几件. 每个阈值只有 lore 与 effects 两个字段, 效果一律写在 effects 里

字段类型必填默认值取值范围说明示例
lorelist否空—阈值激活时展示的 Lore 行- "[2件套] 物理攻击 +5"
effectslist否空type 取值 ea_attribute / es_skill / name_action / lore_action阈值效果列表见"套装示例"

注意, 阈值的顶层简写 (ea_attributes, es_skills, name_actions, lore_actions, 以及从未生效的 name_action / lore_action) 与效果数据的备用别名 (ea_attribute 的 attributes, es_skill 的 es_skill) 同样已停止读取, 写了只会在加载时输出一条 WARN

套装示例 ​

yaml
id: "example_set"
display_name: "<aqua>示例守护者套装</aqua>"

pieces:
  blade:
    item: "example_item"
    slot: "main_hand"
    display: "示例之刃"
  helmet:
    item: "example_guardian_helmet"
    slot: "helmet"
    display: "守护者头盔"
  chestplate:
    item: "example_guardian_chestplate"
    slot: "chestplate"
    display: "守护者胸甲"
  boots:
    item: "example_guardian_boots"
    slot: "boots"
    display: "守护者战靴"

lore:
  header: "<dark_gray>—— <aqua>示例守护者套装</aqua> <gray>(%active%/%total%)</gray> ——</dark_gray>"
  equipped_format: "<green>✔ %piece%</green>"
  missing_format: "<gray>✘ %piece%</gray>"
  active_threshold_format: "<green>%line%</green>"
  inactive_threshold_format: "<dark_gray>%line%</dark_gray>"
  separator: ""

thresholds:
  2:
    lore:
      - "[2件套] 物理攻击 +5,解锁冲刺技能"
    effects:
      - type: "ea_attribute"
        ea_attributes:
          physical_attack: 5.0
      - type: "es_skill"
        es_skills:
          - "guardian_dash"
  4:
    lore:
      - "[4件套] 物理攻击 +15,物理防御 +10,解锁守护者光环"
    effects:
      - type: "ea_attribute"
        ea_attributes:
          physical_attack: 15.0
          physical_defense: 10.0
      - type: "es_skill"
        es_skills:
          - "guardian_aura"

自动更新 ​

update 配置决定物品在哪些时机自动刷新:

yaml
update:
  enabled: true
  version: 1
  triggers:
    join: true
    held_change: true
    inventory_click: true
    inventory_drag: true
    pickup: true
    interact: true
    command: true
触发项说明性能影响
join玩家登录时低
held_change切换手持物品时低
inventory_click点击背包时中
inventory_drag拖拽物品时中
pickup拾取物品时低
interact交互事件时中
command执行 /ei update 时低

改完物品配置, 递增 version 字段就能触发更新. 你先确保手动 /ei update 正常, 再逐步开启自动更新, 别一次开太多高频触发