Repository navigation
Add data-driven cube selection for 26.3 为26.3添加数据驱动的模型选取与描边 - #282
Conversation
- 支持按命名空间和方块配置精确模型选取、仅模型描边及原版模式 - 按资源包优先级逐项合并规则,并在模型重载完成时同步应用规则与几何 - 保留动态部件和程序排除接口,分离描边与精确选取入口并限制邻格补扫范围 - 补充资源配置格式、覆盖顺序及 KubeJS 整合包接入说明
🌿 Roseau API Breaking Change Report
|
- 在跳过精确选取前刷新客户端帧缓存,避免仅描边模式冻结动态部件 - 保留嵌套射线调用的缓存保护及超出精确选取距离时的原版行为
Gugle2308
left a comment
There was a problem hiding this comment.
结论:PR #282 已合并(squash cf6b22c3,与 dev/26.3 tip 一致,合并树与 head bbd035f5 完全相同);六个 Java 文件与 #281(26.2)逐字节相同,我在 26.3 官方未混淆 client.jar 上复核了关键语义,未发现本 PR 引入的阻塞缺陷。七条版本线的横向对比已完整:只有 1.21.1 带距离哨兵。
一、合并态与范围
| 判据 | 结果 |
|---|---|
| state / merged / merged_at | closed / true / 2026-11-14T11:13:38Z |
| merge_commit_sha | cf6b22c37dc096735c18e160348415157426aa4d = dev/26.3 tip |
| 合并树 vs head | 空 diff ⇒ 进主干的就是 bbd035f5 |
| 规模 | 7 文件 +194/−11,与 API 计数一致,diff 覆盖完整 |
| head CI | build / build ✅ |
| 既有评论 | 仅 Roseau API 报告(`cube |
| 与 #281 的关系 | CubeSelection / CubeSelectionRules / CubePicking / CubeModelEvents / CubeHighlightEvents / ModelSelections 全部 IDENTICAL(含 26.3 独有 API 也一致) |
二、已验证的关键语义(26.3 官方未混淆 client.jar,直接按内部名反汇编)
- 包优先级方向正确。
MultiPackResourceManager的listPacks()返回构造器List.copyOf存下的同一个packs,构造器按列表顺序 push 进FallbackResourceManager;getResourceStack从size()-1倒序取、末尾Lists.reverse⇒ 索引升序 = 低→高,CubeSelectionRules.java:43的升序排序 + 顺序merge与 README 一致。 - 目录参数合法。
checkTrailingDirectoryPath仍是「endsWith("/")为真才抛」⇒ 传"anvillib"正确;七条线行为一致,可写进文档(路径不带尾斜杠)。 - 规则取本轮包集。
createReload顺序为 close 旧 → new →putfield→SimpleReloadInstance.create派发,listPacks()与listResourceStacks()委托同一个resources字段。 - 逐帧链路成立。
Minecraft.renderFrame(boolean)内pick(偏移 388)早于GameRenderer.render()(偏移 500)⇒beginFrame在描边提取之前清帧缓存,仅描边模式不再冻结动态部件。 Identifier.createUntrusted仍校验(assertValidNamespace/assertValidPath)⇒CubeSelectionRules.java:66的 namespace 键校验有效。- 其余结论与同批 #276–#281 相同:规则与几何成对发布、
install先写rules再重算、三种模式四消费点收敛、exclude优先、整份文件校验后替换、公开面零增长。
三、七线对比终版:距离哨兵只在 1.21.1
| 版本线 | PR | distanceToHit 上界 |
|---|---|---|
| 1.21.1 | #276 | ✅ 有 |
| 1.21.4 | #277 | ❌ 无 |
| 1.21.8 | #278 | ❌ 无 |
| 1.21.11 | #279 | ❌ 无 |
| 26.1 | #280 | ❌ 无 |
| 26.2 | #281 | ❌ 无 |
| 26.3 | #282(本 PR) | ❌ 无(CubePicking.java:38-39 直接赋值) |
1.21.1 的守卫处理「Entity.pick 返回被第三方模组重定向到远处/子空间坐标」(注释点名 Sable):先在 start.distanceToSqr(end) + 1e-7 处兜底返回原版结果。其余六条线会把该坐标直接喂给 BlockGetter.traverseBlocks(start, block.getLocation(), …) 逐格遍历整段射线(每格再跑 (2r+1)³ 次 getBlockState),且每帧一次;context.distance 同时失去「不超过射线长度」的上界。
七条线已全部合并,建议一次处理:26.1 / 26.2 / 26.3 与 1.21.11 的 CubePicking.java 逐字节相同,1.21.4 / 1.21.8 只差 API 名——补守卫时可直接复用 1.21.1 的三行与注释。
四、其他建议
⚠️ 预算截断静默(七线通病):MAX_STATES = 32768/MAX_GEOMETRY_BYTES = 16 MiB超限只unsupported++,而CubeSelection.statistics()全仓无调用者;namespace 级配置最容易撞上,表现为「一部分方块仍走原版行为」且无日志。建议在CubeModelEvents.apply里unsupportedStates > 0时打一条一次性 warn。- 💡 README 138–139 行连续两个空行(
### RPC 模块在 140 行)。 - 💡
packs.indexOf(...)的-1(CubeSelectionRules.java:39):命不中会被排成最低优先级(静默降级),可Math.max(0, …)或 debug 日志。 - 💡
load()的异常边界(:35、:37在逐文件 try 之外):listPacks()/listResourceStacks()抛RuntimeException会穿出监听器、让整次模型重载失败,外部资源包引发的问题应退化成EMPTY。 - 💡 公开重载
install(Snapshot)(CubeSelection.java:133)不重置rules,第三方重装快照会沿用上一轮包规则,建议 javadoc 注明。 - 💡
extendsBlock热路径(CubeSelection.java:193-196):mode()每格多一次注册表反查 + 4 次 map 查询,而extended命中即必为 MODEL,可把廉价判断前移。 - 💡
active()/isEnabled()语义收窄(签名不变、javadoc 已更),下游若做渲染/拾取判断需知会。
五、验证边界
未执行 Gradle 构建、runClient 或 JUnit;结论来自静态读码 + 三点 diff 对账(7 文件,与 API 计数逐项一致)+ 26.3 官方未混淆 client.jar 字节码核对(listPacks / getResourceStack / checkTrailingDirectoryPath / createReload / Identifier.createUntrusted / renderFrame 内 pick 与 render 的偏移)+ 与同批 #276–#281 的逐文件比对 + head CI。观感类结论(描边跟手度、outline 手感、F3+T 热换包)静态无法替代实机,建议按 model / outline / vanilla 三档各测一次,并覆盖「整包设成 model 触发预算」与「装带子空间坐标的重定向类模组」两种边界。
feat(cube): 支持资源包配置模型选取与描边
fix(cube): 保持仅描边模式的动态几何逐帧更新