简体中文
强化配方
一件装备的强化规则写在 recipes/*.yml 里: 各星级成功率, 需要什么材料, 失败怎么罚, 成功后加什么效果和动作
配方文件放在 recipes/*.yml. 配方的身份看必填的 id 字段, 与文件名无关; 文件名只用来组织文件和定位报错
顶层字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
schema_version | integer | 否 | 1 | 1~2 (超出范围整份配方被跳过) | 材料的结构版本; 材料条目按这个版本做规范化 |
id | string | 是 | — | — | 配方唯一 ID; 缺失或为空时整份配方被跳过 |
display_name | string | 否 | 取 id | — | 配方显示名 (MiniMessage 格式) |
gui_template | string | 否 | strengthen_gui | — | GUI 模板引用 (gui/ 下模板名, 不含 .yml) |
economy | object | 否 | enabled 依 currencies 是否为空 | — | 经济系统配置 (每次强化要扣的费用) |
limits | object | 否 | Limits.defaults() | — | 强化限制 (最大星级, 锻印等), 见强化限制 |
success_rates | map | 否 | 空 (回退到 config.yml 全局值) | 键为目标星级正整数 | 各星级基础成功率 (百分比) |
matcher | object | 否 | 无 | CoreLib 通用匹配器 | 按非物品源条件判定哪些装备可使用此配方. 见匹配规则 |
source_patterns | list | 否 | 空 (不限来源) | 正则字符串 | 按物品来源模式匹配 (忽略大小写的部分匹配), 与其余三个字段要同时满足. 见匹配规则 |
slot_groups | list | 否 | 空 (不限槽位组) | weapon / armor / offhand / generic | 槽位组匹配 (小写), 与其余三个字段要同时满足. 见匹配规则 |
stats_any | list | 否 | 空 (不限属性) | EmakiAttribute 属性 ID | 拥有其中任意一个属性就算满足, 与其余三个字段要同时满足 |
match | object | 否 | 无 | — | 已废弃, 不再被读取. 见从 match 迁移 |
stat_lines | map | 否 | 空 | 键为属性 ID; 子键见下 | 属性行模板定义 |
name_actions | list | 否 | 无 | 名称操作条目 | 全局名称修改操作 |
lore_actions | list | 否 | 无 | Lore 操作条目 | 全局 Lore 修改操作 |
stars | map | 否 | 空 | 键为目标星级正整数 (≤0 跳过) | 各星级阶段定义, 见星级阶段定义 |
branch_tree | object | 否 | 无 (线性配方) | — | 分支树定义. 详见分支树系统 |
condition | object | 否 | 无 | CoreLib ConditionBlock | 使用该配方的条件组 |
stat_lines.<属性 ID> 的子键:
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
template | string | 否 | "" | — | 属性行模板; 留空时使用内置默认行 |
section_id | string | 否 | "" | — | 该属性行归属的展示区段 ID; 为空时归入 strengthen.stats.secondary |
section_order | integer | 否 | 0 | ≥ 0 | 区段的排序权重; 填 0 时按区段 ID 是不是 primary 来推断 |
经济配置
yaml
economy:
enabled: true
currencies:
- provider: "vault"
currency_id: ""
base_cost: 320
cost_formula: "%base_cost% * %star%"
display_name: "<gold>金币</gold>"cost_formula 支持表达式, 你可以引用 %base_cost%, %star% 等变量
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
enabled | boolean | 否 | currencies 非空时为 true | true / false | 是否启用货币费用; 关闭时不扣除任何货币 |
currencies | list<map> | 否 | [] | — | 货币条目列表, 逐项见下 |
currencies[].provider | string | 否 | "" | 经济提供者 ID | 经济提供者标识 (如 vault) |
currencies[].currency_id | string | 否 | "" | — | 提供者内的货币 ID; 留空由提供者决定 |
currencies[].base_cost | long | 否 | 0 | ≥ 0 (负值按 0) | 基础费用, 供 cost_formula 引用 |
currencies[].cost_formula | string | 否 | %base_cost% | 表达式 | 实际费用表达式, 可引用 %base_cost%, %star% 等 |
currencies[].display_name | string | 否 | "" | — | 费用展示名 |
下面的示例按星级线性递增费用 (%star% 为目标星级):
yaml
economy:
enabled: true
currencies:
- provider: "vault"
currency_id: ""
base_cost: 100
cost_formula: "%base_cost% * %star%"
display_name: "<gold>金币</gold>"强化限制
yaml
limits:
max_star: 12
max_temper: 4
temper_chance_bonus_per_level: 5.0
success_chance_cap: 90.0| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
max_star | integer | 否 | 12 | ≥ 1 (小于 1 按 1) | 最大可强化星级; 达到后无法继续强化 |
max_temper | integer | 否 | 4 | ≥ 0 (负值按 0) | 最大锻印等级 (失败时累积, 提升下次成功率) |
temper_chance_bonus_per_level | double | 否 | 5.0 | ≥ 0 (负值按 0) | 每级锻印提供的成功率加成 (百分点) |
success_chance_cap | double | 否 | 90.0 | 0~100 (超出钳制) | 成功率上限 (含锻印加成后不超过此值) |
每个星级还可以用 economy_override.currencies 覆盖该星级的费用 (结构与顶层 economy.currencies 相同)
匹配规则
目标装备的匹配由文件顶层的四个字段决定, 四个都要满足:
yaml
slot_groups:
- "weapon"
source_patterns:
- "^emakiitem-example_item$"| 字段 | 类型 | 说明 |
|---|---|---|
source_patterns | list | 顶层的物品源条件, 按物品来源模式匹配 (正则) |
matcher | object | 通用物品匹配器, 只按组件, PDC, Lore, 变量等非物品源条件判定. 语法见 物品匹配器 |
slot_groups | list | 按装备大类分的槽位组 (weapon/armor/offhand/generic), 不是 main_hand/helmet 这类具体装备槽位 |
stats_any | list | 拥有指定属性之一 |
顶层物品源条件走 source_patterns
配方顶层没有 item_sources 字段, 物品源条件一律写既有的 source_patterns. 它是正则, 忽略大小写的部分匹配, 所以想精确绑定单一物品源, 就在两端加上 ^ 和 $ 这两个首尾定位符: "^emakiitem-example_item$". 不加定位符的 "emakiitem-example_item" 会把 emakiitem-example_item_v2 这类来源也一并命中
matcher 内部不能写物品源条件 (type: item_source / item_sources / source / sources 会被拒绝并告警)
NOTE
想要精确绑定物品 ID, 就给 source_patterns 加上首尾定位符, 免得配方泛匹配到所有武器
从 match 迁移
旧版的 match 块已不再被读取. 字段去向如下:
| 旧字段 | 现在的写法 |
|---|---|
match.source_ids | 顶层 source_patterns, 每个 ID 写成两端带 ^ / $ 的正则 ("^minecraft-diamond_sword$") |
match.lore_contains | matcher 里的 type: component + component: lore + operator: contains, 每条文本一个子条件 |
match.slot_groups | 提升为顶层 slot_groups |
match.stats_any | 提升为顶层 stats_any |
match.source_patterns | 提升为顶层 source_patterns |
match.source_types | 无法自动转换, 需手工改写为 source_patterns 或 matcher 条件 |
/emakistrengthen convert-legacy 可以自动完成转换:
| 命令 | 行为 |
|---|---|
/emakistrengthen convert-legacy | 预演, 只打印将要产生的差异, 不改文件 |
/emakistrengthen convert-legacy confirm | 实际改写 recipes/*.yml, 并为每个文件留一份 .bak 备份 |
--apply 与 confirm 等价, 命令需要 emakistrengthen.admin 权限
WARNING
含 match.source_types 的文件会被判为无法转换并跳过; 文件里同时存在 match 和已写好的 matcher (或对应顶层字段) 时会报冲突并跳过. 两种情况都需要手工处理
match.source_ids 会被自动转成两端带 ^ / $ 的正则并合并进顶层 source_patterns, 不会写进 matcher, 转换结果无需手工修正. 转换出的正则是精确匹配: 两端补上了 ^ / $ 定位符, ID 里的特殊字符也做了转义 (形如 ^\Qemakiitem-xxx\E$)
旧材料字段的规范化与拒绝条件
解析阶段材料时, 旧的标量 item 会被改写成 item_sources, 并按 material_id → id → count_key → 单一来源 → 阶段索引的顺序补出 material_id; 省略 count_key 时回退到 material_id. 如果没写身份却给了多个来源, 解析器没法安全地选出唯一身份, 就会拒绝这条材料, 且不改写原文件里的映射. 注意: 上面的行为目前只由当前 JVM 的解析代码和本地测试证明, 还没在 Paper/Folia 实机上验证旧配置或旧存档的运行结果
通用物品匹配器 (matcher)
配方里有两处 matcher: 顶层那个判定目标装备, materials[].matcher 判定强化材料. 语法一致, 但物品源条件摆放的位置不同:
| 位置 | 物品源条件写在哪 | 与 matcher 的关系 |
|---|---|---|
顶层 matcher | 顶层 source_patterns (正则) | 顶层 source_patterns, slot_groups, stats_any, matcher 四者都要成立才会命中 |
materials[].matcher | 同级 item_sources | 两者一起交给 ItemRequirement.test 判定, 取且: 来源条件和非物品源条件都必须成立; 任何一个不成立, 就不算这份材料 |
NOTE
enhancement_recipes/*.yml 的 materials[] 同样是 item_sources + matcher 同级取 AND. 过去写在 matcher 内部的物品源条件请移到同级 item_sources
完整说明见 物品匹配器
yaml
id: enchanted_sword_strengthen
# 顶层: 只有附了锋利 3 以上的钻石剑能用这条配方
# 物品源走 source_patterns (带锚点精确绑定), matcher 只写组件条件
source_patterns:
- "^minecraft-diamond_sword$"
matcher:
type: component
component: enchantments
path: sharpness
operator: '>='
value: 3
stars:
1:
materials:
# 材料: 来源和 matcher 条件统一判定, 必须同时满足
- item_sources:
- minecraft-copper_ingot
matcher:
type: component
component: custom_name
operator: absent
amount: 3WARNING
物品源用连字符 (minecraft-copper_ingot), 不是冒号. 写成 minecraft:copper_ingot 会被解析器判为无效并不报错地丢弃, 整个 item_sources 被丢空后等同于"不限来源". 详见 物品源用连字符, 组件 ID 用冒号
附魔强化配方的 target.filter
enhancement_recipes/*.yml 与 recipes/*.yml 是两套独立配方, 它的 target.filter 也认通用物品匹配器: filter 里带 type 键时按匹配器解析, 不带就按原有的 Provider 自由键值对解释
yaml
target:
provider: equipment
# 含 type 键 → 按通用物品匹配器解析
filter:
type: component
component: enchantments
operator: existsyaml
target:
provider: equipment
# 不含 type 键 → 仍按 Provider 自由键值对解释 (原有行为)
filter:
item_type: SWORD可引用的锻造品质变量
target.filter 的 variable.<变量名> 键, target 的 matcher, 以及配方 conditions, 都能引用从目标物品 PDC 读到的锻造品质变量. 这些变量来自 EmakiForge 写在物品上的 emakiforge 命名空间 PDC
| 变量 | 类型 | 物品无锻造数据时 | 说明 |
|---|---|---|---|
forge_quality_id | string | "" | 品质档位标识 |
forge_quality_display | string | "" | 品质显示名 |
forge_quality_multiplier | double | 1.0 | 品质倍率 |
forge_recipe_id | string | "" | 锻造配方 ID |
每个变量都有三种等价写法, 任选一种:
| 规范名 | 点号写法 (历史兼容) | 简短写法 |
|---|---|---|
forge_quality_id | forge.quality_id | quality_id |
forge_quality_display | forge.quality_display | quality_display |
forge_quality_multiplier | forge.quality_multiplier | quality_multiplier |
forge_recipe_id | forge.forge_recipe_id | 无 |
点号写法为何保留
Forge 的 PDC 键已从 forge.quality_id 改名为 forge_quality_id (见 PDC 键名规范). 点号写法作为历史兼容别名保留, 已写好的配置不用改. 新配置建议直接用规范名
yaml
target:
provider: equipment
filter:
# filter 是相等判定: 只命中品质档位恰为 legendary 的物品
variable.forge_quality_id: legendaryfilter 只做相等判定
filter 里的每一项都是相等比较, 不支持 >=, < 这类比较符. 数值按数值比, 其余按字符串忽略大小写比. 写 variable.forge_quality_multiplier: '>= 1.5' 不会报错, 但会拿字符串 ">= 1.5" 去和实际倍率比, 永远不命中
需要数值区间判断时, 改用 target 的 matcher (type: variable_expr) 或配方 conditions
还有一个辅助变量 forge_quality_multiplier_valid: 物品上的倍率能正常解析成有限正数时是 1, 写坏了 (非数值, 负数, NaN) 时是 0, 同时 forge_quality_multiplier 回退为 1.0. 用它就能区分"这件物品没锻造过"和"锻造数据坏了"
filter 中引用不存在的键会导致整条规则不命中
filter 里写了既不是内置键, 也不在变量表里的键名时, 该条过滤直接判为不匹配. 上表四个变量始终存在 (无锻造数据时取默认值), 因此可以安全引用
NOTE
enhancement_recipes/ 的其余字段见通用强化配方
全局名称与 Lore 修改
每次强化成功后, 这些操作都会套用到物品上, 支持 %star%, %temper%, %max_temper%, %temper_color% 等占位符
yaml
name_actions:
- action: "append_suffix"
value: " [+%star%]"
lore_actions:
- action: "prepend"
content:
- "<gradient:#F2C46D:#C9703D>强化等级 +%star%</gradient>"
- "<gray>锻印: %temper_color%%temper%/%max_temper%</gray>"星级阶段定义 (stars)
每个星级可以写这些字段:
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
name | string | 否 | "" | — | 该星级的里程碑名称 (用于 GUI 展示) |
effects | list<map> | 否 | [] | 效果条目, type 取值见效果类型 | 效果列表 (统一格式) |
materials | list<map> | 否 | [] | 材料条目见下 | 强化所需材料 |
economy_override | object | 否 | currencies: [] | currencies 结构与顶层 economy 相同 | 覆盖该星级的经济费用; 填了内容时优先用这里的, 而不是顶层 economy |
actions | object | 否 | 无 | 键为 success / failure | 强化成功/失败时执行的动作 |
材料字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
material_id | string | 否 | 按 id, count_key, 单一来源或阶段索引回退 | — | 材料选择和阶段规则用的稳定身份. 新配置建议明确写上, 免得来源或配置形态一变, 身份也跟着漂移; 声明了多个来源又没给出身份时, 这条材料会被拒绝 |
count_key | string | 否 | material_id | — | 数量聚合和消耗用的身份. 可以和 material_id 不一样; 想让多份材料共享计数时, 就明确填同一个值 |
item_sources | list | 否 | 空 (不限来源) | 物品源简写 (连字符, 如 minecraft-copper_ingot) | 允许的材料物品来源. 省略表示不限来源; 旧的标量 item 字段只在读取时改写成这个字段 |
matcher | object | 否 | 无 | CoreLib 通用匹配器 | 只写组件, PDC, Lore 等非物品源条件. 与同级 item_sources 经统一 ItemRequirement.test 取 AND; 两者都省略时这条材料永远不命中. 见 物品匹配器 |
amount | integer | 否 | 1 | -1 或 ≥ 1 | 需要数量. 设为 -1 表示不消耗, 仅检测是否持有 |
optional | boolean | 否 | false | true / false | 是否为可选材料 (不放也能强化) |
protection | boolean | 否 | false | true / false | 放入后提供保护效果, 失败时不降星 |
temper_boost | integer | 否 | 0 | ≥ 0 (负值按 0) | 放入后额外提供的锻印等级, 用于提升本次成功率 |
yaml
materials:
- material_id: "copper_ingot"
count_key: "copper_ingot"
item_sources:
- "minecraft-copper_ingot"
amount: 3
# 保护材料: 不消耗, 仅检测持有
- material_id: "protection_gold_nugget"
count_key: "protection_gold_nugget"
item_sources:
- "minecraft-gold_nugget"
amount: -1
optional: true
protection: true
# 锻印材料: 额外提供 1 级锻印加成
- item_sources:
- "minecraft-potion"
amount: -1
optional: true
temper_boost: 1效果类型
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
effects[].type | string | 是 | — | variables / ea_attribute / es_skill / lore_action / name_action | 效果类型; 不在此列的条目被忽略 |
effects[].variables | map | 否 | 无 | 属性 ID → 数值或表达式 | type: variables 时读取; 用于 Lore, 名称/Lore 模板与占位符上下文, 不会自动写入 Attribute PDC |
effects[].ea_attributes | map | 否 | 无 | 属性 ID → 数值或表达式 | type: ea_attribute 时读取; 写入 EmakiAttribute PDC 属性层 (显式覆盖) |
effects[].es_skills | list | 否 | 无 | EmakiSkills 技能 ID | type: es_skill 时读取; 技能附加 |
effects[].lore_actions | list | 否 | 无 | Lore 操作条目 | type: lore_action 时读取; 对物品 Lore 的修改 |
effects[].name_actions | list | 否 | 无 | 名称操作条目 | type: name_action 时读取; 对物品名称的修改 |
除效果列表外, 星级阶段还支持同级的直接键 variables, ea_attributes, name_action, lore_action: 它们与对应的 effects 条目是累加关系, 读取含义一致
当前效果的边界:
variables只提供文本, 占位符和动作模板上下文, 不会自动成为 Attribute PDC 属性- 想要真实属性输出, 必须显式配置
type: "ea_attribute"和ea_attributes - 技能附加用
type: "es_skill", 但具体技能 ID 要写在es_skills列表里
Lore 操作策略
强化配方的 Lore 操作按下面的策略走, 保证每种属性在 Lore 里始终只有一行:
| 场景 | 操作 | 说明 |
|---|---|---|
| ★1 首次添加 | action: "append" | 首次使用 append 添加属性行 |
| ★2+ 更新已有行 | action: "replace_line" | 通过 anchor 匹配已有行并替换为新数值 |
| 里程碑解锁新属性 | 先 replace_line 再 append | 先更新旧行, 再 append 添加新属性行 |
星级示例
yaml
stars:
# ★1: 首次添加属性行
1:
effects:
- type: "variables"
variables:
physical_attack: 4
- type: "lore_action"
lore_actions:
- action: "append"
content:
- "<gray>物理伤害: <gold>+4</gold></gray>"
materials:
- item_sources:
- "minecraft-copper_ingot"
amount: 1
- item_sources:
- "minecraft-gunpowder"
amount: 2
# ★2: 使用 replace_line 更新已有行
2:
effects:
- type: "variables"
variables:
physical_attack: 4
- type: "lore_action"
lore_actions:
- action: "replace_line"
anchor: "物理伤害:"
content:
- "<gray>物理伤害: <gold>+8</gold></gray>"
materials:
- item_sources:
- "minecraft-copper_ingot"
amount: 1
# ★6 里程碑: 解锁新属性
6:
name: "觉醒"
effects:
- type: "variables"
variables:
physical_attack: 6
physical_crit_rate: 3
- type: "ea_attribute"
ea_attributes:
physical_attack: 28.0
physical_crit_rate: 3.0
- type: "es_skill"
es_skills:
- "weapon_aura"
- type: "lore_action"
lore_actions:
# 先更新已有行
- action: "replace_line"
anchor: "物理伤害:"
content:
- "<gray>物理伤害: <gold>+28</gold></gray>"
# 再添加新属性行
- action: "append"
content:
- "<gray>暴击率: <gold>+3%</gold></gray>"
- "<yellow>★ 觉醒: 解锁武器光环</yellow>"
materials:
- item_sources:
- "minecraft-iron_ingot"
amount: 3
actions:
success:
- 'send_message text="<gold>★ 觉醒!装备提升至 +%star%!</gold>"'
- "play_sound sound=minecraft:entity.player.levelup volume=1 pitch=1.5"
failure:
- 'send_message text="<red>强化失败,装备等级下降至 +%star%。</red>"'分支配方
强化配方支持分支树系统, 装备可以在特定星级分叉成不同的强化路线. 详见 分支树系统 文档
完整示例
yaml
id: "weapon_physical"
display_name: "<gold>物理武器强化</gold>"
gui_template: "strengthen_gui"
economy:
enabled: true
currencies:
- provider: "vault"
currency_id: ""
base_cost: 320
cost_formula: "%base_cost% * %star%"
display_name: "<gold>金币</gold>"
limits:
max_star: 12
max_temper: 4
temper_chance_bonus_per_level: 5.0
success_chance_cap: 90.0
success_rates:
1: 100.0
2: 100.0
3: 95.0
4: 85.0
5: 75.0
6: 60.0
7: 45.0
8: 32.0
9: 22.0
10: 14.0
11: 8.0
12: 4.0
slot_groups:
- "weapon"
name_actions:
- action: "append_suffix"
value: " [+%star%]"
lore_actions:
- action: "prepend"
content:
- "<gradient:#F2C46D:#C9703D>强化等级 +%star%</gradient>"
- "<gray>锻印: %temper_color%%temper%/%max_temper%</gray>"
stars:
1:
effects:
- type: "variables"
variables:
physical_attack: 4
- type: "lore_action"
lore_actions:
- action: "append"
content:
- "<gray>物理伤害: <gold>+4</gold></gray>"
materials:
- item_sources:
- "minecraft-copper_ingot"
amount: 1
2:
effects:
- type: "variables"
variables:
physical_attack: 4
- type: "lore_action"
lore_actions:
- action: "replace_line"
anchor: "物理伤害:"
content:
- "<gray>物理伤害: <gold>+8</gold></gray>"
materials:
- item_sources:
- "minecraft-copper_ingot"
amount: 2enhancement_recipes 通用强化配方
enhancement_recipes/*.yml 是通用强化框架 (target / materials / costs / chance / pity / actions) 的配方, 与 recipes/*.yml 是两套独立配方. 分工是: EmakiStrengthen 管材料匹配与消耗, 货币扣费, 成功率, 保底 (连续失败到一定次数后必定成功), 重试时结果不变和出错补偿; 目标识别与等级/阶段写回交给已注册的 Target Provider
顶层字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
schema_version | integer | 否 | 1 | 1~2 (超出范围整份配方被跳过) | 材料的结构版本 |
id | string | 是 | — | — | 配方唯一 ID; 缺失或为空时整份配方被跳过 |
mode | string | 是 | — | equipment / affix / gem | 用途分组; 缺失, 为空或不在取值内时整份配方被跳过 |
target | object | 是 | — | 见 target | 目标配置; provider 为空时整份配方被跳过 |
materials | list<map> | 否 | [] | 见 materials[] | 材料槽列表; 单个槽解析失败会使整份配方被跳过 |
costs | list<map> | 否 | [] | 见 costs[] | 货币消耗列表; 单个条目解析失败会使整份配方被跳过 |
chance | number | object | 否 | 1.0 | 0~1 概率; 或 CoreLib Quantity (fixed / formula / lookup_table) | 成功率; 非法配置会使整份配方被跳过 |
pity | object | 否 | 无 | 见 pity | 单轨保底; 存在但非法 (缺 group 等) 会使整份配方被跳过 |
pity_tracks | list<map> | 否 | [] | 见 pity | 多轨保底; 单条非法会使整份配方被跳过 |
condition | object | 否 | 无 | CoreLib ConditionBlock | 进入条件; 在 prepare() 内求值, 预览与正式强化同时生效 |
actions | map | 否 | {} | 键名自由的 CoreLib 动作行列表 | 结算后按结果阶段触发的动作分组 (如 on_success / on_failure) |
target
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
provider | string | 是 | — | 已注册 Target Provider ID (内置 equipment / affix / gem) | 目标提供者; 为空时整份配方被跳过 |
filter | map | 否 | 无 | 含 type 键时按通用物品匹配器解析; 否则按 Provider 自由键值对 | 目标过滤, 含义见附魔强化配方的 target.filter |
materials[]
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
item_sources | list | 否 | 空 (不限来源) | 物品源简写 | 与同级的 matcher 取 AND (同时满足); 两者都省略时这个槽会失败 |
matcher | object | 否 | 无 | CoreLib 匹配器 | 组件, PDC, Lore 等非物品源条件 |
quantity | number | object | 否 | 1 | CoreLib Quantity | 需求数量 |
consume | string | 否 | always | always / success / failure / never | 消耗时机; 非法值按 always |
required | boolean | 否 | true | true / false | false 时缺料不阻断 (等价 optional: true) |
optional | boolean | 否 | 无 | true / false | required 的反向写法; 与 required 同时出现时 optional 生效 |
material_id | string | 否 | 依次取 count_key, 来源身份, 条件身份 | — | 规则与选择身份 |
count_key | string | 否 | material_id | — | 数量聚合和消耗用的身份 |
target_compare | string | 否 | 空 (不做比较) | same_affix / same_affix_set / same_item_type / same_level / level_at_least | 把该槽材料与当前目标比较; 非法值按不比较 |
costs[]
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
provider | string | 否 | "" | 经济提供者 ID | 经济提供者标识 |
currency_id | string | 是 | — | — | 货币 ID; 可用别名 currency. 为空时该条目解析失败, 并因条目数不一致使整份配方被跳过 |
amount | number | object | 否 | Quantity 默认 | CoreLib Quantity | 费用数额 |
pity / pity_tracks[]
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
scope | string | 否 | item | item / player | 计数范围; 非法值按 item |
group | string | 是 | — | — | 计数器分组; 为空时整段 pity 被丢弃 |
threshold | integer | 否 | 10 | ≥ 1 (≤0 使整段被丢弃) | 触发阈值; 与 formula 二选一 |
formula | object | 否 | 无 | CoreLib Quantity | 触发条件表达式; 与 threshold 二选一 |
effect | string | 否 | force_success | force_success / chance_bonus | 保底效果; 非法值按 force_success |
bonus_value | double | 否 | 无 | chance_bonus 时必填且 > 0 | chance_bonus 的加成值; 非有限值使整段被丢弃 |
decay.type | string | 否 | reset | reset / fixed_decay / proportional | 计数衰减方式; 非法值按 reset, 值域越界使整段被丢弃 |
decay.value | double | 否 | 0.0 | fixed_decay ≥ 0; proportional 0~1 | 衰减量 |
isolate | list | 否 | 空 | recipe / mode / target / affix / level | 把这条 track 的计数按维度分组存放; 写入未知或重复的维度会使这份配方加载失败 |
pity 与 pity_tracks 会合并成同一份轨道列表; scope + group 相同的轨道会被静默去重, 保留先出现的那条
下面是自带示例 (enhancement_recipes/example_enhancement_recipe.yml 节选):
yaml
schema_version: 2
id: example_equipment_enhance
mode: equipment
target:
provider: equipment
filter:
item_type: SWORD
materials:
- item_sources:
- "minecraft-diamond"
quantity: 2
consume: always
- matcher:
type: pdc_match
key: "emakiitem:item_type"
value: "enhance_stone"
quantity:
type: formula
expression: "1 + floor(target.level / 5)"
consume: success
costs:
- provider: vault
currency_id: money
amount:
type: formula
expression: "100 * (target.level + 1)"
chance:
type: formula
expression: "max(0.05, 0.9 - target.level * 0.05)"
pity:
scope: item
group: example_equipment_enhance
threshold: 10
effect: force_success
decay:
type: reset
value: 0
actions:
on_success:
- "sound: ITEM_TOTEM_USE"
on_failure:
- "sound: BLOCK_ANVIL_USE"