Skip to main content

让配方自动生成价值

这篇文档对应的使用场景是:

  • 你不想给每个物品都手写价格
  • 你想让模组按照配方自动推导大部分物品的价值
  • 你已经给一部分原材料设了基础值,准备让中间产物和成品自动延伸

配方生成价值的核心思路

当某个物品没有固定基础价值,但存在可以产出它的已处理配方时,模组会尝试为它生成价值。

默认思路非常直接:

输入值总和,决定输出值。

但真正实现时,还有几条容易被忽略的细则。

默认规则

1. 先看输入原料的价值总和

配方中的每个输入 Ingredient 都会先尝试求值。

如果一个 Ingredient 能匹配多个物品,模组会取其中价值最低的那个结果。

这意味着它天然偏向“最便宜可行成本”。

2. 同一物品有多条配方时,取最小值

如果一个物品能通过多种方式合成,模组会保留其中成本最低的结果。

例如:

  • 方案 A 的总成本是 64
  • 方案 B 的总成本是 16

那么最终生成值会采用 16。

3. 输出数量大于 1 时自动平摊

如果一个配方产出多个相同物品,模组会把总价值除以产出数量。

例如:

  • 金锭价值 648
  • 1 金锭可产出 9 金粒
  • 每个金粒的生成价值会是 72

4. 有原料无价值时,该配方无法生成有效结果

只要某个必要输入没有可用价值,整条配方就无法生成稳定价值。

所以想让配方推导跑起来,最重要的是先把上游原料锚定好。

默认支持哪些配方类型

源码中默认注册了以下配方类型:

  • crafting
  • smelting
  • blasting
  • smoking

也就是说,原版常见的工作台与几类炉类配方,开箱就会参与价值推导。

推荐的实际使用方式

场景一:只给原材料定价

这是最推荐的方式。

例如你只手动定义:

  • 铁锭
  • 金锭
  • 铜锭
  • 钻石
  • 煤炭
  • 红石

然后把各种板材、零件、压块、半成品、机器外壳、基础工具都交给配方自动推导。

优点是:

  • 工作量低
  • 逻辑统一
  • 改动上游材料后,下游价格会自动重新传播

场景二:只手动修正少数例外物品

有些物品的配方虽然能算,但结果不符合整合包预期。

这时不需要放弃自动推导,只要单独给这些例外物品设置基础值即可。

因为基础价值优先级更高,所以它会覆盖自动生成值。

场景三:让跨模组共用统一材料成本

如果多个模组共用 Forge 标签,例如铜锭、锡锭、铅锭等,你只需要按标签定义一次基础值,后面的配方推导就会自然统一。

一个典型例子

OEVEvents.addItemValue(event => {
event.addBaseItemValue('#forge:ingots/iron', 256)
event.addBaseItemValue('#forge:ingots/gold', 648)
event.addBaseItemValue('#forge:dusts/redstone', 64)
event.addBaseItemValue('#forge:gems/diamond', 8192)
})

如果某个模组里有下面这些配方:

  • 4 铁锭 + 2 红石 = 基础机器框架
  • 1 基础机器框架 + 2 金锭 = 高级部件

那么这些中间物品就可以自动得到价值,而你不需要一个个写死。

为什么有些物品推不出来

常见原因主要有四类。

1. 上游原料没有基础值

这是最常见的原因。

如果最底层材料就没有值,整条链都没法往上推。

2. 该配方类型没有被处理

如果某个模组注册了自定义 RecipeType,而你没有给它添加处理器,那么这类配方就不会参与计算。

3. 配方输出不是默认单产物形式

默认输出获取逻辑只处理标准的单结果输出。

如果某些配方类型有多输出、动态输出或特殊容器输出,往往需要自定义处理器。

4. 配方图里存在复杂循环

模组内部会在依赖图中反复传播更低成本的结果,也带了熔断保护。

如果配方设计过于复杂或互相绕圈,最终可能不会得到你预期的自动结果,这时就该为关键节点手动设基础值,或者写自定义规则。

自动推导和基础值的关系

这部分非常关键。

最终合并时,模组会先放入配方生成值,再放入基础值。

这意味着:

  • 配方生成值适合做“补充覆盖面”
  • 基础值适合做“最终锚点”

如果你觉得一个物品的自动推导结果不合理,最简单直接的修正方式不是改整条链,而是给它手动定一个基础值。

什么时候该继续用默认自动推导

适合继续使用默认逻辑的情况:

  • 配方是标准输入求和
  • 配方只有一个正常输出
  • 原料成本基本就等于产物成本
  • 你只关心“最低可得成本”

什么时候该改成自定义处理

不适合默认逻辑的情况:

  • 有多个输出,需要手动分配每个产物价值
  • 某类工序需要额外成本,例如燃料、催化剂、损耗
  • 配方输入或输出格式特殊
  • 你希望按固定倍率、固定损耗或别的规则计算