Skip to content

Add client projection renderer module 新增客户端投影渲染模块 - #126

Merged
Gu-ZT merged 1 commit into
dev/1.21.1from
fff/renderer
Sep 22, 2026
Merged

Gu-ZT merged 1 commit into
dev/1.21.1from
fff/renderer

Conversation

@WhereisFff

Copy link
Copy Markdown
Contributor

No description provided.

@Gugle2308

Copy link
Copy Markdown

🌿 Roseau API Breaking Change Report

Module Status Breaking Changes
codec ⚪ Skipped
collision ⚪ Skipped
cube ⚪ Skipped
config ⚪ Skipped
integration ⚪ Skipped
moveable-entity-block ⚪ Skipped
network ⚪ Skipped
rendering ⚪ Skipped
space-select ⚪ Skipped
font ⚪ Skipped
util ⚪ Skipped
explosion ⚪ Skipped
rpc ⚪ Skipped
math ⚪ Skipped
multiblock ⚪ Skipped
recipe ⚪ Skipped
registrum ⚪ Skipped
sync ⚪ Skipped
wheel ⚪ Skipped
main ⚪ Skipped

Full CSVs: see the Artifacts section of this workflow run.

@Gugle2308

Copy link
Copy Markdown

核查已完成(diff 分析 + 1.21.1 官方 mappings/字节码 + NeoForge 21.1.226 实测 + 与 AnvilCraft 现存同源实现逐行对账)。以下是审查意见:


代码审查摘要 — PR #126 投影模块(AnvilLib)

操作: opened | 范围: 23 个文件(19 新增 / 4 修改 / 0 删除),+1247 / −1 行
内容: 新增 module.rendereranvillib_renderer)——独立客户端投影渲染模块:ProjectionScene(219)、ProjectionRenderer(139)、ProjectionRenderTypes(48)、ProjectionShaders(40)、GhostConsumer(42) + 着色器 projection.fsh/.json + AT 5 行 + clientTest 回归测试(187) + 隐藏窗口 mixin + 构建/CI 接线。

🔴 关键

无。逐项核验了 1.21.1 的 API 存在性、AT 目标、Mixin 注入点与着色器一致性,未发现会导致编译失败、崩溃或功能失效的问题。(预判中的两个高风险项均已排除:① MeshData 未显式 close 不是泄漏 —— VertexBuffer.upload(MeshData) 字节码内含 MeshData.close() ×3;② 实体用 entity.getX()(绝对坐标)传入 EntityRenderDispatcher.render 不是错位 —— 该 API 语义是「场景坐标 + 调用方 pose」,与烘焙网格(pos + 0..1)使用同一坐标空间,AnvilCraft 消费端 BuildingRodRenderer 正是把实体变换到同一局部空间后 addEntity。)

⚠️ 警告

  1. module.renderer/build.gradle:280-286 把 cube 的本地测试钩子整段复制,属性名仍是 cube 专属的 cubeLocalTests / cubeClientSmoke Gradle -P 属性是全局的:一旦有人按 cube 既有流程执行 ./gradlew … -PcubeLocalTests,本模块也会进入该分支,而 module.renderer/local-tests.gradle 永远不存在 → 直接 throw new GradleException('本地测试脚本 local-tests.gradle 不存在…'),配置阶段即失败,会把 cube 的本地测试流程整体打断(连 cube 自己的任务也跑不了)。本模块已有 -PprojectionTest,建议删掉这 7 行或改成 renderer 专属属性名。
  2. 新增的投影回归测试在 CI 中永远不会执行。 client-test.gradle 只在 -PprojectionTest 存在时才 apply(build.gradle:271),而 .github/workflows/build_and_test.yml 只跑 ./gradlew :anvillib-renderer-neoforge-1.21.1:build,全仓库无任何工作流传递该属性(已 grep 确认),且 sourceSets.test 被清空 → 187 行测试 + mixin + PROJECTION_TEST ALL PASS/FAILED 日志门禁只存在于手工环境,腐化无人兜底。建议二选一:a) 加 CI 任务(xvfb-run -a ./gradlew :anvillib-renderer-neoforge-1.21.1:runProjectionTest -PprojectionTest);b) 在 README/CONTRIBUTING 写明手工命令并注明为何不进 CI(需 GL 上下文)。
  3. README 未同步。 中文 README「Main 模块」的子模块清单是全量的(codec…wheel 共 18 项),main 现已多打包/重导出 renderer,清单失真;「按需引入单独模块」示例亦缺 anvillib-renderer-neoforge-1.21.1。(README.en.md 对应清单原本只列 8 项,可另议。)

💡 建议

  1. ProjectionRenderer.close() 缺少 RenderSystem.assertOnRenderThread()rebuild()/render() 都有断言,而 VertexBuffer.close() 直接调用 glDeleteBuffers/glDeleteVertexArrays(已在 1.21.1 客户端字节码确认无任何线程守卫),非渲染线程 close 会静默破坏 GL 状态。类注释已声明 render-thread-only,建议把断言补齐到 close()
  2. isValid() 无法区分「着色器尚未加载」:generation 初值 0,ProjectionShaders.generation() 只在注册回调里自增,故着色器加载前(或加载失败)烘焙的网格会被判为有效;此时 ShaderStateShard supplier 返回 null 会跳过 RenderSystem.setShader,而 render()RenderSystem.getShader() 绘制 → 用上一次绑定的着色器画网格(画面错乱而非崩溃)。加 shader != null && 即可消除该失败模式。
  3. ProjectionSceneminY/maxY 以 0 为初值,只反映插入过的方块:方块全在 y>0(如仅 y=5..7)时 getMinBuildHeight()=0、getHeight()=8,与实际内容不符(当前因 isOutsideBuildHeight 恒 false、无人建 section 而无害;Shifted 反而修正了 getMinBuildHeight 偏移)。首次 put 时初始化语义更干净。
  4. rebuild()view.positions() 调用两次(烘焙循环 + 收集方块实体),各产生一次 stream+list;给场景加 blockEntities() 访问器或单次遍历可省重复工作。
  5. GhostConsumer.setUv2() 忽略入参恒 (240,240)setColor() 恒定覆盖 alpha 为 opacity —— 有意的「全亮 + 统一虚影透明度」(与上游一致),建议补一行注释说明忽略原因,避免后续被当作 bug「修掉」。

🟢 看起来不错 / 交叉验证

  • 与仓库外 AnvilCraft 现网实现同源且一致:AT 5 行与 AnvilCraft/src/main/resources/META-INF/accesstransformer.cfg:47-51 逐行相同(仅去行尾注释);projection.fsh 与 AnvilCraft building_rod_ghost.fsh 逐字节一致projection.jsonfragment 命名空间不同;ProjectionRenderTypes.translucent()RenderSupport.useTranslucentIfPossible() 判断链(CompositeRenderTypetransparencyState == NO_TRANSPARENCYtextureState instanceof TextureStateShardtexture.map(entityTranslucentCull).orElse(original))逐条等价。
  • 相比 AnvilCraft 原实现的改进rebuild() 捕获 RuntimeException|Error 后先 close() 再抛(不留半初始化网格);setupRenderState/bind 用 try/finally 保证 unbind+clearRenderStateclose() 幂等(有测试);put(pos,state,null) 清除陈旧方块实体(有测试);alpha 0..255 校验;着色器 generation 计数使资源重载后网格自动失效;tint 回调泛化为世界坐标并保留 level::getBlockTint 默认路径。
  • API 存在性逐项实测(1.21.1 官方 client_mappings + 混淆客户端字节码 + NeoForge 21.1.226 universal jar):
待核验 结论
CompositeRenderType.state()CompositeState.textureState/transparencyStateTextureStateShard.texture(Optional) ✅ 均存在,AT 目标与描述符正确
VertexBuffer.upload(MeshData) 是否接管 MeshData.close() ✅ 接管(字节码 close() ×3),无原生内存泄漏
renderBatched(9 参, ModelData+RenderType) / renderLiquid(5 参) ✅ 与 NeoForge 1.21.1 签名一致(AnvilCraft 1.21.1 同写法)
BakedModel.getRenderTypes(state,random,data)ChunkRenderTypeSet ✅ 可 for-each 为 RenderType
BlockAndTintGetter 抽象方法集(3+3+2) ✅ ProjectionScene 全覆盖;getShade(FFFZ)IBlockAndTintGetterExtension 提供
RenderSystem.assertOnRenderThread/getModelViewMatrix/getShaderdrawWithShader
RegisterShadersEvent.registerShaderModelEvent.BakingCompletedClientTickEvent.PostRenderLevelStageEvent.Stage
Window.<init>GLFW.glfwDefaultWindowHints() ✅ 唯一命中,@At(INVOKE, shift=AFTER) 注入点有效
WorldOpenFlows.createFreshLevel(5)/LevelSettings(7)/Block.shouldRenderFace(5)/BlockPos.of(long) ✅ 签名匹配
  • 规模/卫生:19 新增 0 删除;No newline at end of file 0 处;无 TODO/FIXME/调试输出/凭据;@NullMarked + 仅 org.jspecify.annotations(合 AGENTS.md);公共面收敛为 ProjectionScene/ProjectionRenderer,渲染类型/着色器/消费者均包私有。
  • 构建与发布接线一致settings.gradle include + 构件重命名;.github/modules.jsongenerate-matrix.js 据此生成 build-l0 矩阵、deploy-l0 与 roseau 检查,anvillib-renderer/anvillib_renderer 与推导规则吻合);roseau_comment.yml MODULES 列表;module.main/build.gradle 两处依赖块(发布坐标 + project 坐标)对称补齐。

📋 声称验证表

PR 描述为空(body: null),无 checklist 可比对;按标题「投影模块」对 diff 做映射核对:

应有内容 状态 对应文件
模块骨架/元数据 AnvilLibRenderer、package-info ×2、gradle.properties、neoforge.mods.toml
场景/邻接视图 ProjectionScene(含 Shifted 视图)
网格烘焙与绘制 ProjectionRenderer、GhostConsumer
渲染类型与着色器 ProjectionRenderTypes、ProjectionShaders、projection.fsh/.json、accesstransformer.cfg
回归测试实现 ProjectionTest、HiddenWindowMixin、projection_test.mixins.json、client-test.gradle
测试在 CI 执行 无工作流传 -PprojectionTest⚠️2)
构建/CI 接线 settings.gradle、.github/modules.json、roseau_comment.yml、module.main/build.gradle
文档同步 README 未更新(⚠️3)

🧪 测试建议

  • rebuild() 异常路径(烘焙中途抛异常 → mesh 为 null 且 isValid()==false)无覆盖;
  • ProjectionScene.getBlockTint默认构造器路径(level::getBlockTint + tintPos 偏移)未断言,仅覆盖了自定义回调;
  • ProjectionRenderTypes.ghost() 的缓存分支(非 solid/cutout/translucent → entityTranslucentCull)与 128 上限清理未覆盖;
  • render()isValid()==false 时应为 no-op(断言不抛异常即可)。

结论: COMMENT — 实现质量高,AT/着色器/API/Mixin 目标均经实机核验,可以合并;建议合并前顺手处理 ⚠️1(cube 属性泄漏有跨模块负面影响),⚠️2/⚠️3 可另开小 PR。另:PR 描述为空,建议补一段模块用途与 -PprojectionTest 用法说明。

标题建议Add client projection renderer module 新增客户端投影渲染模块
gh auth status 显示 token 已失效:The token in /opt/data/home/.config/gh/hosts.yml is invalid,按规程未导出凭据、未自动改标题;修复认证后我可执行 gh pr edit 126 --title …。)


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown

💾 Self-improvement review: Patched SKILL.md in skill 'offline-pr-evidence-verification' (1 replacement). · Patched references/new-module-and-ci-verification.md in skill 'github-webhook-pr-review' (1 replacement). · Patched references/pr-class-routing.md in skill 'github-webhook-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown

🌿 Roseau API Breaking Change Report

Module Status Breaking Changes
codec ✅ Compatible 0
collision ✅ Compatible 0
cube ✅ Compatible 0
config ✅ Compatible 0
integration ✅ Compatible 0
moveable-entity-block ✅ Compatible 0
network ✅ Compatible 0
rendering ⚪ Skipped
space-select ✅ Compatible 0
font ✅ Compatible 0
util ✅ Compatible 0
explosion ✅ Compatible 0
rpc ✅ Compatible 0
math ⚪ Skipped
multiblock ⚪ Skipped
recipe ⚪ Skipped
registrum ⚪ Skipped
sync ⚪ Skipped
wheel ⚪ Skipped
main ⚪ Skipped

Full CSVs: see the Artifacts section of this workflow run.

@Gugle2308

Copy link
Copy Markdown

🌿 Roseau API Breaking Change Report

Module Status Breaking Changes
codec ✅ Compatible 0
collision ✅ Compatible 0
cube ✅ Compatible 0
config ✅ Compatible 0
integration ✅ Compatible 0
moveable-entity-block ✅ Compatible 0
network ✅ Compatible 0
rendering ⚪ Skipped
space-select ✅ Compatible 0
font ✅ Compatible 0
util ✅ Compatible 0
explosion ✅ Compatible 0
rpc ✅ Compatible 0
math ✅ Compatible 0
multiblock ✅ Compatible 0
recipe ✅ Compatible 0
registrum ✅ Compatible 0
sync ✅ Compatible 0
wheel ✅ Compatible 0
main ✅ Compatible 0

Full CSVs: see the Artifacts section of this workflow run.

@Gu-ZT Gu-ZT changed the title 投影模块 Add client projection renderer module 新增客户端投影渲染模块 Sep 22, 2026
@Gu-ZT
Gu-ZT merged commit d6c3947 into dev/1.21.1 Sep 22, 2026
82 of 97 checks passed
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