Files
thaumicenergistics-neo/路径.md
T
2026-08-19 00:17:24 +08:00

16 KiB
Raw Blame History

ThaumicEnergistics 代码位置速查表

说明:本文件所有路径均相对于 modules/thaumicenergistics-neo/src/main/。 若文件路径以 java/ 开头 → Java 源码;以 resources/assets/ 开头 → 资源/JSON。


一、物品 / 方块 Java 注册

你想找什么 文件 关键行 备注
物品总注册器入口 java/thaumicenergistics/init/ModItems.java 12 DeferredRegister.Items REGISTRY
1k/4k/16k/64k 源质存储单元(带容量的 Cell) ModItems.java 14~18 ESSENTIA_CELL_1K ~ ESSENTIA_CELL_CREATIVE
1k/4k/16k/64k 存储组件(Storage Component) ModItems.java 19~22 STORAGE_COMPONENT_1K ~ 64K
聚变核心 / 扩散核心 ModItems.java 23~24 COALESCENCE_CORE / DIFFUSION_CORE
铁齿轮 / 知识核心 / AE扳手核心 ModItems.java 25~27 IRON_GEAR / KNOWLEDGE_CORE / FOCUS_AEWRENCH
无线源质终端 / 傀儡WiFi背包 ModItems.java 28~29 WIRELESS_ESSENTIA_TERMINAL / GOLEM_WIFI_BACKPACK
源质IO总线/存储总线/终端/LevelEmitter/Vis接口/共鸣器 ModItems.java 30~37 ESSENTIA_IMPORT_BUS 等一整套
方块对应物品(BlockItem) ModItems.java 39~47 ESSENTIA_PROVIDER_ITEM、KNOWLEDGE_INSCRIBER_ITEM 等,与 ModBlocks 一一对应
方块总注册器入口 java/thaumicenergistics/init/ModBlocks.java 17 DeferredRegister.Blocks REGISTRY
源质提供器 Essentia Provider ModBlocks.java 20 ESSENTIA_PROVIDER
注入提供器 Infusion Provider ModBlocks.java 21 INFUSION_PROVIDER
奥术组装机 Arcane Assembler ModBlocks.java 22 ARCANE_ASSEMBLER(Tile: TileArcaneAssembler)
源质振动室 Essentia Vibration Chamber ModBlocks.java 23 ESSENTIA_VIBRATION_CHAMBER(Tile: TileEssentiaVibrationChamber)
知识刻印机 Knowledge Inscriber ModBlocks.java 24 KNOWLEDGE_INSCRIBER(纯方块,无BE)
精馏编码器 Distillation Encoder ModBlocks.java 25 DISTILLATION_ENCODER(纯方块,无BE)
齿轮箱 / 傀儡齿轮箱 ModBlocks.java 26~27 GEAR_BOX / GOLEM_GEAR_BOX
源质单元工作台 Essentia Cell Workbench(含 GUI 打开逻辑) ModBlocks.java 28~38 里面直接写了 useItemOn 和 getMenuProvider
方块实体(BlockEntity)注册器 java/thaumicenergistics/init/ModBlockEntities.java — (与 ModBlocks 里带 Tile 的对应)
菜单类型 / 屏幕注册 java/thaumicenergistics/init/ModMenuTypes.java + ThaumicEnergistics.java:40~46 — registerScreens 方法里绑定 GuiXXX::new

二、配方注册(1k/4k/16k/64k 组件、奥术、注入、坩埚)

你想找什么 文件 关键行 备注
配方总入口(commonSetup 里触发) java/thaumicenergistics/ThaumicEnergistics.java 36~38 commonSetup(event) { event.enqueueWork(RecipeRegistration::registerAll); }
配方注册总开关 java/thaumicenergistics/common/features/RecipeRegistration.java 247~253 registerAll() 调 4 个子方法 + 打日志
有形状奥术合成(1k/4k/16k/64k、齿轮箱、刻印机等 14 条) RecipeRegistration.java 255~417 registerShapedArcane()
⭐ 1k Storage Component(任意天域之华版,for 循环展开) RecipeRegistration.java 256~267 wisps1k.get(i) 当 'E'
⭐ 4k Storage Component(任意天域之华版) RecipeRegistration.java 269~281 wisps4k.get(i) 当 'E'
⭐ 16k Storage Component(任意天域之华版) RecipeRegistration.java 283~296 wisps16k.get(i) 当 'E'
64k Storage Component RecipeRegistration.java 298~307 单配方,不用循环
天域之华名称表 + wispEssenceStacks()(不用 Tag,硬编码 ID 绕过时序) RecipeRegistration.java Tag 常量区 + WISP_ESSENCE_VARIANTS 数组(第 227 行起) 这是配方「任意天域之华」能生效的核心
无形状奥术合成(核心、总线、终端等 7 条) RecipeRegistration.java 419~473 registerShapelessArcane()
注入配方(Essentia/Infusion Provider、奥术组装机) RecipeRegistration.java 475~514 registerInfusion()
坩埚配方(傀儡齿轮箱 = 齿轮箱熔炼) RecipeRegistration.java 516~523 registerCrucible()
3 个 helper:stack() 物品封装 / tc() 取 Thaumcraft 物品 / ae() 取 AE2 物品 RecipeRegistration.java 525~537 配方里所有 'X', ae(...)、'X', tc(...) 都走这里
配方乱码前缀 RecipeRegistration.java 所有 addXxxRecipe 第一个参数 "th_a€‰" / "th_b€‰" / "th_c€‰" / "th_d€‰"(不影响功能但建议后续统一换成 R + "xxx")

三、资源引用链(材质 / 模型 / BlockState)

根目录:resources/assets/thaumicenergistics/
规则:注册名 = 文件名(不含 .json/.png)。物品/方块在 ModItems/ModBlocks 里用什么 register("xxx"), 下面 4 层 JSON/PNG 就必须都叫 xxx。

层 路径 它引用谁 关键字段
① BlockState(方块状态→方块模型) blockstates/<注册名>.json(共 9 个) 指向 models/block/xxx.json "model": "thaumicenergistics:block/<注册名>"
② Block Model(方块模型→PNG 贴图) models/block/<注册名>.json(共 9 个) 指向 textures/block/xxx.png "textures": { "up": "...", "down": "...", "north": "...", ... }
③ Item Model(物品模型→方块模型 或 物品 PNG) models/item/<注册名>.json(物品 23 个 + 方块物品 9 个 = 32 个) 方块物品:parent 到 ②;纯物品:直接写 layer0 方块物品:"parent": "thaumicenergistics:block/<注册名>";纯物品:"textures": { "layer0": "thaumicenergistics:item/<注册名>" }
④ PNG 贴图 textures/block/*.png(9 套方块面)、textures/item/*.png(23 个物品贴图) 被 ② ③ 引用 直接对应文件名

四、几个你最常问的具体定位(直接跳)

问题 去哪看
1k/4k/16k 组件配方「任意天域之华」怎么实现的 RecipeRegistration.java:227~244(名称表 + wispEssenceStacks()) + 255~296(for 循环注册)
为什么要写死 WISP_ESSENCE_VARIANTS 数组,不能用 Tag 吗 Tag 要到 DataPack 加载(比 commonSetup 晚)才填充,commonSetup 里 getTag() 返回空 → for 循环 0 次 → 配方直接没了。所以注册阶段必须绕开 Tag 用硬编码 ID。
「JEI 里完全没配方」排查顺序 ① latest.log 里搜 Wisp essence variants loaded 看数字是不是 0;② 搜 Invalid arcane recipe ingredient(Ingredient 传进去就崩);③ 搜 Mod loading has failed 看 FMLCommonSetupEvent 是不是中途崩了;④ 确认 commonSetup 里是不是 event.enqueueWork(RecipeRegistration::registerAll)
Essentia Provider / Infusion Provider / Knowledge Inscriber / Gear Box「完全没材质」排查顺序 层 ①→②→③→④ 依次看:① blockstates 里 model 指向对不对;② models/block 里 textures 每个面都写了且 PNG 存在;③ models/item 里 parent 指回方块模型;④ textures 目录下 PNG 真实存在且命名一致。
Essentia Cell Workbench「顶面材质没了,侧面正常」 直接打开 models/block/essentia_cell_workbench.json 看 "textures" 里 "up" 字段是不是写对了(应该指向 textures/block/essentia_cell_workbench_top.png)
想加一个新物品/新方块 ① 先在 ModItems / ModBlocks 里 register("xxx", ...);② 想办法给物品弄一个 models/item/xxx.json + textures/item/xxx.png;如果是方块再加 blockstates/xxx.json + models/block/xxx.json + textures/block/xxx.png;③ 想进创造模式 Tab 要去 ModCreativeTab.java 里加 output.accept(ModItems.XXX.get());④ 有配方去 RecipeRegistration.java 对应子方法里加一条
汉化文本 resources/assets/thaumicenergistics/lang/zh_cn.json
创造模式 Tab 物品顺序 java/thaumicenergistics/init/ModCreativeTab.java
源质单元容量实现(1k/4k/16k/64k 各自多少字节) java/thaumicenergistics/common/items/ItemEssentiaCell.java 里的 create1k / create4k / create16k / create64k 静态工厂
天域之华 Tag 文件(防止主模组未来注册同名产生冲突) resources/data/thaumicenergistics/tags/items/wisp_essences.json (里面写了 "replace": false 且包含 { "id": "#thaumcraft:wisp_essences", "required": false } 作为兼容占位)
启动崩 Invalid arcane recipe ingredient: Ingredient@xxxx 一定是配方里把 Ingredient 传进了字符映射表('E', xxx 的 xxx 必须是 ItemStack / Item / ResourceLocation,不能是 Ingredient),去 registerShapedArcane() 里搜 wispEssenceIngredient,有就立刻改成 wisps.get(i)(ItemStack)
Gradle 警告 Space-assignment syntax ... init.gradle:10 这个是全局 Gradle 初始化脚本(D:\GradleCache\init.gradle)里的老写法,把 url "https://..." 改成 url = "https://..." 就好,跟模组代码无关

五、注册一个方块 — 从 Java 代码 → 材质 PNG 的完整 5 步引用链

🎯 例子用现成的 knowledge_inscriber(知识刻印机),你加新方块时直接把所有 knowledge_inscriber 替换成你的新注册 id 即可。

核心铁律:注册 id 必须全局一致 — ModBlocks、ModItems、blockstates 文件名、models/block 文件名、models/item 文件名、textures 引用名,全部都是同一个字符串(大小写全小写,单词间下划线)。

第 1 步:Java 注册方块本体(决定注册 id)

文件:java/thaumicenergistics/init/ModBlocks.java

public static final DeferredBlock<Block> KNOWLEDGE_INSCRIBER =
        REGISTRY.register("knowledge_inscriber", () -> new Block(P));
//                         ^^^^^^^^^^^^^^^^^^^  ← 这里是「注册 id」,下面 4 层必须全一致

如果方块有 GUI(比如 Essentia Cell Workbench),就在 new Block(P) { ... } 里覆写 useItemOn + getMenuProvider。 如果方块有 BlockEntity(比如 Essentia Provider),就用 ThEBaseEntityBlock(P) 并实现 newBlockEntity。

第 2 步:Java 注册方块物品(拿在手里的那个 Item)

文件:java/thaumicenergistics/init/ModItems.java

public static final DeferredItem<blockitem> KNOWLEDGE_INSCRIBER_ITEM = 
        REGISTRY.registerSimpleBlockItem(ModBlocks.KNOWLEDGE_INSCRIBER);
//                                       ^^^^^^^^^^^^^^^^^^^ ← 直接绑定第 1 步的方块</blockitem>       

registerSimpleBlockItem 是 NeoForge 封装好的,它会自动用同一个注册 id(这里就是 knowledge_inscriber)来生成 BlockItem,所以下面第 5 步「物品模型」的文件名也必须是 knowledge_inscriber.json。

第 3 步:BlockState(方块状态 → 方块模型的路由表)

文件:resources/assets/thaumicenergistics/blockstates/knowledge_inscriber.json

{ 
  "variants": 
  { 
    "": 
    { 
          "model": "thaumicenergistics:block/knowledge_inscriber"
    }
  }
}

📌 解释:Minecraft 渲染一个方块时,先看方块状态属性(朝向、开关等),再查 blockstates 找到该状态对应哪个方块模型 JSON。 知识刻印机没有状态属性(不区分朝向),所以用 "" 表示「默认变体」;如果是有朝向的方块(比如 Essentia Provider),那要写 facing=north/south/east/west/up/down 六个变体。

第 4 步:Block Model(方块模型 → 每个面用哪张 PNG)

文件:resources/assets/thaumicenergistics/models/block/knowledge_inscriber.json

{
  "parent": "minecraft:block/cube_bottom_top",
  "textures": {
    "top": "thaumicenergistics:block/knowledge_inscriber_top",
    "bottom": "thaumicenergistics:block/knowledge_inscriber_bottom",
    "side": "thaumicenergistics:block/knowledge_inscriber_side"
  }
}

📌 解释:particle 是「破坏方块时飞溅的粒子贴图」,一般跟 north 用同一张。上面 6 个面(up/down/north/south/east/west)的字符串,不要加 .png 后缀,游戏会自动去 textures/ 目录下找对应的 PNG。

📌 对应的 3 张贴图必须真实存在:

  • resources/assets/thaumicenergistics/textures/block/knowledge_inscriber_top.png(顶面)
  • resources/assets/thaumicenergistics/textures/block/knowledge_inscriber_bottom.png(底面)
  • resources/assets/thaumicenergistics/textures/block/knowledge_inscriber_side.png(四个侧面共用一张)

第 5 步:Item Model(物品模型 — 方块物品最简单写法:直接「继承」方块模型)

文件:resources/assets/thaumicenergistics/models/item/knowledge_inscriber.json

{
  "parent": "thaumicenergistics:block/knowledge_inscriber"
}

📌 解释:99% 的方块物品不需要独立物品贴图,直接 parent 指回第 4 步的方块模型,Minecraft 会自动把方块渲染器缩放成 3D 物品形态(就是你在背包、物品栏、地上掉落物看到的样子)。

只有当你想让「物品形态」跟「方块形态」长得不一样时(比如 AE2 的接口物品是 2D 图标),才需要单独写 layer0 引用物品 PNG(写法参考下一节纯物品)。

✅ 新方块加完后还要做的 2 件事(别漏)

  1. 进创造 Tab:java/thaumicenergistics/init/ModCreativeTab.java 的 displayItems 里补一行 output.accept(ModItems.KNOWLEDGE_INSCRIBER_ITEM.get());(不然拿不到)
  2. 汉化:resources/assets/thaumicenergistics/lang/zh_cn.json 里补 ","block.thaumicenergistics.knowledge_inscriber":"知识刻印机"
  3. (可选)有配方:去 RecipeRegistration.java 的 registerShapedArcane() 或 registerInfusion() 里加一条。

六、注册一个纯物品(不是方块) — 从 Java 代码 → 材质 PNG 的完整 3 步引用链

🎯 例子用现成的 storage_component_1k(1k 存储组件),加新物品时直接替换 id 即可。 核心铁律同上:注册 id = 模型文件名 = PNG 文件名(不加后缀)。

第 1 步:Java 注册物品本体

文件:java/thaumicenergistics/init/ModItems.java

public static final DeferredItem<item> STORAGE_COMPONENT_1K = REGISTRY.registerSimpleItem("storage_component_1k");
//                                                                                         ^^^^^^^^^^^^^^^^^^^^^ ← 注册 id,下面 2 层必须一致</item>

如果物品有自定义逻辑(比如源质 Cell 带容量读写 NBT、右键使用、背包叠加数量 1 等),就不用 registerSimpleItem,改用:

public static final DeferredItem<itemessentiacell> ESSENTIA_CELL_1K = 
        REGISTRY.registerItem("essentia_cell_1k", ItemEssentiaCell::create1k);

本质上只是把 new Item() 换成你自己的自定义物品构造函数 / 静态工厂。

第 2 步:Item Model(物品模型 → layer0 指向物品 PNG)

文件:resources/assets/thaumicenergistics/models/item/storage_component_1k.json

{
  "parent": "minecraft:item/generated",
  "textures": {
    "layer0": "thaumicenergistics:item/storage_component_1k"
  }
}

📌 解释:所有「普通 2D 贴图物品」的 parent 都是 item/generated(MC 内置的平面图标渲染器)。 layer0 就是「主贴图」。字符串不要加 .png 后缀,游戏会自动找 textures/item/storage_component_1k.png。

少数物品有动画(比如 knowledge_core.png.mcmeta),那是在 PNG 旁边放一个 .mcmeta JSON 描述帧动画,模型文件写法不变。

第 3 步:放真实贴图 PNG

文件:resources/assets/thaumicenergistics/textures/item/storage_component_1k.png

📌 要求:16×16 或 32×32 或 64×64 的 PNG(尺寸必须是 2 的幂),文件名必须跟 layer0 写的一样。