BuildCraft 配方体系:4 个配方管理器 + 30 个本仓调用点 + GTNH 短路边界

事实基准:/Users/evlos/a/mirror/BuildCraft(master,minecraftVersion = 1.7.10)逐行读源码。 不逐条抄配方表,只写清体系、类别、数量分布与关键配方族。

⚠ 头号事实:GTNH 上这 6 个 loadRecipes() 全部直接 return

BuildCraftCore.java:293 定义标志位,BuildCraftCore.java:495 赋值:

public static boolean GTNH = false;                 // :293
GTNH = Loader.isModLoaded("dreamcraft");            // :495

6 个 loadRecipes() 的第一行都是同一个早退:

模块 早退位置 原文
BuildCraft|Core BuildCraftCore.java:843 if (GTNH) return;
BuildCraft|Factory BuildCraftFactory.java:215 if (GTNH) return;
BuildCraft|Silicon BuildCraftSilicon.java:200 if (GTNH) return;
BuildCraft|Builders BuildCraftBuilders.java:659 if (GTNH) return;
BuildCraft|Energy BuildCraftEnergy.java:510 if (GTNH) return;
BuildCraft|Robotics BuildCraftRobotics.java:518 if (GTNH) return;

在装了 DreamCraft(即 GTNH)的环境下,这 6 处全部一条配方都不注册。

⚠ 这是「数值取自错误来源」的典型陷阱: 只数 addCraftingRecipe 调用点会得到 48,但那是「源码里写了多少」, 不是「GTNH 上实际注册多少」——后者是 0。

BuildCraft|Transport 是反向守卫(BuildCraftTransport.java:728):

public void loadRecipes() {
    if (!GTNH) {          // :728  ← GTNH 上反而跳过
        GameRegistry.addShapelessRecipe(new ItemStack(pipeWaterproof, 1), new ItemStack(Items.dye, 1, 2));
        if (additionalWaterproofingRecipe) {
            GameRegistry.addShapelessRecipe(new ItemStack(pipeWaterproof, 1), new ItemStack(Items.slime_ball));
        }
    }
}

即 Transport 的「防水管道」配方只在非 GTNH 环境注册。

配方来源分两类

来源 调用 用途
BCRegistry.INSTANCE.addCraftingRecipe(ItemStack, Object...) core/BCRegistry.java:94-97 工作台配方(有形状/材料字典)
GameRegistry.addShapelessRecipe(...) Transport 等 无序配方

BCRegistry.addCraftingRecipe(core/BCRegistry.java:94)内部先过 isInvalidRecipeElement 守卫(:95-97)再转交 GameRegistry, 材料以 ore-dict 名书写(如 "ingotIron"、"dustRedstone"、"gearIron")。

⚠ 跨 mod 兼容引用:BuildCraft 配方大量使用 ore-dict 名 (ingotIron / stickWood / dustRedstone / chestWood …), 这些不是 BuildCraft 拥有的物品。 例如 BuildCraftCore.java:492 有 OreDictionary.registerOre("chestWood", Blocks.chest); ——把原版箱子注册成 chestWood 供 Builder 配方取用。

调用点数量分布(静态计数)

addCraftingRecipe 在各文件的出现次数:

文件 次数 所属 modid
BuildCraftCore.java 12 BuildCraft|Core
BuildCraftSilicon.java 11 BuildCraft|Silicon
BuildCraftFactory.java 8 BuildCraft|Factory
BuildCraftBuilders.java 8 BuildCraft|Builders
BuildCraftRobotics.java 5 BuildCraft|Robotics
BuildCraftTransport.java 2 BuildCraft|Transport
BuildCraftEnergy.java 2 BuildCraft|Energy
core/BCRegistry.java 1 (方法定义本身,非调用)
合计(调用点) 48 —

⚠ 48 是「源码里写了多少条工作台配方」,不是任何环境下实际生效的数量:

  • GTNH 上:0(见上节 6 处早退);
  • 非 GTNH 上:48(不含 Transport 走 addShapelessRecipe 的 2 条)。

4 个配方管理器(不是工作台配方,是「机器配方」)

BuildCraft 的机器配方与工作台配方是两套:

管理器 源码 添加方法 用途
RefineryRecipeManager core/recipes/RefineryRecipeManager.java addRecipe(String id, FluidStack ingredient, FluidStack result, int energy, int delay)(:30)<br>addRecipe(String id, FluidStack in1, FluidStack in2, FluidStack result, int energy, int delay)(:38) 精炼:流体 → 流体(支持一进一出 / 两进一出)
AssemblyRecipeManager core/recipes/AssemblyRecipeManager.java addRecipe(String id, int energyCost, ItemStack output, Object... input)(:23)<br>addRecipe(IFlexibleRecipe<ItemStack> recipe)(:28) 装配台:Object... 可混物品与流体
IntegrationRecipeManager core/recipes/IntegrationRecipeManager.java addRecipe(IIntegrationRecipe recipe)(:21) 集成台
ProgrammingRecipeManager core/recipes/ProgrammingRecipeManager.java addRecipe(IProgrammingRecipe recipe)(:17) 编程台

对应的 API 接口在 api/recipes/: IRecipeManager、IRefineryRecipeManager、IAssemblyRecipeManager、 IIntegrationRecipeManager、IProgrammingRecipeManager。

本仓自带的机器配方:30 个 .addRecipe( 调用点(不是 0 条)

机器配方既有本仓自带的,也有给第三方 mod 用的 IMC 钩子。两者必须分开数。

管理器 本仓 .addRecipe( 调用点 分布
AssemblyRecipeManager 25 BuildCraftSilicon.java ×9(:348/:353/:359/:365/:371/:377/:383/:389/:397)、transport/TransportSiliconRecipes.java ×11(:41/:47/:56/:61/:71/:78/:85/:92/:104/:177/:182)、transport/ItemFacade.java ×4(:504/:506/:509/:510)、core/CoreSiliconRecipes.java ×1(:19)
RefineryRecipeManager 1 BuildCraftEnergy.java:356-357,即 buildcraft:fuel(油 → 燃料,energy = 120、delay = 1)
IntegrationRecipeManager 3 BuildCraftRobotics.java:585(RobotIntegrationRecipe)、transport/TransportSiliconRecipes.java:153(GateExpansionRecipe)、:154(AdvancedFacadeRecipe)
ProgrammingRecipeManager 1 BuildCraftRobotics.java:584(BoardProgrammingRecipe)
合计 30 静态计数(.addRecipe( 出现次数)

⚠ 30 是「源码里写了多少个调用点」,不是「游戏里生效多少条配方」,两处原因:

  1. ItemFacade.java:504-510 那 4 个调用点在按外观材质遍历的循环体里 (外层守卫是 facadeIDLookup.add(recipeId)),运行时会展开成 N 条,不是 4 条。
  2. GTNH 上有 6 处 if (GTNH) return; 早退(见上文),会吃掉其中一部分。

GTNH 上哪些机器配方仍然会注册

这是最容易数错的一处。BuildCraft|Transport.loadRecipes() 的 if (!GTNH) { ... } 代码块在 BuildCraftTransport.java:790 就闭合了,而 TransportSiliconRecipes.loadSiliconRecipes() 的调用点在 :792—— 落在 !GTNH 块之外,只被 if (Loader.isModLoaded("BuildCraft|Silicon"))(:791)保护。

调用点 守卫 GTNH(装了 DreamCraft)上是否注册
BuildCraftSilicon.java ×9 if (GTNH) return;(:200) 否
BuildCraftEnergy.java ×1 if (GTNH) return;(:510) 否
BuildCraftRobotics.java ×2 if (GTNH) return;(:518) 否
core/CoreSiliconRecipes.java ×1 经 BuildCraftCore.loadRecipes(),:843 早退 否
transport/TransportSiliconRecipes.java ×13 仅 `isModLoaded("BuildCraft Silicon")(:791`)
transport/ItemFacade.java ×4 仅 `isModLoaded("BuildCraft Silicon") && !facadeForceNonLaserRecipe(:499`)

⇒ GTNH 上仍有 17 个调用点会执行(13 + 4), 所以「机器配方在 GTNH 上全被短路掉」是错的——被短路的只是 6 个 loadRecipes() 里的那 13 个调用点,工作台配方才是真的全灭。

IMC 钩子(给第三方 mod 用的注册入口)

core/InterModComms.java 里另有 2 个 addRecipe IMC 处理分支,供其他 mod 通过 FMLInterModComms 推送机器配方:

IMC 分支 位置 说明
装配台配方 core/InterModComms.java:120 AssemblyRecipeManager.INSTANCE.addRecipe(...)
精炼配方 core/InterModComms.java:154 RefineryRecipeManager.INSTANCE.addRecipe(...)

(同文件 :76 / :88 是 removeRecipe,不是 addRecipe,数调用点时别混进去。)

⚠ IMC 钩子的存在不等于「BuildCraft 自带 N 条机器配方」—— 钩子是接口,机器配方的真实来源是上面那张 30 个调用点的表。

关键配方族

族 载体 备注
齿轮系 BuildCraftCore.loadRecipes woodenGearItem ← stickWood(BuildCraftCore.java:846)
扳手 BuildCraftCore.loadRecipes wrenchItem ← ingotIron + gearStone(BuildCraftCore.java:845-846)
机器本体 BuildCraftFactory.loadRecipes 如 miningWellBlock(:217-232)
硅 / 红石 BuildCraftSilicon.loadRecipes Silicon 的 11 条
流体转化 BuildCraftEnergy.loadRecipes buildcraft:fuel:油 → 燃料,经 BuildcraftRecipeRegistry.refinery.addRecipe(...),energy = 120、delay = 1(BuildCraftEnergy.java:356-357)
防水管道 BuildCraftTransport.loadRecipes pipeWaterproof ← 染料 meta 2(BuildCraftTransport.java:731)/ 黏液球(:733,受 additionalWaterproofingRecipe 开关控制,:732)

⚠ 流体配方 buildcraft:fuel 走的是 BuildcraftRecipeRegistry.refinery.addRecipe(...) (BuildCraftEnergy.java:356-357),不是 addCraftingRecipe—— 它是精炼配方,对应 RefineryRecipeManager 的单参重载 addRecipe(String id, FluidStack, FluidStack, int energy, int delay)。

⚠ 它的 120 是能量、1 是延迟,两个参数单位不同, 不能把 120 说成「耗时 120 tick」,也不能说成「需要 120 桶油」。

⚠ 同文件 :359 还有一条燃料(不是配方)的注册: BuildcraftFuelRegistry.fuel.addFuel(fluidOil, fuelOilEnergyOutput, (int) (5000 * fuelOilMultiplier)) ——5000 是燃烧时长 tick,与上面的 120 不是同一个量。

相关条目