Skip to content

Fix creative section rendering 修复创造栏分区显示与提示框层级(1.21.11) - #158

Merged
PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21.11from
WhereisFff:codex/1.21.11-section-5315
Oct 20, 2026
Merged

PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21.11from
WhereisFff:codex/1.21.11-section-5315

Conversation

@WhereisFff

Copy link
Copy Markdown
Contributor

fix(registrum): 修复创造栏分区显示与提示框层级

  • 在配方查看器绘制前景前绘制创造栏分区,避免配方收藏预览导致分区消失
  • 移除分区额外的渲染高度与层级提升,防止遮挡配方查看器提示框
  • 保留分区悬停提示、长文本滚动及变体选择交互

- 在配方查看器绘制前景前绘制创造栏分区,避免配方收藏预览导致分区消失
- 移除分区额外的渲染高度与层级提升,防止遮挡配方查看器提示框
- 保留分区悬停提示、长文本滚动及变体选择交互
@Gugle2308

Copy link
Copy Markdown

已完成取证审查(diff md5 稳定、head 未前进、PR 仍 open)。以下是审查意见。


代码审查摘要 — PR #158 · Fix creative section rendering 修复创造栏分区显示与提示框层级(1.21.11)

状态: open(未合并)|head: db5adcb(与 refs/pull/158/head 一致,审查期间未前进)|CI: head 上 workflow runs 仍在跑(conclusion=null),本次结论为静态审查
范围: 2 个文件 / +40 −9(1 新增 35 行,1 修改 +5/−9)
基准: dev/1.21.11 @ 9bfc393(NeoForge 21.11.40-beta / MC 1.21.11)

📋 声称验证表

PR 声称 状态 证据
在配方查看器绘制前景前绘制创造栏分区,避免分区消失 ✅ 新增 @EventBusSubscriber 监听 ContainerScreenEvent.Render.Foreground(EventPriority.HIGHEST),分区绘制不再依赖 renderTooltip 是否被调用
移除分区额外的渲染高度与层级提升 ✅ CreativeModeInventoryScreenMixin#anvillib$renderSection 删除 graphics.nextStratum();新增监听器也不再提升 stratum
保留悬停提示 / 长文本滚动 / 变体选择交互 ✅ anvillib$renderBannerText(滚动、scissor)与 anvillib$renderTooltips(setTooltipForNextFrame)逻辑零改动;命中判定仍用绝对 mouseX/mouseY

🔍 关键正确性取证(本 PR 的核心风险点,均已排除)

  1. translate(-getGuiLeft(), -getGuiTop()) 的补偿是正确的。ContainerScreenEvent.Render.Foreground 在 NeoForge 1.21.11 分支的 patch 中是在 pose().popMatrix() 之前 post 的,即处于容器平移矩阵内部;而 vanilla 的平移量恰为 translate((float)leftPos, (float)topPos)(已用 26.1 client jar 字节码核对同一 extractContents 结构:pushMatrix → translate(leftPos, topPos) → labels → hoveredSlot → popMatrix)。因此 −left/−top 恰好把 pose 还原到绝对坐标,与 anvillib$renderSection 中 bannerX = this.leftPos + GRID_LEFT - 1 的绝对坐标假设一致。✅
  2. registrum 模块没有 @Mod 类,@EventBusSubscriber 仍会被注册。这是本 PR 最隐蔽的坑(Registrum.create(modid) 是纯库模式,module.registrum 内无 @Mod)。已核 FML FMLModContainer 字节码:modClasses 循环以 ifeq → 364 结束后,AutomaticEventSubscriber.inject(...) 调用点位于 370 之后(循环外),故无 @Mod 类也会注入。✅
  3. modid 字符串正确:module.registrum/gradle.properties → mod_id=anvillib_registrum,且该模块在 module.main 中是 jarJar 独立嵌套 jar ⇒ 独立 mod 文件,事件扫描覆盖其类。✅
  4. 服务端安全:value = Dist.CLIENT + 该类只被 client mixin(implements)引用,专用服务器不加载、注解扫描阶段即按 Dist 跳过。✅
  5. 去掉 nextStratum() 不会让物品图标盖住横幅:CreativeTabSections.arrange() 为横幅格填入的是 ItemStack.EMPTY(for cell < bannerLength: arranged.add(ItemStack.EMPTY)),横幅不需要压物品;槽位背景/高亮在同一 stratum 更早提交,仍会被横幅覆盖。✅
  6. @Unique 的移除是必须且正确的:方法现在实现 mixin 注入到目标类的接口方法,保留 @Unique 会导致 Mixin 改名从而破坏接口契约。✅

⚠️ 警告

  • module.registrum/.../registrum/client/ 新建包缺 package-info.java — 本 PR 新建了 client 包(base 上只有 client/gui),但 module.registrum 现有 19/20 个包都带 @NullMarked 的 package-info.java(client/gui、mixin/client 都有)。建议补一个,保持 JSpecify 全包标注一致:
    @NullMarked
    package dev.anvilcraft.lib.v2.registrum.client;
    import org.jspecify.annotations.NullMarked;
  • Renderer 接口的调用契约是隐式的 — anvillib$renderSections 内部用绝对屏幕坐标,只有「在容器相对 pose 下被调用」时才正确;但 Renderer 是 public 接口,任何调用方从绝对 pose 调用都会整体偏移 (leftPos, topPos)。建议在接口 javadoc 明确写「实现方按绝对屏幕坐标绘制,调用方负责提供容器相对 pose」,或把 translate 收进 mixin 侧(接口方法改为无坐标假设、由 mixin 自己补偿),避免库使用者误用。

💡 建议

  • @EventPriority.HIGHEST 值得一行注释:只有在「同一 Foreground 事件上有其它监听者(配方查看器等)」时 HIGHEST 才有意义;换到 ScreenEvent.Render.Post 上渲染的查看器与本优先级无关。写明意图可防止后人误降优先级。
  • modid 建议走常量:其它模块统一 modid = AnvilLibXxx.MOD_ID,registrum 目前没有 MOD_ID 常量(Registrum.create(modid) 模式)。字符串一处拼错会静默不注册,建议在 Registrum 内加 public static final String MOD_ID = "anvillib_registrum" 并引用。
  • 命名:CreativeTabSectionRenderListener.Renderer 与 net.minecraft.client.renderer 语义易混,可考虑 SectionRenderer / CreativeTabSectionRenderable。
  • 层级策略不一致:CreativeVariantPickerOverlay(nextStratum() × 3)仍保留提升层级,而分区不再提升。当前组合是正确的(overlay 在 renderTooltip 更晚绘制、层级更高),但两处策略相反,建议在 renderSection 处补一句注释说明「横幅格为空格,无需 stratum」。

🟢 看起来不错

  • 改动面极小且精准:新增 1 个监听器 + 移除 1 处调用 + 1 行 nextStratum,没有顺手重构。
  • pushMatrix()/popMatrix() 用 try/finally 包住,异常路径不会污染 pose 栈。
  • 工具类 final + 私有构造,事件方法 static,符合 @EventBusSubscriber 约定。
  • 修复思路正确:分区绘制从「依赖 renderTooltip 调用链」改为「依赖容器屏幕渲染主流程的事件」,对配方查看器接管 tooltip 渲染的场景是更稳的挂载点。

🧪 测试建议

被测目标 场景 优先级
分区绘制 无配方查看器 / EMI / JEI 三种环境下打开带分区的创造栏,分区均可见 🔴
分区 + 收藏预览 打开配方查看器的收藏/预览面板时分区不消失,且其 tooltip 不被横幅遮挡 🔴
变体选择器 分区横幅叠层变化后,右键变体面板、拖拽物品、hover 高亮层级仍正确 🟡
专用服务器 runServer 启动不因新监听器/接口加载失败(Dist.CLIENT 过滤) 🟡

结论: COMMENT(可以合并,无阻塞项) — 三处层级/时序改动的关键假设(Foreground 处于容器平移矩阵内、无 @Mod 类仍注入订阅者、横幅格为空格)我都做了字节码/patch 级验证,均成立。仅剩新建包缺 package-info.java 与接口契约文档化两个非阻塞项。

标题建议(现标题基本准确,仅英文略泛):Fix creative tab section z-order and tooltip layering 修复创造栏分区层级与提示框遮挡(1.21.11)。本次因 gh auth status 显示 token 失效(The token in /opt/data/home/.config/gh/hosts.yml is invalid),按规程未尝试导出凭据,故未自动修改标题。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown

💾 Self-improvement review: Patched references/gui-render-phase-pose-and-zdepth.md in skill 'menu-widget-interaction-pr-review' (1 replacement). · Patched SKILL.md in skill 'menu-widget-interaction-pr-review' (1 replacement).

@PigeonNian
PigeonNian merged commit 311daa5 into Anvil-Dev:dev/1.21.11 Oct 20, 2026
41 checks passed
@Gugle2308

Copy link
Copy Markdown

PR #158 状态为 closed,按 webhook 审查规则(closed/labeled → stop),本次不做审查、不输出审查意见。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants