Aspect Recipe Index
[!INFO] Git Commit:
4010c2e| Updated: 2026-09-08
Aspect Recipe Index(modid aspectrecipeindex)是 Thaumcraft 4 的一个纯客户端 NEI 增强模组。它把 Thaumcraft 的元素(Aspect)、研究进度与各类炼金配方接入 Not Enough Items,让玩家可以在 NEI 里用"元素"当搜索词,查询和浏览配方。
代码基础是 Time_Conqueror 的 TCNEIAdditions,GTNH 团队在 2020–2025 年间重写维护。mcmod.info 里的自述是 “New and improved compatibility for Thaumcraft in NEI.”
核心结论
| 问题 | 答案 |
|---|---|
| 它注册了什么方块 | 没有任何方块 |
| 它注册了什么实体 / TileEntity | 没有 |
| 它注册了几个物品 | 1 个(aspectrecipeindex:aspect) |
| 它有自己的网络包吗 | 没有,只复用 Thaumcraft 的 PacketAspectPool |
| 它有热键吗 | 没有 |
| 它有指令吗 | 没有 |
| 它是 core mod 吗 | 不是(coreModClass 为空) |
| 有多少个 NEI recipe handler | 7 个(含 1 个继承自有序版的无序版) |
| 有多少个 LATE mixin | 2 个(全部客户端、全部打向 Thaumcraft) |
元素配方索引机制
它没有维护任何长期存活的"配方索引表"。 尽管模组叫这个名字,实际机制是惰性查询 + 线性扫描 + 36 格链表分页:
- 数据源是玩家自己的扫描记录(
Thaumcraft.proxy.getScannedObjects()),不是全局表,所以结果按玩家不同,服务端无法预生成。 - "某元素 → 含该元素的物品"每次查询都把扫描记录里的 hash 逐条
GuiResearchRecipe.getFromCache反查成ItemStack,叠加 object tags 与 bonus tags,再按含量降序排列。 - 36 个物品一页,用
next字段串成链表惰性创建下一页。 - 其余 6 个 handler 更直接:每次都把
ThaumcraftApi.getCraftingRecipes()全量扫一遍,靠Util.getEssentiaFromItem的结果做元素交集匹配。 - 元素物品的"命中判定"发生在
CachedThaumRecipe.contains/containsWithNBT的特判分支里,查的是内存中的AspectList。
完整数据流、分页、进度与刷新策略见 元素配方索引机制。
加载与事件钩子
本模组不订阅任何 Forge 事件(MinecraftForge.EVENT_BUS、@SubscribeEvent、@Mod.EventBusSubscriber 全仓 grep 均无结果)。它只有 4 类钩子:
| 钩子 | 类型 | 触发时机 |
|---|---|---|
onMissingMappings(FMLMissingMappingsEvent) |
@Mod.EventHandler(static) |
映射修复期;忽略 thaumcraftneiplugin:Aspect 物品映射 |
NEIConfig.loadConfig() |
NEI IConfigureNEI |
NEI 客户端加载配置时;注册 7 recipe + 7 usage + 4 GUI overlay + 4 overlay handler + 1 stringify handler |
IMCForNEI.IMCSender() |
FML IMC | FMLInitializationEvent(客户端);向 NEI 发 7 条 registerHandlerInfo + 8 条 registerCatalystInfo |
| 2 个 LATE mixin | UniMixins / GTNHLib Mixins | Thaumcraft MappingThread.run() 与 ClientTickEventsFML.renderAspectsInGui |
FML 生命周期:construct 为空 → preInit 注册物品 → init(客户端)发 IMC、注册渲染器与配置 → postInit 空。
Mixin 与 AT
gradle.properties 中 usesMixins = true、accessTransformersFile = aspectrecipeindex_at.cfg、coreModClass 为空。AT 只提升 net.minecraft.client.gui.inventory.GuiContainer 的 4 个 protected 字段为 public(SRG 原文 field_146999_f = xSize、field_147000_g = ySize、field_147003_i = guiLeft、field_147009_r = guiTop),供 mixin 做鼠标区域排除。
详见 Mixin 与 LATE 注入 与 Access Transformer。
配置项
配置框架是 GTNHLib 的 @Config(modid = "aspectrecipeindex"),共 5 个全部为布尔的选项,且只在客户端注册(注册调用写在 ClientProxy 里,ServerProxy 不注册)。
| 选项 | 类型 | 默认值 | 门控什么 |
|---|---|---|---|
showLockedRecipes |
boolean | false |
研究未完成的配方是否照常显示 |
showInstabilityNumber |
boolean | true |
注入不稳定性用数字还是分级文字 |
showResearchKey |
boolean | true |
研究控件绘制与 tooltip 悬停 |
showUndiscoveredAspectNames |
boolean | false |
未发现元素的名称与描述 |
showUndiscoveredAspectRecipes |
boolean | false |
未发现元素的组合 / 包含物品 |
另有 8 个 ColorResource 颜色常量(硬编码默认值 + 资源包 lang 覆盖,不在配置文件里)。详见 配置项 与 颜色常量。
兼容性门控
| 模组 | 强度 | 门控的代码路径 |
|---|---|---|
| Thaumcraft | required-after |
全部功能(且大量使用其内部 API) |
| GTNHLib | required-after |
@Config 配置框架、ColorResource |
| gtnhmixins | required-after |
LATE mixin 加载 |
| TC4Tweaks / TC4RecipeLib / InfusionRecipeLib | required-after(三者之一) |
注入配方的 EnhancedInfusionRecipe 转换 |
| NotEnoughItems | 编译期 api + IMC 目标 | 全部 7 个 handler 与 GUI 覆盖 |
| Automagy | after |
Loader.isModLoaded("Automagy") + 研究分类为 AUTOMAGY 时,tooltip 追加"击杀并扫描"要求 |
| GTNH-TC-Wands | 编译期 compileOnly | Loader.isModLoaded("gtnhtcwands") 切换魔杖配方生成路径(wrapper API ↔ 杖柄×杖帽笛卡尔积) |
| Baubles-Expanded | 仅 runtimeOnlyNonPublishable |
不参与任何门控,只是 runClient 依赖 |
| TCNEIPlugin / TCNEIAdditions | 冲突但可共存 | 会导致配方重复,README 建议移除 |
Loader.isModLoaded 门控之外还有一处降级:API.registerStackStringifyHandler 被 try / catch (NoSuchMethodError ignored) 包住,NEI 缺该 API 时静默跳过。
详见 兼容性。
NEI 集成总览
7 个 recipe handler,同时全部注册为 usage handler:
| Overlay 标识 | 展示内容 |
|---|---|
thaumcraft.items_containing_aspect |
含指定元素的已扫描物品(36 格分页) |
thaumcraft.aspects |
元素组合关系(父元素 / Primal) |
thaumcraft.alchemy |
坩埚与神秘机器的炼金配方 |
thaumcraft.infusion |
奥法注入配方 + 不稳定性 + Runic 护甲强化 |
thaumcraft.arcane.shaped |
有序奥法合成 |
thaumcraft.arcane.shapeless |
无序奥法合成 |
thaumcraft.wands |
魔杖与法杖合成 |
外加奥法工作台的 NEI 自动摆放覆盖(含 vis 不足时自动换杖),以及元素物品的 NBT 序列化扩展。逐条见下列条目。
物品列表
- Aspect 物品 -
aspectrecipeindex:aspect,NBT 存元素 tag,metadata 0/1/2+ 控制图标可见性
物品效果
- Aspect 研究点 - 右键消耗元素物品,+1 aspect pool 即 +1 研究点,服务端到客户端单播
游戏设定
- 配置项 - 5 个 GTNHLib 布尔选项,逐条追踪到判定入口
- 颜色常量 - 8 个
ColorResource默认值与不稳定性 6 档配色 - 元素配方索引机制 - 惰性扫描、36 格分页、加载进度与 10 秒刷新
- 兼容性 - 硬依赖、软依赖门控、TCNEIPlugin 共存问题
- Access Transformer -
GuiContainer的 4 个字段提升为 public - Mixin 与 LATE 注入 -
MappingThread3 处 +ClientTickEventsFML1 处注入
NEI 处理器
- Items Containing Aspect Handler - 模组核心功能,含加载进度显示与 tooltip 增强
- Aspect Combination Handler - 元素组合关系,只有第 0 页显示研究控件
- Alchemy Handler - 坩埚配方,催化产物 + 元素需求
- Arcane Infusion Handler - 注入配方 + 不稳定性分档 + Runic 护甲强化数学
- Shaped Arcane Crafting Handler - 有序奥法合成,vis 与材料格分离
- Shapeless Arcane Crafting Handler - 无序版,按 3 列切块复用父类
- Wand Crafting Handler - 魔杖配方,GTNH-TC-Wands 双分支生成
- Arcane Workbench 覆盖 - 自动摆放 + vis 不足自动换杖
- Stack Stringify Handler - 元素物品 NBT 序列化,含
NoSuchMethodError降级 - IMC 注册消息 - 发给 NEI 的 7 条 handlerInfo + 8 条 catalystInfo
本 mod 没有的内容(附 grep 证据)
以下维度在源码中确认不存在,因此没有创建对应目录。
没有方块、多方块、TileEntity
$ grep -rn "registerBlock\|EntityRegistry\|registerTileEntity\|registerEntity" src/main/java
(无输出)
$ grep -rn "class Block\b\|TileEntity\|Multiblock" src/main/java
(无输出)
没有实体
$ grep -rln "EntityLiving\|IWorldGenerator" src/main/java
(无输出)
ItemAspect.onItemRightClick 里出现的 EntityPlayer / EntityPlayerMP / FakePlayer 是判定接收者类型,不是本模组定义的实体。
没有热键
$ grep -rn "new KeyBinding" src/main/java
(无输出)
$ grep -rn "KeyBinding" src/main/java
(无输出)
连 import 都没有。模组的全部交互都在 NEI 界面内完成。
没有指令
$ grep -rn "ICommand\|CommandHandler\|CommandBase\|registerCommand" src/main/java
(无输出)
没有 addChatCommand,也没有任何权限节点。
没有网络包
$ grep -rn "SimpleNetworkWrapper\|NetworkRegistry\|IMessage\|IMessageHandler\|sendToServer" src/main/java
(无输出)
$ grep -rn "sendTo(" src/main/java
./com/gtnewhorizons/aspectrecipeindex/common/items/ItemAspect.java:58: PacketHandler.INSTANCE.sendTo(
唯一的发包点是复用 Thaumcraft 的 PacketAspectPool,不是自建通道。
没有 Forge 事件订阅
$ grep -rn "@SubscribeEvent\|@Mod.EventBusSubscriber\|MinecraftForge.EVENT_BUS" src/main/java
(无输出)
没有附魔、药水效果、群系、维度、结构、成就
$ for kw in Enchantment Potion BiomeGen WorldProvider DimensionManager WorldGenerator IWorldGenerator ChestGenOre Achievement; do ... done
每一个都是 NONE
不是 core mod
gradle.properties 中 coreModClass =(空值),仓库内没有实现 IFMLLoadingPlugin 的类。
只注册了 1 个物品,没有方块物品 / 机器 / Tile
$ grep -rn "GameRegistry.register" src/main/java
./com/gtnewhorizons/aspectrecipeindex/ModItems.java:15: GameRegistry.registerItem(itemAspect, "aspect");
ModItems 类里只有 itemAspect 一个字段。