配方系统
配方按工位类型分别存放在 recipes/ 的子目录中,每个配方一个 YAML 文件。四种工位的配方格式各不相同,下面逐一说明。
砧板配方 (Chopping Board)
存放路径:recipes/chopping_board/
yaml
# recipes/chopping_board/cut_carrot.yml
schema_version: 1
id: "cut_carrot"
display_name: "切胡萝卜"
# 输入物品
input:
source: "minecraft-carrot"
# 需要切割的次数
cuts_required: 3
# 每次切割对工具造成的耐久损耗
tool_damage: 1
# 使用此配方所需的权限(可选)
permission: ""
# 切割结果
result:
# 产出物品列表
outputs:
- source: "minecraft-golden_carrot"
amount: 1
- source: "minecraft-carrot"
amount_range:
min: 1
max: 3
chance: 50
# 完成时执行的动作列表(可选)
actions:
- "playsound sound=block.wood.break volume=1.0 pitch=1.2"
# 覆盖全局 cut_damage 设置(可选)
damage_override:
chance: 20
value: 1字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
schema_version | int | 是 | 固定为 1 |
id | string | 是 | 配方唯一标识 |
display_name | string | 是 | 显示名称 |
input.source | string | 是 | 输入物品来源 |
cuts_required | int | 是 | 需要切割的次数 |
tool_damage | int | 否 | 每次切割的工具耐久损耗(默认 1) |
permission | string | 否 | 使用权限 |
result.outputs | list | 是 | 产出物品列表 |
result.actions | list | 否 | 完成时执行的动作 |
damage_override | object | 否 | 覆盖全局 cut_damage 设置 |
炒锅配方 (Wok)
存放路径:recipes/wok/
炒锅配方是四种配方中最复杂的,因为它涉及食材顺序、翻炒规则、火力要求,以及四个结果分支。
yaml
# recipes/wok/simple_stew.yml
schema_version: 1
id: "simple_stew"
display_name: "简易炖菜"
# 食材列表(顺序敏感)
ingredients:
- source: "minecraft-beef"
amount: 2
stir_rule: ">=3" # 翻炒规则:每个食材至少翻炒 3 次
- source: "minecraft-carrot"
amount: 1
stir_rule: ">=2"
# 要求的火力等级(0 表示不限)
heat_level: 1
# 总翻炒次数范围
stir_total:
min: 5
max: 15
# 容错次数 —— 允许多少个食材的 stir_rule 不满足仍判定为成功
fault_tolerance: 0
# 使用权限(可选)
permission: ""
# 结果分支
result:
# 成功
success:
outputs:
- source: "minecraft-mushroom_stew"
amount: 1
actions:
- "playsound sound=entity.player.burp volume=1.0 pitch=1.0"
- "sendmessage message=<green>美味的炖菜出锅了!"
# 欠火候(翻炒不足)
undercooked:
outputs:
- source: "minecraft-suspicious_stew"
amount: 1
actions:
- "sendmessage message=<yellow>似乎还没炒熟..."
# 过火(翻炒过多或超时)
overcooked:
outputs:
- source: "minecraft-charcoal"
amount: 1
actions:
- "sendmessage message=<red>烧焦了!"
# 无效(随机失败或完全不匹配)
invalid:
outputs:
- source: "minecraft-charcoal"
amount: 1字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
ingredients | list | 是 | 食材列表,顺序敏感 |
ingredients[].source | string | 是 | 食材物品来源 |
ingredients[].amount | int | 是 | 食材数量 |
ingredients[].stir_rule | string | 否 | 翻炒规则表达式(如 >=3、==5、<=10) |
heat_level | int | 否 | 要求的火力等级(0 = 不限) |
stir_total.min | int | 否 | 最小总翻炒次数 |
stir_total.max | int | 否 | 最大总翻炒次数 |
fault_tolerance | int | 否 | 允许不满足 stir_rule 的食材数量(默认 0) |
result.success | object | 是 | 成功分支 |
result.undercooked | object | 否 | 欠火候分支 |
result.overcooked | object | 否 | 过火分支 |
result.invalid | object | 否 | 无效分支(未配置时使用全局 invalid_result_source) |
结果判定逻辑
出锅时,系统按以下顺序判定走哪个分支:
1. 超时检查 → 超过 timeout_ms 未翻炒 → overcooked
2. 总翻炒次数 < stir_total.min → undercooked
3. 总翻炒次数 > stir_total.max → overcooked
4. 随机失败检查 → failure.chance% 概率 → invalid
5. 逐食材检查 stir_rule:
- 不满足数 <= fault_tolerance → success
- 过多 > 不足 → overcooked
- 不足 > 过多 → undercooked
- 相等 → invalid注意判定是有优先级的:超时最先检查,然后是总翻炒次数范围,再是随机失败,最后才逐食材检查。fault_tolerance 可以让配方更宽容——比如设为 1 表示允许一个食材的翻炒次数不达标也算成功。
研磨机配方 (Grinder)
存放路径:recipes/grinder/
研磨机配方比较简单:一个输入、一个时间、一组产出。
yaml
# recipes/grinder/bone_meal.yml
schema_version: 1
id: "bone_meal"
display_name: "骨粉研磨"
# 输入物品
input:
source: "minecraft-bone"
# 研磨时间(秒)
grind_time_seconds: 5
# 使用权限(可选)
permission: ""
# 研磨结果
result:
outputs:
- source: "minecraft-bone_meal"
amount: 3
- source: "minecraft-bone_meal"
amount: 1
chance: 30
actions:
- "playsound sound=block.grindstone.use volume=1.0 pitch=0.8"字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
schema_version | int | 是 | 固定为 1 |
id | string | 是 | 配方唯一标识 |
display_name | string | 是 | 显示名称 |
input.source | string | 是 | 输入物品来源 |
grind_time_seconds | int | 是 | 研磨时间(秒) |
permission | string | 否 | 使用权限 |
result.outputs | list | 是 | 产出物品列表 |
result.actions | list | 否 | 完成时执行的动作 |
蒸锅配方 (Steamer)
存放路径:recipes/steamer/
蒸锅配方和其他工位有一个关键区别:它的 result 用的是 output(单数),而不是 outputs(复数列表)。这是因为蒸锅的每个 GUI 槽位只对应一个食材,每个食材独立匹配配方、独立产出。
yaml
# recipes/steamer/steamed_cod.yml
schema_version: 1
id: "steamed_cod"
display_name: "清蒸鳕鱼"
# 输入物品
input:
source: "minecraft-cod"
# 需要的蒸汽总量
required_steam: 100
# 使用权限(可选)
permission: ""
# 蒸制结果
result:
output:
source: "minecraft-cooked_cod"
amount: 1
actions:
- "playsound sound=block.fire.extinguish volume=0.5 pitch=1.5"字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
schema_version | int | 是 | 固定为 1 |
id | string | 是 | 配方唯一标识 |
display_name | string | 是 | 显示名称 |
input.source | string | 是 | 输入物品来源 |
required_steam | int | 是 | 需要的蒸汽总量 |
permission | string | 否 | 使用权限 |
result.output | object | 是 | 产出物品(单个) |
信息
蒸锅配方的 result 使用 output(单数),而非其他工位的 outputs(复数列表)。这是设计上的区别:蒸锅每个槽位独立烹饪,一个食材对应一个产出。
默认配方一览
| 配方 ID | 工位 | 输入 | 产出 | 说明 |
|---|---|---|---|---|
cut_carrot | 砧板 | 胡萝卜 | 金胡萝卜 | 切割 3 次 |
bone_meal | 研磨机 | 骨头 | 骨粉 ×3 | 研磨 5 秒 |
simple_stew | 炒锅 | 牛肉 ×2 + 胡萝卜 ×1 | 蘑菇煲 | 需要火力 1 |
steamed_cod | 蒸锅 | 鳕鱼 | 熟鳕鱼 | 需要 100 蒸汽 |
物品来源格式规则
所有配方中的 source 字段使用 CoreLib 的物品来源简写格式:
{provider}-{identifier}| 来源类型 | 格式示例 | 说明 |
|---|---|---|
| 原版 | minecraft-diamond_sword | Minecraft 原版物品 |
| CraftEngine | craftengine-my_namespace:my_item | CraftEngine 自定义物品 |
| MMOItems | mmoitems-SWORD:FIRE_BLADE | MMOItems 物品 |
| ItemsAdder | itemsadder-custom_food | ItemsAdder 物品 |
| NeigeItems | neigeitems-my_item | NeigeItems 物品 |
注意
物品来源使用 - 分隔符而非 :。写成 minecraft-diamond_sword,而不是 minecraft:diamond_sword。这是 CoreLib 的统一约定,所有 Emaki 模块都遵循这个格式。