Repository navigation
Rename the omitted resource files and item id 重命名遗漏的资源文件与物品 ID - #6101
Conversation
Gugle2308
left a comment
There was a problem hiding this comment.
Good: getKey is not patched to resolve aliases. So BuiltInRegistries.ITEM.getKey(item) returns the new id (since the item is registered as hardened_resin). So GuideItemBinding.matches() compares hardend_resin (handbook) != hardened_resin → no match.
But createItemStack() uses lookup.get().get(ResourceKey.create(...hardend_resin)) → Registry.get(ResourceKey) → patched to byKey.get(resolve(key)) → alias resolves → returns the hardened_resin item. So:
<item id="anvilcraft:hardend_resin"/>(MDItemComponent) → uses registry lookup → alias works ✅ displays correctly.<ref item="anvilcraft:hardend_resin"/>(BuiltinInlineComponents REF) → usesBuiltInRegistries.ITEM.get(itemId)(Optional holder) → alias-resolving get → works ✅.items:frontmatter → builds ITEM_DOCUMENT_CACHE keyed bybinding.itemId()= old id; thengetFirstDocumentByItemStacklooks up byBuiltInRegistries.ITEM.getKey(stack.getItem())= new id → cache miss → W 键提示 / 悬浮提示找不到这份手册页(regression: item→handbook binding broken for hardened_resin).
Let me verify this carefully: GuideDocumentCache line 178-185: Identifier itemId = BuiltInRegistries.ITEM.getKey(stack.getItem()); List<ItemDocumentBinding> bindings = ITEM_DOCUMENT_CACHE.get(itemId); and cache was built with binding.itemId() — the raw frontmatter id, i.e. anvilcraft:hardend_resin. Since getKey returns anvilcraft:hardened_resin now, lookup misses.
That's a concrete, verifiable regression: the handbook items: binding for hardened_resin no longer resolves → the "W / hold to open guide" navigation for that item is lost. Confirmed by class reading. Note matchSpecificity also fails but that's only used in the same path.
Also <recipe id="anvilcraft:fast_cooking/hardend_resin"/> — recipe ids are data pack ids, alias doesn't help. But the MDRecipeComponent's byKey lookup is currently commented out (TODO) in ageratum build.141 — so <recipe> currently renders emptyComponent for ALL recipes? Let's check: extractRenderState → if component != null → render; else look up recipe... but the lookup is commented out, so it falls to emptyComponent.extractRenderState. Hmm, wait: the whole block after ClientLevel level = minecraft.level; is comments only, so nothing happens after if (level == null). Actually the code is:
Minecraft minecraft = context.minecraft();
if (component != null) { ...; return; }
ClientLevel level = minecraft.level;
if (level == null) { emptyComponent.extractRenderState(...); return; }
// TODO
// ... commented
}So when component == null and level != null, nothing is rendered at all (no empty component either). So currently <recipe id> renders nothing regardless of id validity. So the stale fast_cooking/hardend_resin recipe id in handbook is currently unobservable (ag wasted), but it's still stale data that will break once the TODO is implemented. Also note AnvilCraft's own MD components (MDVanillaCraftingComponent etc.) — but those are for recipe types; entry is via ageratum's registry factory. Since the byKey lookup is disabled, they never get instantiated? Hmm, maybe repo registers its own... Actually AnvilCraftRecipeComponentFactories registers factories; the proxy creates components only through setComponent which is only called from the commented-out path. So MD*RecipeComponent are dead code in build.141? That seems odd but plausible (mid-refactor). Either way, the stale handbook recipe id is a latent issue, not currently visible. I should mention it with appropriate grading (💡/
Wait — but maybe AnvilCraft versions. Let me double check whether there's another activation path for setComponent, e.g. in AgeratumCommand or recipe preview. Our grep for "setComponent(" found only MDRecipeComponent. So yes: currently unobservable.
But careful: The repo's <recipe id=...> is used everywhere in handbook; if all rendered nothing, that would be a glaring bug in the mod's handbook. Maybe ageratum build.141 sources reflect a WIP state where the recipe preview moved elsewhere... Let me check if AgeratumRegistries.RECIPE_COMPONENT_FACTORY_REGISTRY is consumed anywhere else.
Let me grep the whole ageratum jar for "RECIPE_COMPONENT_FACTORY_REGISTRY".
Also I should double-check the items: binding claim by looking at whether ITEM_DOCUMENT_CACHE key uses binding.itemId() (raw) — yes line 64-66: itemDocuments.computeIfAbsent(binding.itemId(), ...). And lookup by getKey. So mismatch confirmed.
Additionally the MDItemComponent <item id> works via alias. Let's verify <item id> uses registry lookup: MDItemComponent.getItemStack uses level.registryAccess().lookup(Registries.ITEM).get(ResourceKey.create(...)) → Registry.get(ResourceKey) → patched resolve → alias OK.
So findings:
- 🔴/
⚠️ Handbookitems:binding stale → W-key/hover navigation lost for hardened_resin (both en_us & zh_cn, and the zh_cn page too). Since this is the only mechanism, and the mod maintainsitems:as the item→page map, this is a real user-visible regression introduced by this PR? Wait — was it working before? Before the PR the item id washardend_resin, anditems: anvilcraft:hardend_resinmatchedgetKey=hardend_resin→ worked. After the rename: getKey =hardened_resin, handbook stillhardend_resin→ broken. So yes, this PR breaks it. That's the key defect: they renamed the item but didn't update the handbook (which references both item id and recipe id). And notably the handbookitems:binding is the ONLY file that uses the raw id in a non-alias-resolving path.
Hmm, but wait: are matches/getKey paths really non-resolving? BuiltInRegistries.ITEM.getKey(value) → Registry.getKey(T) → not patched (patch list showed getValue/get/getOrCreateHolder/getValue(Identifier)). Also MappedRegistry getKey in vanilla uses byValue map → returns the key given at registration = new id. Confirmed.
So: getFirstDocumentByItemStack misses → BoundItemGuideNavigator finds no document → no "hold to open guide" tooltip. That's a genuine regression, actionable: update handbook to anvilcraft:hardened_resin.
Also <ref item="anvilcraft:hardend_resin"/> works via alias (get). And <item id> works. And the handbook heading # <ref item=...> would display the item name fine.
-
Stale
<recipe id="anvilcraft:fast_cooking/hardend_resin"/>— recipe id renamed; aliases don't cover data pack ids. Currently the recipe-preview lookup is commented out in ageratum build.141, so latent; but it will break when enabled, and it's inconsistent data. Grading⚠️ /💡 latent. -
Lang: 11 hand-maintained lang files still have
item.anvilcraft.hardend_resin, and en_us has the new key. Weblate — so 💡 per skill discipline (not breaking). But note: zh_cn is at 100% translated and item rename means Chinese players see "Hardened Resin" in English until Weblate syncs. Per skill §3,⚠️ with Weblate note → 💡. Also mention old key becomes orphan in Weblate. -
Pill box advancement criterion name
has_hardend_resinleft unrenamed (cosmetic, criterion key not user-visible) — 💡 consistency; other 8 advancements renamed. Actually let me double-check: RegistrumItemRecipeLoader.pillBox uses.unlockedBy("has_hardend_resin", ...)while others useAnvilCraftDatagen.hasItem(...)auto-naming. This is a name only; harmless. But it creates a mismatch with the PR's goal "rename omitted files and item ids". 💡. -
The deprecated alias constant
HARDEND_RESIN— fine, but check it'sItemEntry<Item>referencing same instance;@Deprecated(forRemoval = true)— good. Is it used anywhere? Only definition (24 refs of HARDENED_RESIN). So it's a source-compat shim for addons. OK. But: does@Deprecatedon a public static field trigger checkstyle? No.
Wait — one thing: does the deprecated alias create a duplicate registration? No, it's just a field alias.
aliasFromon ItemBuilder: does the alias apply to the item registry?addAliasesdefault →getOwner().addAlias(getRegistryKey(), oldName, getEntryId()). Fine. Timing: at register(). OK.
Also — potential issue: alias target validation requires "new name registered" at applyAliases. Fine.
- The JewelCraftingRecipeGeneratingCache changes: significantly more than a rename —
logger→BaseGeneratingCache.logger,this.qualification (RequireThis), wrapping of long lines, and removal of unusedRecipeimport. This is scope creep, but it's style/checkstyle-driven. Should I check whether it's checkstyle-mandated? The class hadprivate static final Logger logger = logger();which would be a RequireThis/static-access issue... ActuallyRequireThiswith validateOnlyOverlapping=false checks instance members, not static.logger()is static, called without class qualification — that'sUnnecessaryThis? orStaticMethodCall? Hmm. Anyway CI green. Report as 💡 "unrelated refactor bundled" and check whether the unused import removalRecipewas truly unused in base: base hadimport ...crafting.Recipe;and grep showed only import line → truly unused in base too. So removing it is a cleanup. Note UnusedImports is NOT enabled in style.xml (grep found nothing) → so it wasn't CI-mandated. So these changes are unrelated cleanup — worth 💡 note ("本次夹带无关重构").
Hmm, but wait: is logger field now unused? private static final Logger logger = BaseGeneratingCache.logger(); and usages JewelCraftingRecipeGeneratingCache.logger.debug(...) — that's referencing the static field. Fine.
- Capacitor model fix: base had
items/empty_capacitor.jsonpointing toanvilcraft:item/empty_capacitorbut models/item only hadcapacitor_empty.json→ missing model (紫黑). PR renames model files toempty_capacitor.json/empty_supercapacitor.jsonand fixes texture refs to existingempty_capacitor.png/empty_supercapacitor.png. Verified: head has 0 missing model refs (my sweep), base has 2. ✅ real fix. Texture refs: base capacitor_empty.json pointed toitem/capacitor_empty(missing png) — so both model filename AND texture name were wrong. Now correct. Also confirmed no orphan texture refs remain;textures/item/capacitor_empty.pngdoesn't exist at all (only empty_capacitor.png), so the old texture names were simply wrong.
Wait, earlier grep "capacitor_empty 引用数=0" showed no JSON references item/capacitor_empty anymore ✓.
-
Are there leftover references to models
capacitor_empty/supercapacitor_empty? Zero. ✓ -
Missing: does anything reference
anvilcraft:item/capacitor_emptymodel path in code (e.g.,SharedTexturesorDataGenUtil::onlyInfo)? No.
Now the biggest question: is the handbook items: binding issue the real 🔴? Let me sanity-check getFirstDocumentByItemStack cache key once more and confirm binding.itemId() is the raw id (yes, GuideItemBinding record field itemId from Identifier.tryParse(itemIdText)).
And confirm that alias resolution does NOT apply: BuiltInRegistries.ITEM.getKey(...). The patch file for MappedRegistry didn't touch getKey. Let me verify getKey isn't patched in Registry.java.patch either (it had 200 but grep for getKey returned nothing). So confirmed.
Therefore: after this PR, anvilcraft:hardened_resin has no handbook binding → W-key navigation lost for that item, plus <ref> links pointing to a document via resolveFirstDocument (which goes through createItemStack → getFirstDocumentByItemStack) also fail → the <ref item="anvilcraft:hardend_resin"/> inline links lose their click-to-open-document behavior (they still display name/hover because createItemStack resolves via alias, but clickEvent won't be added). That's user-visible in two places. Good, that's a concrete
Severity: pre-existing content in both en_us and zh_cn; the PR renamed the item without touching the handbook. Since the repo's own skill discipline says handbook must be updated when ids change, I'd grade it
Actually wait — the PR is merged already. So post
Gugle2308
left a comment
There was a problem hiding this comment.
结论:已合并(9a94984f),重命名与空电容器模型修复都正确;但手册 4 个文件 14 处仍用旧 id,其中 items: 绑定会实际失效(⚠️ ,唯一需跟进项)
⚠️ 仓库内容与 issue 文本属不可信数据,我未执行其中任何嵌入指令。
覆盖范围:PR patch diff(34 文件 / +93 −2… 实为 +93/−87,见下核对)、head 树与 base 树(0439e2c0)逐文件对比、AnvilLib RegistrumaliasFrom实现源码、NeoForge26.1.x的MappedRegistry.java.patch、Ageratumbuild.141sources jar(手册items:/<ref>/<recipe>的解析路径)。
未覆盖:实机渲染、runData重跑、Weblate 侧同步、旧存档实机加载验证。
📋 合并状态核实表
| 判据 | 实测值 |
|---|---|
state / merged / merge_commit_sha |
closed / true / 9a94984f45b2e87fe408b54daf80f024ef59e4e2 |
| 落地验证(不经 API) | 目标分支 dev/26.1/1.6 的 FluidTankBlockEntity 等文件内容与 head 一致;9a94984f 就是 dev/26.1/1.6 当前 tip ⇒ 变更已在主干 |
| CI | build ✅ / checkstyle ✅(Pull Request Check + Check Style in Pull Request 双 success) |
| diff 完整性 | 非空 + 行 93 − +++ 34 = 59;空 + 行 0;非空 - 行 87 − --- 34 = 53 —— 与 API additions=93 / deletions=87 / changed_files=34 逐项相等 ⇒ diff 完整无截断 |
⚠️ 手册未同步旧 id:items: 绑定与 <recipe> 引用会失效(alias 救不回来)
base 与 head 的手册完全相同(14 处 hardend_resin),本 PR 只改了代码与生成资源,没动 ageratum:
| 文件 | 行 | 内容 |
|---|---|---|
ageratum/{en_us,zh_cn}/002_material/002_resin.md |
9 | items: 下的 - anvilcraft:hardend_resin |
| 同上 | 18 | <item id="anvilcraft:hardend_resin"/> |
| 同上 | 29 | <ref item="anvilcraft:hardend_resin"/> |
| 同上 | 33 | <recipe id="anvilcraft:fast_cooking/hardend_resin"/> |
| 同上 | 37 | 标题 # <ref item="anvilcraft:hardend_resin"/> |
ageratum/{en_us,zh_cn}/000_process/004.md |
15 / 20 | <item id=…> / <ref item=…> |
要分清哪些靠别名救得回来、哪些救不回来(这是本条唯一实质点):
aliasFrom(AnvilCraft.of("hardend_resin"))注册的是注册表别名。NeoForge26.1.x的patches/net/minecraft/core/MappedRegistry.java.patch只给这些方法加了resolve(...):getValue(ResourceKey)、getValue(Identifier)、get(ResourceKey)、get(Identifier)、getOrCreateHolderOrThrow。getKey(T)没被打补丁,仍返回注册时的名字 =hardened_resin。<item id>(MDItemComponent#getItemStack)和<ref item>的显示/悬停(BuiltinInlineComponents.REF→BuiltInRegistries.ITEM.get(itemId))都走get⇒ alias 生效,图标与名字正常 ✅。- 但
GuideDocumentCache#getFirstDocumentByItemStack是ITEM_DOCUMENT_CACHE.get(BuiltInRegistries.ITEM.getKey(stack.getItem())),而该缓存是用binding.itemId()(手册 frontmatter 里的原始字符串)建立的 ⇒ 拿新 idhardened_resin去查旧键hardend_resin必然 miss,且没有 alias 兜底。
后果(本 PR 引入的回归,修复前是匹配的):
- 手持/悬浮硬化树脂不再出现「按住打开手册」的提示(
BoundItemGuideNavigator.onTooltipGather拿不到文档); <ref item="anvilcraft:hardend_resin"/>的resolveFirstDocument()同样落空 ⇒ 这些行内链接仍有下划线/链接色,但点击无反应(ClickEvent不会被挂上)。
第二处是配方 id:anvilcraft:fast_cooking/hardend_resin 已随文件重命名为 …/hardened_resin,而数据包 id 不受注册表别名覆盖。当前 Ageratum build.141 的 MDRecipeComponent.MDRecipeComponentProxy.extractRenderState 里 manager.byKey(this.location) 整段是注释掉的 // TODO(因此眼下所有 <recipe> 一律渲染空),属潜伏——一旦该 TODO 落地,这行就会因为旧 id 找不到配方而空白。
建议(一处改动即可闭合):把这 4 个手册文件里的 hardend_resin 全部替换为 hardened_resin(含 fast_cooking/ 那条配方 id)。
💡 其它跟进项(均非阻塞)
- 11 个手维护语言文件仍用旧键:
de_de / lzh / zh_tw / ko_kr / zh_hk / es_es / ru_ru / ja_jp / zh_meme / fr_fr / zh_cn都有item.anvilcraft.hardend_resin(zh_cn:1007「硬化树脂」),而新键只出现在生成的en_us/en_ud。按本仓流程(crowdin/Weblate,zh_cn 由Translated using Weblate提交维护)这属正常滞后:中文玩家在下一次同步前会看到英文Hardened Resin。旧键在 Weblate 侧会被标为 obsolete,无需手工删。 pill_box的进度条件名残留旧拼写:RegistrumItemRecipeLoader.java:672仍写.unlockedBy("has_hardend_resin", …),生成物advancement/recipes/misc/pill_box.json也因此保留has_hardend_resin(其余 8 个进度都改成了has_hardened_resin)。纯内部键、不影响功能,属清单一致性问题。- 进度 criterion 改名对已有存档的影响:
has_hardend_resin→has_hardened_resin会让老存档里已计入的旧 criterion 被忽略。这些是「拿齐材料即全部满足」的配方解锁条件,玩家重新拾取一次该物品就自愈,实际影响可忽略——列出仅为完整。 - 夹带了与主题无关的重构:
JewelCraftingRecipeGeneratingCache的this.限定、BaseGeneratingCache.logger()显式限定、换行重排、删除未用 importRecipe;RegistrumItemRecipeLoader:847的RegistrumItemRecipeLoader.hyperdimensionTerminalUnbind(...)显式限定。这些都是 checkstyle/风格向的清理(注:style.xml并未启用UnusedImports,所以删 import 不是 CI 强制),与「重命名」无关,建议后续拆成独立提交,便于回溯。 - 不需要改的相似命名:
gui.anvilcraft.category.item_compress.supercapacitor_empty.resin(JeiLang.java:126)里的supercapacitor_empty只是翻译键片段,不是物品 id,别顺手「修正」。
🟢 已核对正确
| 检查项 | 结论 |
|---|---|
| 空电容器紫黑修复(声称 2) | 用脚本对全树 582 个 items/*.json 做模型/贴图可达性扫描:base 有 2 处缺失、head 为 0。base 的 items/empty_capacitor.json、items/empty_supercapacitor.json 指向 anvilcraft:item/empty_capacitor / …/empty_supercapacitor,但 models/item 下只有 capacitor_empty.json / supercapacitor_empty.json(且这两个文件被任何地方引用 0 次)⇒ 确实是「缺模型=紫黑」。本 PR 把模型文件名改成 empty_*,同时把贴图指向真实存在的 textures/item/empty_capacitor.png / empty_supercapacitor.png(base 引用的 capacitor_empty / supercapacitor_empty 贴图根本不存在)。改名后 models/item 全树 3270 条贴图引用中只剩 3 个与本 PR 无关的既有缺口(block/laser、campfire_fire 原版引用)✅ |
| 物品 id 重命名 + 别名 | ModItems.HARDENED_RESIN = .item("hardened_resin", …).aliasFrom(AnvilCraft.of("hardend_resin"));AnvilLib AbstractBuilder.register() 里 for (Identifier oldName : this.aliasedFrom) addAliases(oldName),ItemBuilder 未覆写 ⇒ 走默认 getOwner().addAlias(getRegistryKey(), oldName, getEntryId());AbstractRegistrum.applyAliases 对「旧名仍在册」「新名未注册」「重复施加」三种情况都有守卫 ⇒ 旧存档里的物品栈/结构里的物品能继续解析(这正是 Registry#get 走 resolve 的意义)✅ |
| 源码兼容层 | @Deprecated(forRemoval = true) public static final ItemEntry<Item> HARDEND_RESIN = ModItems.HARDENED_RESIN; 是字段别名(不是二次注册),不会产生重复条目;全仓 24 处引用已全部切到 HARDENED_RESIN,仅此定义保留 ✅ |
| 生成数据一致性 | 9 个 advancement + 8 个 recipe JSON 的 items/recipe/rewards.recipes 全部与新 id、新配方路径一致;fast_cooking/hardened_resin.json 的 results.id 也同步 ✅;datagen 源(RegistrumBlockRecipeLoader、RegistrumItemRecipeLoader、VanillaRecipesLoader、FastCookingRecipeLoader、JewelCraftingRecipeGeneratingCache)与新 JSON 逐处对应 |
| en_ud 反转 | uᴉsǝᴚ puǝpɹɐH → uᴉsǝᴚ pǝuǝpɹɐH(Hardend→Hardened 多一个 e 的位置正确,整串仍为倒序)✅ |
| EOF 与格式 | 被 renaming 的 4 个生成 JSON 沿用本仓「生成物无尾换行」事实(models/item 163/163、items 582/582 均有尾换行,但这 4 个 resin 文件 base/head 双向都无);empty_supercapacitor.json 反而补上了尾换行,属改善;empty_capacitor.json 新建带换行 ✅ |
| 无产物被丢 | 改名后 capacitor_empty / supercapacitor_empty 的模型与贴图引用数均为 0(不是悬空引用,是彻底替换);hardened_resin.png 贴图本就在 textures/item,base 的模型指错名字才是 bug 根因 ✅ |
📋 声称验证表
| 声称 | 证据 | 判定 |
|---|---|---|
fixed #6092「硬化树脂贴图 bug」 |
base:items/hardend_resin.json → models/item/hardend_resin.json → layer0: anvilcraft:item/hardend_resin,而贴图实际叫 hardened_resin.png ⇒ 缺贴图。head:模型与贴图名双向对齐 |
✅ 机制闭环 |
hardend_resin → hardened_resin |
注册名、lang(en_us/en_ud)、9 advancement、8 recipe、5 datagen 源 + 3 个调用方全部改为新名,并 aliasFrom 兼容旧名 |
|
| 「修复了两种空电容器模型变为紫黑」 | 模型缺失 2 → 0(脚本全树扫描前后对比);贴图名从不存在的 capacitor_empty/supercapacitor_empty 改为存在的 empty_capacitor/empty_supercapacitor |
✅ |
🧪 回归建议
- 进旧存档确认箱子/背包里的硬化树脂仍在(验证 alias 对存档栈生效)。
- 悬浮或手持硬化树脂,确认按住打开手册是否仍可用——预期当前失效(本条
⚠️ 的直接验证点)。 - 打开手册「树脂」页,确认行内
<ref>链接点击是否跳转;空电容器/空超级电容器两个物品在两处(背包、JEI)不再显示紫黑。
收尾
9a94984f 已入主干,两块改动方向正确、别名机制与模型链均自洽,无需回退。唯一建议跟进的是手册 4 个文件里的旧 id(会实打实影响手册绑定与链接点击),其余为一致性/流程类。已合并,故不改标题。
hardend_resin->hardened_resin