feat(recipe): 为配方查找增加基于方块约束的搜索树剪枝 - #108
Conversation
Gu-ZT
commented
Aug 23, 2026
- InWorldRecipeManager 注册配方时预提取 HasBlockBase 谓词的方块约束(offset 与非空 blocks 集合)
- 触发查找时按相对位置批量去重读取实际方块状态,一次性失效所有不可能匹配的配方
- 未限制对应位置方块(blocks 为空)的谓词不产生约束,所在配方永不剪枝
- 候选集沿用既有优先级排序,完整匹配与执行循环语义不变
- InWorldRecipeManager 注册配方时预提取 HasBlockBase 谓词的方块约束(offset 与非空 blocks 集合) - 触发查找时按相对位置批量去重读取实际方块状态,一次性失效所有不可能匹配的配方 - 未限制对应位置方块(blocks 为空)的谓词不产生约束,所在配方永不剪枝 - 候选集沿用既有优先级排序,完整匹配与执行循环语义不变
|
⏳ Retrying in 2.3s (attempt 1/3)... |
|
⏳ Retrying in 5.4s (attempt 2/3)... |
|
❌ API failed after 3 retries — HTTP 503: Service temporarily unavailable |
|
API call failed after 3 retries: HTTP 503: Service temporarily unavailable |
🌿 Roseau API Breaking Change Report
|
- 相同 offset 与方块集合的约束在注册时合并为共享判定节点,构成节点与配方槽位的二部连线 - 触发时每个节点至多判定一次实际方块状态,相同 offset 的多个节点共享同一次世界读取 - 节点判定失败沿连线一票否决全部相连配方,索引内配方全部失效时立即终止查找 - 绕过 register 直接写入 recipeHolders 的配方保守放行且不参与提前终止,行为与剪枝前一致
- BlockStatePredicate 新增 cannotMatch 方法,testWithoutEntity 复用其实现,剪枝否决条件与谓词语义收敛为一处代码 - PrunePlan 节点判定改用代表谓词的 cannotMatch,替代手写 state.is 复刻 - NodeKey 引入 BlockSetKey 规范化键:标签按 TagKey 值合并、直接集合按排序后方块 id 列表合并,无键 Holder 以实例身份兜底 - NodeKey 构造时归一化 Vec3 偏移(-0.0 归为 0.0),避免浮点表示差异导致无法合并 - resolve 以 try/finally 保证异常路径同样复位失效计数 - RECIPE_ORDER 追加配方 id 决胜,消除同优先级比较不对称带来的不确定遍历顺序 - 注释说明 slotMap 无移除路径时提前终止的失效风险
|
⏳ Retrying in 2.4s (attempt 1/3)... |
|
⏳ Retrying in 4.5s (attempt 2/3)... |
|
❌ API failed after 3 retries — HTTP 503: Service temporarily unavailable |
|
API call failed after 3 retries: HTTP 503: Service temporarily unavailable |
- PrunePlan 新增 OffsetGroup,注册时把节点按归一化 offset 分组 - resolve 改为逐组判定:每组一次 BlockCache 读取,组内节点共享 - 移除每次触发分配的 states 哈希表与重复 Vec3 哈希 - nodes 降级为注册期去重索引,否决/提前终止/兜底放行语义不变
|
❌ Non-retryable error (HTTP 400): HTTP 400: Format Error |
|
HTTP 400: Format Error |
🌿 Roseau API Breaking Change Report
|
🌿 Roseau API Breaking Change Report
|
|
PR #108 的 action 为 closed。按 webhook 审查约束第 1 条( (如需要,可重新打开 PR 或推送新提交触发 |