16 KiB
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 件事(别漏)
- 进创造 Tab:
java/thaumicenergistics/init/ModCreativeTab.java的displayItems里补一行output.accept(ModItems.KNOWLEDGE_INSCRIBER_ITEM.get());(不然拿不到) - 汉化:
resources/assets/thaumicenergistics/lang/zh_cn.json里补","block.thaumicenergistics.knowledge_inscriber":"知识刻印机" - (可选)有配方:去
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 旁边放一个.mcmetaJSON 描述帧动画,模型文件写法不变。
第 3 步:放真实贴图 PNG
文件:resources/assets/thaumicenergistics/textures/item/storage_component_1k.png
📌 要求:16×16 或 32×32 或 64×64 的 PNG(尺寸必须是 2 的幂),文件名必须跟 layer0 写的一样。