Files
thaumicenergistics-neo/Issue-改善物品方块扫描要素.md
2026-08-19 00:17:24 +08:00

87 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# [Feature Request] 改善物品/方块扫描要素的自动赋予机制(恢复配方溯源 + 性能优化)
## 概述 Summary
请求为 TC4 1.21.1 移植版恢复 1.7.10 的**合成配方溯源**机制(物品作为配方产出时,按原料要素自动赋予要素),并修复 `getObjectTags` 无索引穷举遍历导致的严重性能问题。
当前移植版 `ItemAspectRegistry.getObjectTags` 只保留:注册表 → NBT → 精确表 → ID 词根推算 → `ENTROPY` 兜底。**词根表仅覆盖约 15 组 ID**,对 mod 物品几乎不命中,大量物品退化为 `ENTROPY×1` 或词根给的 1-2 种要素,且无法反映合成复杂度。
## 问题描述 Problem
### 功能缺失(影响整个 mod 生态)
1. **要素不准确**:mod 物品(如 `thaumicenergistics:essentia_provider`、`waystones:waystone`)扫描要素靠 ID 词根猜——词根对不上就 `ENTROPY×1`,对得上也只有 1-3 种
2. **无合成溯源**:合成材料完全不影响要素——1 个原料的和 10 个原料的合成品要素一样,无法体现合成复杂度
### 性能严重(实测)
- `getObjectTags` 每次调用**穷举遍历全部配方**(1932+ 个 CRAFTING)比较产出——无索引、无缓存
- 客户端 JEI 启动遍历全部物品时触发全量扫描:**实测单次扫描耗时 10 秒 / 1127 tick**(F3+L profiler)
- 频繁调用(Thaumonomicon/JEI 显示)导致持续卡顿
## 期望行为 Expected Behavior
- mod 物品扫描要素**按合成材料赋予**(与 1.7.10 一致)
- 要素数量/种类**合理**(种类 2-6、总量 8-24、单要素 ≤64)
- 扫描/显示**无卡顿**(单次查询毫秒级)
## 建议实现 Suggested Implementation
### A. 功能:getObjectTags 增加配方溯源分支
```
在词根推算 / ENTROPY 兜底之前:
recipe = 查产出=stack 的配方
if recipe != null:
原料要素 = 递归 getObjectTags(原料)(深度 ≤2,visited 防环)
返回 原料要素之和(同种要素取最大,避免累加爆炸)
```
可选覆盖配方类型(按需):普通合成(Crafting)、熔炉(Smelting)、注魔(Infusion)、炼金(Crucible)、奥术(Arcane)。
### B. 性能:产出→配方索引
```
懒构建 Map<Item, List<Recipe>>(按产出分组,首次查询时建一次)
getObjectTags 内 O(1) 查索引,不再每次穷举遍历全部配方
结果缓存 ConcurrentHashMap<Item, AspectList>,绑定 Server 引用(/reload 自动失效)
```
### C. 要素限制(贴近 1.7.10 + 平衡)
- 单要素 ≤64
- 种类 ≤6(按数量降序取前 6)
- 总量按复杂度归一化:`clamp(8 + 原料种类×2, 8, 24)`
- 同种要素多个原料出现时**取最大值**(不累加,防 1000+)
## 复现步骤 Steps to Reproduce
1. 安装任意含合成配方的 mod(如 waystones 传送石碑:3 黑曜石 + 3 石砖 + 1 传送石)
2. 用魔导透镜扫描该 mod 物品
3. 实际:`ENTROPY×1` 或词根 1-3 种(传送石碑给 1 混沌)
4. 期望:黑曜石(暗/虚空)+ 石砖(石头)+ 传送石(水晶/末影)要素
## 性能复现
1. 客户端启动(JEI 加载,遍历全部物品调 getObjectTags)
2. F3+L 采样 10 秒
3. 实际:`getObjectTags` 占比极高(穷举遍历配方),单物品 10s 级
## 参考实现要点(作者可参考)
- 1.21.1 `RecipeManager.byType` 为 **private**——用 `getAllRecipesFor(RecipeType)`(公开,返回 `List<RecipeHolder<T>>`)
- `RecipeHolder.id()` 直接返回 `ResourceLocation`(无 `.location()`)
- TC 配方访问:`ThaumcraftApi.getInfusionRecipe(result)` / `getCrucibleRecipe(result)` / `getCraftingRecipes()`(遍历 `IArcaneRecipe`,含 `getAspects()` vis 成本)
- `InfusionRecipe` 原料:`centralInput()` + `getComponents()`(公开)
- 缓存注意:组件敏感物品(药水/染色/耐久 NBT 变体)不进缓存(TC 的 NBT 分支先截走);COMPUTING 哨兵防跨配方递归环;缓存绑定 Server 引用(reload 失效)
## 环境 Environment
- Minecraft 1.21.1
- NeoForge 21.1.x
- Thaumcraft
## 补充
- 完整反编译调研与参考实现已由 ThaumicEnergistics 移植团队完成,可提供更详细方案(含存储体系:内存缓存 + 可选本地二进制文件缓存,指纹校验跨启动复用)