简体中文
配方系统
一份配方文件里能写哪些字段, 以及它们分别怎么管锻造的输入, 条件, 结果和动作
一份配方定义一次锻造要放什么, 怎么判定, 消耗什么, 产出什么, 以及成功或失败后执行哪些动作. 你把配方文件放进 recipes/*.yml, 配方的 ID 取自文件里的 id, 和文件名无关; 同一目录里 id 重复时, 后一个会被拒绝加载
根字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
id | string | 是 | — | 非空字符串 | 配方的唯一 ID. 留空时这个文件被跳过并报 BLANK_ID |
display_name | string | 否 | id | MiniMessage 文本 | 配方显示出来的名字, 用在配方书和锻造界面的标题上 |
gui_template | string | 否 | 空 | gui/ 下的模板 id, 如 forge_gui | 这个配方使用的界面模板. 留空时用内置的 forge_gui |
blueprint_requirements | list<object> | 否 | 空列表 | — | 图纸要求清单, 只检查玩家是否持有, 不消耗. 每一项的字段见图纸与材料 |
materials | list<object> | 否 | 空列表 | — | 材料清单. 每一项的字段见图纸与材料 |
forge_capacity | integer | 否 | 0 | >= 0 (负值截断为 0) | 锻造容量上限, 限制投入材料的 capacity_cost 总和. 为 0 时界面显示成"等待图纸" |
optional_material_limit | integer | 否 | 0 | >= 0 (负值截断为 0) | 一次锻造最多能放几种可选材料 |
condition | object | 否 | all_of / 0 / 空 | — | 条件组, 见条件节点 |
quality | object | 否 | 关闭 | — | 配方自己的品质配置, 用来覆盖全局品质设置. 全部键见品质系统 |
result | object | 否 | 空 | — | 结果定义, 见结果定义 |
actions | object | 否 | 空 | — | 流程动作, 见动作节点 |
permission | string | 否 | 空 | 权限节点字符串 | 使用这个配方需要的权限. 留空表示不检查权限 |
success_rate | number | 否 | 100 | 0 ~ 100 (超范围截断) | 锻造成功率, 用百分比表示. 低于 100 时按概率失败, 并启用 failure_outcomes |
failure_outcomes | list<object> | 否 | 空列表 | — | 失败时怎么处理材料. 只有在 success_rate < 100 时才会用到 |
发货默认值: 随模块发布的 recipes/example_recipe.yml 即一份完整示例 (含图纸需求, 7 种材料, 品质, 结果与动作). 可复制的最小配方:
yaml
id: flame_sword
display_name: '<red>烈焰剑锻造'
blueprint_requirements:
- item_sources:
- "minecraft-paper"
amount: 1
materials:
- item_sources:
- "minecraft-blaze_rod"
amount: 3
capacity_cost: 5
forge_capacity: 10
optional_material_limit: 2
result:
success:
outputs:
- item_source: "minecraft-diamond_sword"条件节点
condition 由 CoreLib 条件组解析, 支持五种组合方式:
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
condition.type | string | 否 | all_of | all_of / any_of / none_of / at_least / exactly | 条件的组合方式. 写其他值这个配方会被拒绝加载并报 INVALID_CONDITION_MODE |
condition.required_count | integer | 否 | 0 | >= 0 (负值截断为 0) | at_least (至少 N 条成立) 和 exactly (恰好 N 条成立) 拿它当基准; 其他组合方式会忽略它 |
condition.entries | list | 否 | 空列表 | — | 条件条目清单. 每一项是一个 CoreLib 条件表达式, 或者一个嵌套的条件组 |
yaml
condition:
type: at_least
required_count: 2
entries:
- "level >= 30"
- "permission: blacksmith"
- "world: world_nether"WARNING
CoreLib 条件块还支持 condition.invalid_as_failure, condition.on_pass.actions, condition.on_fail.actions, condition.on_fail.block_output, condition.on_fail.message 这些键, 但 Forge 的锻造流程只读 type / required_count / entries: 写错的条件算不算失败, 由全局 config.yml 里的 condition.invalid_as_failure 统一控制, on_pass / on_fail 不参与锻造判定. 写在配方里不会生效
你可以在配方里用 permission 和 condition 一起限制使用者, 例如"只有铁匠职业能用""等级达到 30""必须拥有某个 PDC 标记"
结果定义
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
result.success.outputs | list<object> | 否 | 空列表 | — | 锻造成功时的产出物品清单, Forge 只拿第一项当主产物. 为空时, 这个配方需要界面提供目标物品槽 (requiresTargetInput()), 否则无法生成结果 |
result.success.outputs[].item_source | string | 是 (该产出项存在时) | — | 单值物品源 | 产出物品的来源. 只能写一个值; 写成列表会报 OUTPUT_SOURCE_NOT_SINGLE, 省略会报 OUTPUT_SOURCE_MISSING |
result.success.outputs[].item_sources | list | 否 | — | 恰好 1 个合法来源 | 旧写法, 兼容读取并打 WARNING (OUTPUT_LEGACY_SOURCE). 和 item_source 同时出现会报 OUTPUT_SOURCE_FIELD_CONFLICT |
result.success.outputs[].matcher | — | 否 | — | 不允许 | 产出项不允许写 matcher, 写了会报 OUTPUT_MATCHER_FORBIDDEN |
result.success.outputs[].amount | integer | 否 | 忽略 | — | 现在的实现不读这个键, 主产物固定按数量 1 生成; 写错也不会报错, 更不会生效 |
result.success.actions | list<string> | 否 | 空列表 | CoreLib 动作行 | 结果生成之后执行的动作 |
result.success.name_actions | list<object> | 否 | 空列表 | CoreLib 名称动作 | 对结果物品名称执行的动作链 |
result.success.lore_actions | list<object> | 否 | 空列表 | CoreLib Lore 动作 | 对结果物品 Lore 执行的动作链 |
配上 result.success.outputs 的物品来源后, 锻造成功时会生成其中第一项作为主产物, 并给它附上锻造层快照. 你可以用它把材料合成成新武器, 用图纸制造固定装备, 或产出 EmakiItem 与外部插件的物品
yaml
result:
success:
outputs:
- item_source: "minecraft-diamond_sword"
name_actions:
- action: "append_suffix"
value: " <gray>[%quality_name%]</gray>"
lore_actions:
- action: "append"
content:
- ""
- "<gray>锻造品质: <white>%quality_name%</white></gray>"
- "<gray>品质倍率: <white>%quality_multiplier%</white></gray>"IMPORTANT
内置 forge_gui 模板只提供图纸槽和材料槽, 不提供目标装备输入槽. 用内置界面时必须配置 result.success.outputs, 否则无法生成锻造结果
配方结果动作, 材料效果动作和品质 item_meta 动作会合并到一起, 统一应用到结果物品上
成功率与失败结果
success_rate 默认 100, 表示必定成功. 你设成低于 100 的值后, 锻造就有概率失败, 这时按 failure_outcomes 里的 weight 加权随机挑一个方案
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
failure_outcomes[].type | string | 否 | return_materials | return_materials / partial_consume / consume_materials (其他值不报错但按全额返还处理) | 失败时怎么处理材料 |
failure_outcomes[].weight | integer | 否 | 1 | >= 1 (小于 1 提升为 1) | 这个方案的选取权重 |
failure_outcomes[].params | object | 否 | 空对象 | — | 方案的参数表, 具体读哪些键取决于 type; 没写的键用源码里的默认值 |
failure_outcomes[].params.return_rate | number | 否 | return_materials 为 1.0; partial_consume 为 0.5 | 0 ~ 1 | 返还比例. 只有 return_materials 和 partial_consume 这两个 type 会读它 |
yaml
success_rate: 70
failure_outcomes:
- type: "return_materials"
weight: 50
params:
return_rate: 1.0
- type: "partial_consume"
weight: 30
params:
return_rate: 0.5
- type: "consume_materials"
weight: 20NOTE
没有配置 failure_outcomes 时, 默认按 return_materials 全额返还. 填了其他 type 不会报错, 但一样按全额返还材料处理
品质配置
品质系统的完整说明见品质系统. 配方里常见写法是这样:
yaml
quality:
enabled: true
custom_pool:
- "普通-70-1.0"
- "精良-25-1.05"
- "史诗-5-1.15"
guarantee:
enabled: true
attempts: 10
minimum: 精良NOTE
配方自己的品质池字段是 custom_pool, 保底的阈值字段是 attempts; 全局 config.yml 里对应的字段分别叫 tiers 和 threshold. custom_pool 用 "品质名-权重-倍率" 这种字符串写法, 留空时用全局品质池
建议:
- 你让普通品质权重大, 稀有品质权重小
- 高价值配方给个保底, 免得玩家长期抽不到好东西
- 品质的名字要和展示, 属性, 动作里的配置对得上
动作节点
| 节点 | 类型 | 触发时机 |
|---|---|---|
actions.pre | list<string> | 配方开始执行之前. 如果 pre 阶段动作失败, 锻造会中止并触发 failure |
actions.success | list<string> | 锻造成功后 |
actions.failure | list<string> | 锻造失败后 |
result.success.actions | list<string> | 结果物品生成或应用时, 在 actions.success 之前触发 |
你加载配方时, actions.pre, result.success.actions, actions.success, actions.failure 四条动作链都会先用 CoreLib 动作引擎试编译一遍. 任何一行编译失败, 这个配方就会被拒绝加载并报 INVALID_ACTION_LINE
成功时按 result.success.actions → actions.success → 品质动作的顺序执行. 每个动作列表内部一条条按顺序执行, 下一阶段会等上一阶段全部做完再开始. 三个阶段全部结束后, Forge 才从可变的 item_target holder 里读出最终物品并交付, 所以 Item component 动作可以安全地修改锻造结果, 不会出现动作还没做完就提前把旧物品发出去的情况. 动作批次失败只记一条警告, 已经生成的锻造结果不会被吞掉
yaml
actions:
pre:
- 'send_message text="<gray>锻造开始……"'
success:
- 'send_title title="<green>锻造成功" subtitle="<gray>你的装备已被重铸"'
- 'play_sound sound=BLOCK_ANVIL_USE volume=1 pitch=1'
failure:
- 'send_message text="<red>锻造失败,材料已损毁。"'
- 'play_sound sound=ENTITY_VILLAGER_NO volume=1 pitch=1'NOTE
actions.pre 失败时, 错误消息里可以用这几个变量: %reason%, %action%, %line%
可用模板变量
result.success.name_actions 的 value 与 result.success.lore_actions 的 content 里可以用:
| 变量 | 说明 |
|---|---|
%quality% | 品质名. 只有在品质档位解析成功时才会注入 |
%quality_name% | 品质显示名, 与 %quality% 取值相同 |
%quality_multiplier% | 品质倍率, 按 0.## 格式化 |
%multiplier% | 品质倍率的简写别名 |
%变量名% | 材料效果注入的变量值 |
完整的变量清单 (含材料效果和界面变量) 见占位符参考
最小示例
yaml
id: flame_sword
display_name: '<red>烈焰剑锻造'
permission: emakiforge.recipe.flame_sword
blueprint_requirements:
- item_sources:
- "minecraft-paper"
amount: 1
materials:
- item_sources:
- "minecraft-blaze_rod"
amount: 3
capacity_cost: 5
forge_capacity: 10
optional_material_limit: 2
condition:
type: all_of
entries: []
quality:
enabled: true
custom_pool:
- "普通-80-1.0"
- "精良-20-1.05"
result:
success:
outputs:
- item_source: "minecraft-diamond_sword"
name_actions:
- action: "append_suffix"
value: " <gray>[%quality_name%]</gray>"
lore_actions:
- action: "append"
content:
- ""
- "<gray>锻造品质: <white>%quality_name%</white></gray>"
actions:
success:
- 'send_message text="<green>烈焰力量被注入武器。"'