Skip to content

配方定义

合成配方放在 plugins/EmakiStation/recipes/ 下。一个文件一条配方,文件名不参与识别,配方 id 取文件内的 id 字段。

匹配方式是无序集合匹配:只看材料种类和总数,不看摆放位置,没有 shaped 概念。

完整示例

yaml
id: "iron_ingot_block"
display_name: "<white>铁块压制</white>"

station_ids:
  - "blacksmith"

tags:
  - "blacksmith"

permission: ""
visible: true
duration_seconds: 30

cost:
  currency:
    type: "vault"
    amount: 0

materials:
  - item_sources:
      - "minecraft-iron_ingot"
    amount: 9
    consume: true

result:
  outputs:
    - item_source: "minecraft-iron_block"
      amount: 1
  actions: []

condition:
  invalid_as_failure: true
  entries: []

display_condition:
  invalid_as_failure: false
  entries: []

actions:
  pre: []
  success: []
  failure: []

字段

字段说明
id配方 id。
display_name显示名,支持 MiniMessage。
station_ids声明此配方属于哪些工作站。留空表示对所有工作站开放。
tags仍可用于其他用途(如 API 查询),但不再驱动工作站归属逻辑
permission使用该配方需要的权限,留空表示不限制。
visible是否出现在配方目录里。false 表示彻底不显示,通常配合 API 提交使用。
duration_seconds单次合成耗时(秒)。填 0 或省略表示立即完成,不进队列。
cost每次合成额外收取的货币,按倍率乘算。
materials材料需求列表。
result.outputs产物列表。
result.actions结算后执行的动作行。
condition提交前的条件门。
display_condition解锁条件。
actions各阶段动作行:presuccessfailure

工作站文件的 recipes 段(include_tags / include_ids / exclude_ids)已废弃,归属关系现在由配方侧的 station_ids 声明。

没有 permission 对应权限时,配方不出现在目录里,不是显示为灰色。

cost 货币成本

字段说明
cost.currency.typevaultexcellentexcellenteconomy 等价)。填其他值会报错并按不收费处理。
cost.currency.amount金额。省略或为 0 表示不收费;负数会报错并按不收费处理。

WARNING

typeamount 必须写在 cost.currency 子节里,不能直接挂在 cost 下。缺少 currency 子节时插件不报错,直接按不收费处理,配置会静默失效。

余额在扣材料之前先校验,扣款在扣材料之后执行;扣款失败会把材料原额退回。取消队列条目时按工作站的 cancel_refund_rate 折算退还。

materials 材料需求

字段说明
material_id可选。材料选择身份;省略时按 recipe_id.material.<index> 派生。配方内与 requirement_id 重复会阻塞该配方加载。
requirement_id可选。需求记录身份;省略时回退到 material_id
count_key可选。数量聚合/消费记录身份;省略时回退到 material_id
item_sources「任意其一」集合,数量按集合内总数计算。省略表示不限来源。
matcher可选。通用物品匹配器,只写组件、PDC、Lore 等非物品源条件,与同级 item_sources 取 AND。见 物品匹配器。注意下方的仓库通道限制。
amount需要的总数。
consumefalse 表示只校验持有、不扣除,用于「需要工具在手」这类需求。

需要 64 个时,30 个 coal 加 34 个 charcoal 也算满足。

单个配方的材料种类数不受 GUI 槽位数限制。仓库通道按 long 直扣,背包通道受原版每格 64 上限约束。

材料分配是贪心的,没有回溯。当同一个物品能满足多条需求时,会分配给先声明的那一条。极少数情况下这会让一个理论可行的配方匹配失败,拆分配方即可规避。

通用物品匹配器(matcher)

materials[] 的判定由 item_sourcesmatcher 两个同级并行字段合成,取 AND:item_sources 只写允许的物品源,matcher 只写组件、PDC、Lore 等非物品源条件。两者都省略时该材料永不命中。完整语法见 物品匹配器

yaml
materials:
  # 铁锭,且没被重命名过
  - item_sources:
      - minecraft-iron_ingot
    matcher:
      type: component
      component: custom_name
      operator: absent
    amount: 9
    consume: true

WARNING

matcher 内部不能写物品源条件。type: item_source / item_sources / source / sources 会被解析器拒绝并告警,该 matcher 恒不匹配。

声明了 matcher 的材料只能从背包供料

凡是声明了 matcher 的材料,都只能从背包供料,仓库检索会跳过它。 原因是仓库只按物品源统计库存,看不到真实物品的组件,无法证明组件条件成立。

加载期会为这类材料打一次 storage_unreachable_material WARN,看到该提示即为此原因,不是配置错误。

需要走仓库供料的材料请只写 item_sources、不写 matcher

此外,一条配方里只要出现任意一个 matcher,整条配方的扣料就切换到栈模型:同一配方里其他只写 item_sources 的材料也一并改为背包扣料。

分解配方(recipes_dismantle/*.yml 的顶层 item_sources + matcher)没有这个限制。

两种条件门的区别

决定什么不满足时的表现
condition能不能做配方照常显示,点了会被拒绝。
display_condition解锁没有配方显示为灰色占位,点击无反应。

用灰色占位而不是隐藏,是为了让玩家知道后面还有内容。想彻底隐藏请用 visible: falsepermission

display_condition 会在每次绘制目录页时求值,写得太重会拖慢界面。