Repository navigation
[26.2] Share structure previews 共用结构渲染与只读界面预览 - #288
Merged
Merged
Conversation
- 迁移隔离结构沙盒、相机拾取与原生界面浮窗 - 提供自定义界面注册和附加渲染接口,解除对手册的依赖 - 适配当前游戏版本的渲染与透明度补丁 - 补充通用翻译、接口说明及只读作用域回归检查
🌿 Roseau API Breaking Change Report
|
Gugle2308
reviewed
Nov 14, 2026
Gugle2308
left a comment
There was a problem hiding this comment.
结论:PR #288 已合并(squash c0e0d4c8 之后的 dev/26.2,合并树与 head ce0aacc7 完全一致,2026-11-14T18:43:36Z)。26.2 的 6 处注入逐一用未混淆 client.jar 核对通过;其中两处 @ModifyArgs 已正确跟上 26.2 的关键 API 漂移——规范构造器改取 Matrix3x2fc(接口)而非 Matrix3x2f,且 PictureInPictureRenderer 构造器变成无参、textureView 走既有 AT 放宽——三处都对上了。需要跟进的是「光照设置在空 level 早退之前执行且不再恢复」「PiP 内复用真实相机剔除实体」「getSeaLevel() 与 1.21.x 线不一致」三点。
一、合并态与范围
| 判据 | 结果 |
|---|---|
| state / merged / merged_at | closed / true / 2026-11-14T18:43:36Z |
| base / 合并树 vs head | dev/26.2 / 空 diff ⇒ 进主干的就是 ce0aacc7 |
| 规模 | 34 文件 +3295/−0,与收到的 diff 一致 |
| head CI | build / build ✅ |
| 既有评论 | 仅 Roseau API 报告 |
| 语言文件 | en_us / en_ud / zh_cn 各 107 条 ✅ |
二、注入点与 PiP API 逐条核实(26.2 未混淆 jar)
| 注入 / 依赖 | 核对结果 |
|---|---|
innerBlit(RenderPipeline, GpuTextureView, GpuSampler, IIII, FFFF, I) ordinal=4 |
类里两个重载(Identifier 版 code=46、GpuTextureView+GpuSampler 版 code=57),mixin 用完整描述符锁定后者 ✅;ordinal=4 = 第 5 个 int = color ✅ |
innerFill(…, IIIII, Integer) 两个 handler |
单重载(code=59)⇒ ordinal=4 = color ✅;尾部 Integer handler 匹配渐变参数 ✅ |
innerTiledBlit(…, IIIIII, FFFF, I) ordinal=6 |
code=61;7 个 int(6 坐标 + color)⇒ ordinal=6 = 第 7 个 = color ✅ |
text(Font, FormattedCharSequence, IIIZ) ordinal=2 |
text 有 4 个重载(String/Component × III/IIIZ 形态),mixin 按描述符锁定 IIIZ(code=53)✅;ordinal=2 = 第 3 个 int = color ✅ |
Screen.extractBackground(GuiGraphicsExtractor, int, int, float) |
public code=56 ✅ |
RecipeBookComponent.isVisibleAccordingToBookData()Z |
private code=15 ✅ |
BlitRenderState.<init> 14 参 + args.set(11, …) |
该类有两个构造器:13 参 Matrix3x2f 版与 14 参 Matrix3x2fc 版;mixin 精确指向后者 ✅。字节码显示 GuiRenderer.submitBlitFromItemAtlas 与 PictureInPictureRenderer.blitTexture 各自只调用一次该 14 参构造器 ⇒ 命中唯一,index 11 = int color ✅ |
PictureInPictureRenderer 无参构造器 |
26.2 改为 ()V public(26.1 是 (MultiBufferSource$BufferSource))⇒ StructureRenderEvents.register(State.class, StructurePreviewPipRenderer::new) 与「类里不写构造器」一致 ✅ |
renderToTexture(T, PoseStack, SubmitNodeCollector) |
基类 abstract ✅,签名与 override 一致;blitTexture(T, GuiRenderState) protected code=73 ✅ |
this.textureView 访问 |
字段在 jar 里是 private,由既有(base 上就有,第 24 行)module.rendering/.../accesstransformer.cfg 的 public … PictureInPictureRenderer textureView 放宽 ⇒ 合法 ✅ |
三、需要跟进(合并后)
- 光照设置发生在空 level 早退之前,且不再恢复:
renderToTexture首行就是mc.gameRenderer.lighting().setupFor(Lighting.Entry.LEVEL),随后才if (mc.level == null) return;——即「什么都没画却已改掉全局光照入口」;而 1.21.x / 26.1 版本会保存并恢复RenderSystem.setShaderLights(previousLights),26.2 版完全没有恢复动作。若 26.2 的 feature 渲染并非在提交几何时烘焙光照,这段会把Lighting.Entry.LEVEL的平行光状态泄漏给同帧后续的 GUI/世界绘制。建议:把setupFor移到 null 检查之后,并在finally中恢复(或注释说明 26.2 为何无需恢复)。 - PiP 内复用真实世界相机剔除实体(与 1.21.8 / 1.21.11 / 26.1 同源):
gameRenderer.gameRenderState().levelRenderState.cameraRenderState被传给entityRenderDispatcher.submit(...)与blockEntityRenderer.submit(...),实体裁剪距离、shouldRender、阴影判定都按玩家真实视角算 ⇒ 结构里位于玩家背后或超视距的实体不出现在预览窗。建议构造与预览state.transform()对齐的相机状态。 - 跨线海平面不一致(已实测):本线
getSeaLevel()返回 0,而dev/1.21.8上的同文件返回 63(26.1 也是 0);getBlockTint(...)恒-1、cardinalLighting()恒CardinalLighting.DEFAULT。渲染走ProjectionScene(mc.level)暂时绕开了它,但任何以后直接把沙盒当BlockAndTintGetter用的扩展会拿到「无生物群系染色 + 默认朝向光照 + 海平面 0」。 - 对既有 AT 的硬依赖需要写明:
Effects.render把GpuTextureView交给调用方,其取用依赖accesstransformer.cfg第 24 行放宽的PictureInPictureRenderer.textureView。该行不在本 PR 范围内(base 已有),但只要它被清理或上游改字段名,本模块立刻编译失败——建议在该 AT 行与blitTextureoverride 各留一句用途注释。 defaultRequire: 1+required: true下 pin 死 record 构造器没有运行时保险:两个@ModifyArgs精确绑定 14 参构造器,而build/previewTest不加载 mixin,CI 绿不证明命中(本次由字节码手工证)。这一族的风险已被本 PR 自己证明是真实的——26.1→26.2 就把构造器的Matrix3x2f换成了Matrix3x2fc,照抄上一线就会静默失配。建议对这两个纯视觉注入加require = 0。createClientClockManager在注册表缺席时静默无时钟(同 26.1):registryAccess.lookup(Registries.WORLD_CLOCK)为空时clockManager无任何时钟数据、无日志;依赖clockManager()的渲染会拿到空/默认值。建议补一条一次性 warn。- 每帧新建三个渲染器对象:
new ProjectionScene(...)、new ModelBlockRenderer(...)、new FluidRenderer(...)每帧一次,建议提到字段(ambientOcclusion变更时重建)。 - 混合层流体对
ChunkSectionLayer.values()逐个提交 3 次:每次submitCustomGeometry只让一个层收到顶点,另两次为空缓冲;可改成只按fluidModels.get(fluid).layer()提交一次,减少无效几何缓冲。 mixins.json的compatibilityLevel本线也是JAVA_8(1.21.1 / 1.21.4 / 1.21.8 为JAVA_21)——既有配置,新增 6 个 mixin 后建议跨线统一。- 既有项(跨线通病):
getFilledBlocks()返回复用的MutableBlockPos;StructureGuiProviders.register冲突直接抛IllegalStateException(客户端初始化期);StructureBlockEntityDetails.describe/StructureDetailsPager仍无生产调用方(107×3 条 lang 随之闲置)。
四、与 26.1 的差异对照(26.2 适配点,均已核实)
| 维度 | 26.1 | 26.2(本 PR) |
|---|---|---|
BlitRenderState 规范构造器 |
Matrix3x2f |
Matrix3x2fc(接口)⇒ 描述符必须同步,作者已改对 ✅ |
| PiP 构造器 | (MultiBufferSource$BufferSource) |
无参 ()V ✅ |
| 纹理提交 | collector 由方法参数传入 |
同(renderToTexture(T, PoseStack, SubmitNodeCollector)) |
| 覆盖效果入口 | Effects.render(State) |
Effects.render(State, GpuTextureView, GuiRenderState),在 blitTexture 里 super 之后调用 ✅ 与 README「26.2/26.3 收到已完成纹理」一致 |
| 光照 | RenderSystem.getShaderLights() 保存/恢复 |
gameRenderer.lighting().setupFor(...),无恢复 |
| 实体加载 | EntityType.loadEntityRecursive(data, level, EntitySpawnReason.STRUCTURE, …) |
new EntitySpawnRequest(EntitySpawnReason.STRUCTURE, true) ✅ |
| chunk/pos 工具 | ChunkPos.asLong/pack |
ChunkPos.pack/containing ✅ |
| 表面选择 | Sheets.translucentBlockSheet()/cutoutBlockSheet() |
Sheets.translucentBlockItemSheet()/cutoutBlockItemSheet() ✅ |
| 语言 / mixin 配置 | 107 × 3 / JAVA_8 |
同 ✅ |
五、验证边界
未执行 Gradle 构建、runClient 与游戏内实测(PR 自述「客户端画面尚未实测」);previewTest 只覆盖 provider 注册、renderOnly 嵌套/异常恢复与缓动函数,不加载 mixin、不渲染。本文结论来自静态读码 + 26.2 未混淆 client.jar 的方法表与字节码(上表逐项给出描述符/code=/构造器调用唯一性)、accesstransformer.cfg 逐行核对(确认 textureView 的放宽在 base 上已存在)+ 合并树/head 对账 + head CI + 三份 lang 键数比对 + 1.21.8 线的 getSeaLevel() 实测对照。建议实机补测:真实容器屏在不同 GUI scale 下的浮窗裁剪与层级、F3 隐藏 GUI、结构内实体位于玩家背后/远处的可见性(第三节第二条)、大尺寸物品淡出、时钟/时间相关渲染,以及同一结构在 26.1 与 26.2 上的观感一致性(光照与海平面两处差异最可能表现为「版本间看起来不一样」)。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
将结构渲染、隔离沙盒、相机拾取和只读 GUI 浮窗移入砧库,让手册与机器界面共用实现,避免机器功能依赖手册模组。
验证:
:anvillib-rendering-neoforge-26.2:build(含previewTest)与git diff --check通过;已对照当前版本源码核查 Mixin 目标。客户端画面尚未实测。