Skip to content

Refactor CFA 重构锻星砧 - #4480

Merged
PigeonNian merged 4 commits into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/CFA3
Aug 20, 2026
Merged

Refactor CFA 重构锻星砧#4480
PigeonNian merged 4 commits into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/CFA3

Conversation

@WhereisFff

@WhereisFff WhereisFff commented Aug 19, 2026

Copy link
Copy Markdown
Contributor
  • 拆分搜索、引力、库存编解码、天体快照和搜索历史逻辑,统一 CFA 状态持久化与服务端同步
  • 新增巨构定义模型、注册表和内置巨构注册,支持稳定 ID、前置条件、环层模型、材料、旋转规则及处理器工厂
  • 保留旧版巨构名称与索引兼容逻辑,支持旧存档和扩展模组平滑迁移
  • 将星球资源配方改为构建器 API,支持物品/流体便捷注册、嵌套加权选项及 offerings 宝石随机选择
  • 将物流与热力提示改为版本化 RPC 按需同步,增加客户端缓存刷新与等待同步提示,并移除旧热力同步数据包
  • 统一 CFA 方块实体追踪同步,完善伽马激光、虫洞激光状态持久化和相关渲染逻辑
  • 更新 CFA 方块掉落表、模型注册、语言资源及星球资源生成数据,保留拆除时所需的方块实体数据
  • 为特殊天体配方增加可序列化的登陆与返回规则,支持同坐标、缩放、固定位置和随机出生点,并兼容旧版 NBT、网络数据及 travel 字段
  • 新增天体返回门、方块实体和服务端旅行管理器,处理安全落点、跨维度实体移动、传送冷却、返回门复用与重复门清理,并在无安全地形时生成紧急黑曜石平台
  • 添加独立的 anvilcraft:overworld_like 维度和原版生物群系源,通过独立种子、原版生成设置及结构集合筛选保持稳定且隔离的世界生成
  • 新增褐矮星戴森球巨构,接入巨构注册、重构选项、模型渲染和界面文本,实现原始物质分级供给、稳定 40gt 后的发电倍率,以及过量物质累积至 12800B 后转化为特殊红矮星
  • 扩展恒星与巨行星数据模型,持久化特殊红矮星标记和褐矮星能量,调整环位、引力控制、增幅器要求及相关巨构前置条件
  • 改进锻星砧传送门和流体接口的独立运行、批量排液与同步逻辑,并补充接口占位方块碰撞形状
  • 将创造发电机功率上限提升至 65536,并同步服务端校验、滑杆界面和中英文提示文本
  • 注册返回门方块实体、世界生成组件和 Mixin,更新方块模型、方块状态、免疫标签、特殊天体配方及生成语言资源
  • resolved [TODO] 额外锻星砧传送门内容 #3737
  • resolved [TODO] 锻星砧内容增加 #4423
  • resolved [TODO] 可登陆星球-类主世界 #4429

- 拆分搜索、引力、库存编解码、天体快照和搜索历史逻辑,统一 CFA 状态持久化与服务端同步
- 新增巨构定义模型、注册表和内置巨构注册,支持稳定 ID、前置条件、环层模型、材料、旋转规则及处理器工厂
- 保留旧版巨构名称与索引兼容逻辑,支持旧存档和扩展模组平滑迁移
- 将星球资源配方改为构建器 API,支持物品/流体便捷注册、嵌套加权选项及 offerings 宝石随机选择
- 将物流与热力提示改为版本化 RPC 按需同步,增加客户端缓存刷新与等待同步提示,并移除旧热力同步数据包
- 统一 CFA 方块实体追踪同步,完善伽马激光、虫洞激光状态持久化和相关渲染逻辑
- 更新 CFA 方块掉落表、模型注册、语言资源及星球资源生成数据,保留拆除时所需的方块实体数据
- 为特殊天体配方增加可序列化的登陆与返回规则,支持同坐标、缩放、固定位置和随机出生点,并兼容旧版 NBT、网络数据及 travel 字段
- 新增天体返回门、方块实体和服务端旅行管理器,处理安全落点、跨维度实体移动、传送冷却、返回门复用与重复门清理,并在无安全地形时生成紧急黑曜石平台
- 添加独立的 `anvilcraft:overworld_like` 维度和原版生物群系源,通过独立种子、原版生成设置及结构集合筛选保持稳定且隔离的世界生成
- 新增褐矮星戴森球巨构,接入巨构注册、重构选项、模型渲染和界面文本,实现原始物质分级供给、稳定 40gt 后的发电倍率,以及过量物质累积至 12800B 后转化为特殊红矮星
- 扩展恒星与巨行星数据模型,持久化特殊红矮星标记和褐矮星能量,调整环位、引力控制、增幅器要求及相关巨构前置条件
- 改进锻星砧传送门和流体接口的独立运行、批量排液与同步逻辑,并补充接口占位方块碰撞形状
- 将创造发电机功率上限提升至 65536,并同步服务端校验、滑杆界面和中英文提示文本
- 注册返回门方块实体、世界生成组件和 Mixin,更新方块模型、方块状态、免疫标签、特殊天体配方及生成语言资源
Copilot AI lite review requested due to automatic review settings August 19, 2026 15:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 19, 2026 15:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Gugle2308

Copy link
Copy Markdown
Collaborator

Only 3 missing-newline markers (generated/translation files), well within normal bounds. No ghost files flagged by the scale check. This is a large but well-structured refactor.

Let me produce the final review.


PR #4480 审查 — Refactor CFA 重构锻星砧

审查规模:86 个文件 / 10,703 行 diff(73 个 Java,21 个新增,1 个删除,3 处缺失 EOF 换行,均在生成/翻译文件中,正常)。

整体评价:这是一次大规模、结构良好的 CFA 模块重构。拆除旧的硬编码 if/else 链,改为注册表驱动的巨构定义模型(Megastructure + ModRegistries.MEGASTRUCTURE),将搜索/引力/库存编解码/搜索历史拆分为独立控制器,并新增了跨维度返回门与 overworld_like 维度。向后兼容处理尤其出色(旧 NBT index/name/ring 惰性迁移、travel/landing 别名、兼容构造函数、StreamCodec/Codec 双路径)。以下是我发现的具体问题,按优先级排序:

🔴 需要确认的行为变更

1. getActiveIndex() 对"仅新 ID"存档返回 0CfaMegastructureManager

return this.legacyActiveMegastructureIndex >= 0 || this.activeMegastructureId != null
    ? Math.max(this.legacyActiveMegastructureIndex, 0) : -1;

对于只有稳定 ID(无旧索引)的新存档,legacyActiveMegastructureIndex == -1,此时方法返回 0 而非 -1。注释说明这是"active-state 标志",但返回值 0 意味着"选项 0 处于激活状态"。经查,当前所有剩余调用方都只用 >= 0 / < 0 布尔判断(已迁移到 hasActiveMegastructure() / getActiveId()),尚无直接按索引高亮选中项的地方。风险较低,但建议收敛:新增专用 hasActiveMegastructure() 后,若未来 UI 用该索引高亮选项,会错选为 0 号选项。可考虑让它始终返回 -1(当 legacy 索引未知时)。

2. 褐矮星戴森球被排除出 isInfinitePower 与加速器 boost(行为变更)

  • CfaMegastructureManager.isInfinitePower 现只检查 dyson_sphere_small / dyson_sphere_large
  • AcceleratorHandler.isDysonSphereBuilt 同理只检查这两个

旧代码用 option.megastructure().contains("dyson_sphere")包含 dyson_sphere_brown_dwarf。现在加速器无法锁定褐矮星戴森球。考虑到褐矮星新增了独立的稳定供给分层发电模型(STABLE_SUPPLY_TICKS/stableSupplyTier 驱动 1.5x–5x 倍率),这大概率是有意为之,但属于相对 1.6 的实质行为变更,请确认加速器不应作用于褐矮星。

3. 拆除锻星砧后掉落不再保留活动巨构(行为变更)
saveBlockEntityDataToDrop 现在从掉落 NBT 中 remove("activeMegastructureId")remove("activeMegastructure")/Name/Ring;旧 onRemove 代码没有移除 activeMegastructure。因此旧存档中挖掉 CFA 再放回会恢复已建巨构,新版本不会。考虑到巨构是实际放置在世界中的多方块结构(拆掉即清除),移除反而更正确,但这是刻意的行为变更,建议在 PR 描述中注明(描述已提"保留拆除时所需的方块实体数据",但活动巨构恰好被排除在外,需确认是有意)。

🟡 观察/提示(非阻塞)

4. 配方 codec 的 travel 字段 getter 恒为空

CelestialTravelData.CODEC.optionalFieldOf("travel").forGetter(recipe -> Optional.empty())

编码时该字段永远得到 Optional.empty()(JSON 中省略),解码侧 landing.isPresent() ? landing : travel 正确兜底。功能无误,只是 travel 分支实际由 landing 承载——可读性略差,但兼容性目标达成。

5. 增速器 26.1 兼容的少数行为差异(均已注释说明)

  • CfaGravityController 明确保留 1.21 的 redstone 插值除数(避免 26.1 差异导致引力源脱离渲染体)👍
  • Math.logMath.log1p 数学等价
  • 新增强制 errorPlanet 引力体半径 × 0.25,与四分一渲染尺寸对齐(改进)

✅ 做得好的地方

  • 注册表化巨构Megastructure builder + ModRegistries.MEGASTRUCTURE,重复 handler/重复 model ring 均有运行时校验抛异常,registerLegacyHandlersputIfAbsent 保证注册表定义优先、旧 fallback 兜底不会被覆盖。
  • 序列化双路径一致saveAdditional/getUpdateTag + writeUpdateTag/readUpdateTag 均遍历 handler;新 ID 存档只写 ID,迁移期 name/ring 条件写入,加载时 loadActiveIdentity 正确区分新旧。
  • 跨维度兼容CelestialTravelManager 的 landing/return 规则、门复用匹配、重复门清理、紧急黑曜石平台都健壮;Move 正确处理玩家/普通实体/同维与跨维(changeDimension 重建实体)差异。
  • 世界生成隔离VanillaOverworldBiomeSource + ChunkGeneratorMixin 过滤为纯 vanilla 结构集 + ServerLevelMixin/MinecraftServerMixin 独立种子,保证 overworld_like 稳定隔离。
  • RPC 按需同步:移除了广播型 HeatableSyncPacket,改版本化 CompletableFuture RPC + 10 tick 刷新 + 客户端缓存重置,显著减少同步垃圾。
  • NBT/网络兼容emittingGamma 键与旧 gamma 键双读兼容;SpecialCelestialBodyData/StarData/GiantPlanetData 均提供兼容构造函数与 NBT 默认值(如 specialRedDwarf=falseenergy=0)。

结论

整体质量高,架构方向正确。三个红色标注项(getActiveIndex 的 0 语义、褐矮星排除出加速器/无限电、掉落不再保留活动巨构)均为行为变更或边界语义而非功能性 bug,建议作者确认意图并在 PR 描述/文档中明确。无阻塞性合并问题,可以做合入前的最后确认。

无新增测试覆盖这些新状态机(搜索、旅行、按需 RPC、褐矮星分层发电)的边界——考虑到复杂度,建议至少为 CelestialTravelData 的 NBT 往返和 CoordinateRule/ReturnRule 的 codec 编解码补充单元测试。

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'data-migration-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

I have completed my analysis. Let me write up the comprehensive review.


代码审查摘要 — PR #4480

操作: review_requested
范围: 86 个文件 (73 Java, 21 新增, 1 删除) / 10,703 行 diff
分支: dev/1.21/CFA3 → dev/1.21/1.6
规模: 大型多功能重构 PR(锻星砧 CFA 全面重构:巨构注册表、天体旅行系统、新维度、戴森球褐矮星、RPC 工具提示、搜索/引力/库存编解码拆分)

这是一个设计良好、结构清晰的大型重构。核心架构改动(Megastructure 定义模型、CelestialRefactorRegistry 注册表、CelestialTravelManager 服务端旅行、序列化迁移)实现严谨、兼容性考虑周到。以下为审查发现。

🔴 关键问题

暂无致命的正确性 bug。以下为需在合并前确认/修复的高优先级项。

⚠️ 警告

  • Nullness 注解规范违反(多处文件) — 本 PR 新引入了 15 个 javax.annotation.Nullable 导入和 3 个 org.jetbrains.annotations.Nullable 导入。而整个仓库基线是纯 JSpecify(570 个文件用 org.jspecify.annotations.Nullable,仅 1 个 javax 残留)。AGENTS.md 明文规定:"Use only annotations from org.jspecify.annotations... Do not introduce legacy nullness annotations such as javax.annotation.Nullable... or JetBrains nullness annotations... These rules supersede conflicting nullness guidance."
    受影响文件:CfaGammaLaserEffects.javaRubyPrismBlockEntity.javaHeatableBlockEntity.java(JetBrains);CelestialTravelManagerMegastructureCelestialTravelDataCelestialSearchHistoryCelestialSnapshotCodecCfaSearchControllerCfaGravityControllerCfaBlockEntitySyncCelestialBackGateBlock(+Entity)ModMegastructuresCelestialRefactorOptionCelestialSeedMatcher、两个 tooltip provider(javax)。
    建议:统一改为 org.jspecify.annotations.Nullable(新代码路径还应考虑 @NullMarked 包级默认)。这是项目硬性规范,请修复。

  • zh_cn 翻译缺失 — 本 PR 新增的 block.anvilcraft.celestial_back_gatetooltip.anvilcraft.waiting 两个 key 只在 en_us.jsonen_ud.json 添加,zh_cn.json 缺失。而 tooltip.anvilcraft.waiting 已被本 PR 修改的 CfaLogisticsInterfaceTooltipProviderHeatableBlockTooltipProvider 实际引用;该 mod 以中文用户为主。建议补上中文翻译:

    • block.anvilcraft.celestial_back_gate → e.g. 「天体返回门」
    • tooltip.anvilcraft.waiting → e.g. 「等待同步中」
  • 增幅搜索功耗 4000 → 32000(未在 PR 描述中说明)CelestialForgingAnvilBlockEntity.getInputPower() 中搜索期间增幅模式耗电从 4000 提升到 32000 FE/t(非增幅 1000 不变)。这是显著的游戏平衡改动,PR 描述未提及。若非刻意为之,请确认;若刻意,请在描述/更新日志中注明以提示玩家。

💡 建议

  • SliderScreen SLIDER_BOUND 潜在 off-by-oneSLIDER_BOUND = Integer.numberOfTrailingZeros(65536) + 1 = 17,而 65536 = 2^16。若滑杆按「2^位置」映射,位置 16 即达上限,位置 17 会算出 131072,最终靠 Math.clamp 截回 65536。顶格位置可能被浪费(或最大值无法通过滑杆精确定位)。服务端 Math.clamp 保护了值正确性,非阻塞,但建议核对滑杆值语义,将 bound 设为 16trailingZeros)而非 +1。请确认该 Slider 组件实际如何将位置映射为数值。

  • getActiveIndex() 返回哨兵值 0 — 新格式存档(有 activeMegastructureId、无 legacy index)时 getActiveIndex() 返回 Math.max(-1, 0) = 0,将「活跃」信号编码为「索引 0」。现有两处调用(getClientVisibleOptions 过滤、onLoad wormhole 重注册)是旧逻辑保留,语义不变,无回归;但该「0 = 活跃」的隐式约定对后续新调用方容易踩坑,建议在注释中强化说明或提供显式 hasActiveMegastructure() 判断。

🟢 看起来不错

  • 序列化迁移非常严谨StarData/GiantPlanetData/SpecialCelestialBodyData 均保留向后兼容构造函数,specialRedDwarf/brownDwarf/energy 带默认值回读;SpecialCelestialBodyData.fromTagtag.contains("landing") ? "landing" : "travel" 兼容旧 NBT;CfaMegastructureManager 同时保存 activeMegastructureId + legacy name/index/ring 并惰性解析,旧存档平滑迁移路径完整。
  • CelestialTravelManager 健壮性:边界 clamp(world border、build height)、安全落点搜索 + 紧急黑曜石平台兜底、传送门冷却、重复门清理按「同一源传送门」精确匹配,move() 对 ServerPlayer / 同维 / 跨维三种情况分别处理,逻辑周全。
  • 加权随机选择WeightedEntry.select)累积权重实现正确,totalWeight <= 0 有兜底。
  • 巨构可用性与旧的硬编码过滤完全对拍:新 ModMegastructures 的 prerequisite(liquid、civilization、brown dwarf、size 阈值、bodyClass 排除)与旧的 legacyOptions 过滤一一对应,双路径行为一致;褐矮星戴森球 isBrownDwarfOrRemnant 仅限非增幅,与 ring 2 非增幅范围一致。
  • 装备/方块注册Megastructure 注册表、MEGASTRUCTURE registry key、返回门方块/方块实体注册、overworld_like 维度 JSON 与 OVERWORLD_LIKE_DIMENSION 常量、seed 派生(MinecraftServerMixin + ServerLevelMixin + ChunkGeneratorMixin)对齐一致。
  • 无硬编码凭据,JSON(lang 三语对称、关键资源)格式正常。

📋 声称验证表

声称 状态 对应文件
拆分搜索/引力/库存编解码/快照/历史逻辑 CfaSearchController, CfaGravityController, CfaInventoryCodec, CelestialSnapshotCodec, CelestialSearchHistory
巨构定义模型/注册表/内置注册 Megastructure, ModRegistries(MEGASTRUCTURE), ModMegastructures, ModRegistryKeys
旧名称/索引兼容 CfaMegastructureManager, CelestialRefactorRegistry.findLegacyId/ByIndex
星球资源配方改构建器 API + offerings 宝石 PlanetResourceRecipe (+WeightedEntry/WeightedChoice), PlanetResourceRecipeLoader
物流/热力改 RPC 按需同步 + 等待提示 ⚠️ CfaLogisticsInterfaceTooltipProvider (RPC 完成;「等待同步」zh 翻译缺失)
CFA 方块实体统一追踪同步 CfaBlockEntitySync, 各 CFA BE
伽马/虫洞激光状态持久化 CfaGammaLaserEffects, CelestialForgingAnvilPortalBlockEntity, BaseLaserBlockEntity, RubyPrismBlockEntity
行星资源掉落表/模型/语言 loot_table, blockstates, models, lang
可序列化登陆/返回规则 CelestialTravelData (CODEC/STREAM_CODEC/toTag/fromTag, legacy travel 别名)
天体返回门 + 旅行管理器 + 安全落点 + 紧急平台 CelestialBackGateBlock(+Entity), CelestialTravelManager
overworld_like 维度 + 独立种子 + 生物群系源 Meteor… (dimension json), VanillaOverworldBiomeSource, ModBiomeSources, 3 个 Mixin
褐矮星戴森球(40gt 稳定、12800B 转红矮星) DysonSphereHandler, ModMegastructures.DYSON_SPHERE_BROWN_DWARF
恒星/巨行星数据模型扩展 StarData, GiantPlanetData (specialRedDwarf, brownDwarf, energy)
锻星砧传送门/流体接口独立运行、批量排液 CelestialForgingAnvilPortalBlockEntity, FluidInterfaceBlockEntity, InterfacePlaceholderBlock
创造发电机 65536 上限 CreativeGeneratorBlockEntity(MAX_POWER=65536), SliderScreen, lang
返回门 BE/世界生成组件/Mixin 注册 ModBlockEntities, ModBiomeSources, ChunkGeneratorMixin 等

🧪 测试建议

被测目标 推荐测试场景 优先级
CelestialTravelManager.tryReturn/tryLand 跨维度往返、安全落点无解 → 紧急平台、重复门清理不误删同门 🔴
DysonSphereHandler 40gt 稳定供给翻倍边界、过量物质 12800B 转红矮星(数值累加溢出)、convertToRedDwarf 后字段重置 🔴
CelestialSearchHistory MAX_ENTRIES=10 越界、browse 游标越界、previous/next 环回与 originalEntry 还原 🟡
CfaMegastructureManager.loadAdditional 旧 name/index/ring 存档 → 惰性解析为 stable ID、注册表空时注册 fallback handler 🟡
WeightedEntry.select totalWeight=0 兜底、负权重忽略、单选择直接返回 🟡
CelestialTravelData.fromTag legacy travel key 别名、非法 dimension 字符串吞异常返回 null 🟢
CelestialSnapshotCodec.save 黑洞/中子星禁止写入 disk 的极端天体守卫 🟢

结论: COMMENT — 架构与迁移实现质量高,无致命正确性缺陷。合并前请处理:① Nullness 注解改为 JSpecify(违反 AGENTS.md 硬性规范);② 补 zh_cn 缺失的两个 key;③ 确认增幅搜索功耗 4000→32000 的改动是否有意。SliderScreen 的 +1getActiveIndex 哨兵值为非阻塞建议。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

I have thoroughly reviewed this PR. It's a very large and comprehensive CFA refactor (~10.7K lines, 86 files, 21 new files, 1 deletion). Let me write up the review.

Key findings:

  • No compile-blocking logic errors found in the core subsystems.
  • Well-designed backward compatibility for megastructure registry migration, serialization, and travel data.
  • Several warnings: localization gap for tooltip.anvilcraft.waiting in zh; the removed BE portals NBT persistence; isInfinitePower no longer covers brown dwarf dyson sphere; client setChanged() no longer calls sendBlockUpdated in laser interface; seed/obfuscation consistency is hard to verify statically.
  • One concern about getActiveIndex() returning 0 semantics.

Let me write the review as the final response.

代码审查摘要 — PR #4480

操作: review_requested
范围: 86 个文件 (73 Java, 21 新增, 1 删除) / 10,703 行 diff

这是一次针对锻星砧 (CFA) 的大规模重构:拆分搜索/引力/库存/天体快照/搜索历史逻辑、新增巨构注册表与内置巨构、褐矮星戴森球、天体旅行门/跨维度传送、overworld_like 维度与伽马激光状态持久化,并将物流与热力提示改为按需 RPC。整体架构设计与向后兼容处理非常用心,未发现核心逻辑的编译级或行为级致命错误。以下按严重度列出问题与建议。


🔴 关键 (需确认/修复后合并)

1. Wormhole 传送门位置持久化 — BE portals 字段被移除后 handler 仍从旧 tag 读取 (疑似死代码/持久化风险)

  • CelestialForgingAnvilBlockEntity 删除了自身 portals 字段,并从 saveAdditional 移除 portals tag 的写入。
  • WormholeStabilizerHandler.loadPortals() (在 loadAdditional/readUpdateTag 中调用) 仍从 BE tag 中读取 portals
  • 由于 BE 不再写这个 tag,loadPortals 每次都会走 if (!tag.contains("portals")) return; 空返回,this.portals 恒为空。
  • 需要确认:虫洞传送门的 Cube323PartHalf → BlockPos 映射在存档重载后是否由 WormholeNetwork (SavedData) + onBuild 重注册完整恢复。若依赖该映射(如同侧传送门查找、hasPortalAt),而网络数据重建时机晚于 handler 读取,或读取路径遗漏,重载后已连接的虫洞传送门可能失联。建议要么恢复 BE 的 portals 持久化,要么删除 loadPortals 这段无法命中的死代码并保证 WormholeNetwork 是唯一权威源。

⚠️ 警告 (建议修复)

2. 本地化缺口 — tooltip.anvilcraft.waiting 缺少中文翻译

  • 新的 HeatableBlockTooltipProvider 在等待同步时显示 Component.translatable("tooltip.anvilcraft.waiting")
  • 该 key 只在 ScreenLang (英文 / "Waiting for syncing") 与 en_us/en_ud 中出现;zh_cn.json 与 ScreenLang 的中文 provider 均未新增该 key 的中文翻译。
  • 中文玩家会看到原始 key tooltip.anvilcraft.waiting 而非中文。请在 zh_cn.json(或 ScreenLang zh provider)补充对应翻译。

3. isInfinitePower 行为变化 — 褐矮星戴森球不再视为"无限电"

  • 旧逻辑 option.megastructure().contains("dyson_sphere") 覆盖 3 种戴森球;新 CfaMegastructureManager.isInfinitePower 仅检查 dyson_sphere_small/dyson_sphere_large排除了新增的 dyson_sphere_brown_dwarf
  • DysonSphereHandler.getOutputPower 看,褐矮星戴森球是"有限可再生"设计(依赖原始物质供给 + 稳定 40gt),不属于无限电,故排除可能是有意为之。请确认该语义符合预期(否则增幅器阶段忽略褐矮星将是平衡回归)。

4. CfaBlockEntitySync.sendToTracking 强制加载 chunk

  • sendToTrackinglevel.getChunkAt(pos) 强制取 chunk(可能触发未加载 chunk 的生成/加载);在 setChanged()→syncToClients() 热路径中被频繁调用(物流/流体/激光接口)。
  • 虽多数调用发生在已加载 chunk 内,仍建议改为 getChunkIfLoaded/hasChunkAt 守卫,避免边界处意外加载 chunk。

5. 新维度种子/遮挡一致性需运行时验证

  • ServerLevelMixin.getSeed 返回去遮挡的 overworldLikeSeed(sourceSeed),而 MinecraftServerMixin 将 ServerLevel 构造的 long 参数(index 8) 设为 BiomeManager.obfuscateSeed(dimensionSeed)ServerLevelMixin 又单独把 StructureCheck 的种子设为未遮挡的派生种子。
  • 代码注释体现了刻意设计,但"生物群系缩放种子 vs 地形/结构种子"是否与原版的遮挡约定完全一致,静态分析无法百分百确认。请在实际创建 overworld_like 维度后验证地形与生物群系分布对齐(无错误陆地/海洋错位、无结构缺失)。

6. 激光接口 setChanged() 不再调用 sendBlockUpdated

  • CelestialForgingAnvilLaserInterfaceBlockEntity.setChanged() 由"sendBlockUpdated + syncToClients"改为仅 syncToClients()。若某些渲染/AABB 依赖块状态通知(updateNeighborsAt 由 emitLaser 另行触发),需确认移除 sendBlockUpdated 不会导致模型/红石强度刷新滞后。

💡 建议 (非阻塞)

7. BaseLaserBlockEntity.javaback_gate.json 缺少末尾换行 (EOF)

  • BaseLaserBlockEntity.java 结尾现在 \ No newline at end of file(重构引入),back_gate.json 也没有。建议补上,避免影响 diff/CI 与未来 merge。

8. getActiveIndex()Math.max(legacyActiveMegastructureIndex, 0) 语义

  • 当存档只有新式 activeMegastructureId 而无遗留 index 时返回 0 作为"有活动"标志;调用方若把这个 0 当成真实 index 会有歧义。当前 handler 已改用 hasActiveMegastructure(),但建议在文档/注释中明确 getActiveIndex 仅作激活标志用途,避免未来误用。

9. buildMegastructure(CelestialRefactorOption, be)options.indexOf(option) 定位索引

  • 依赖 record 值相等;若两个选项 (ring/def/context) 恰好相等会取到第一个。低风险,但建议改为按 id()+ring() 匹配或直接传 index。

10. 遗留 index 兼容映射依赖新旧选项列表顺序一致

  • buildMegastructure 写入的 legacyActiveMegastructureIndex 来自新注册表顺序clientVisibleOptions,而 findLegacyIdByIndex旧硬编码列表 legacyOptions 反向解析。抽查小型恒星/大型恒星/褐矮星等案例两者顺序一致,但特殊排列(如同时含 ring4+ring5 且部分被滤除的组合)理论上可能错位。建议在 findLegacyIdByIndex 复用时按 id() 二次校验,避免极端存档错配。

🟢 看起来不错

  • 巨构注册表迁移Megastructure 定义 + ModRegistries.MEGASTRUCTURE + ModMegastructures 注册,配合 registerLegacy/synchronizeRegistryHandlers/resolveLegacyIdentity 的三层兼容(新 ID / 遗留 name+ring / 遗留 index),设计严谨;抽查的各天体场景新旧列表顺序一致。
  • 序列化向后兼容StarData/GiantPlanetData/SpecialCelestialBodyData/SpecialCelestialBodyRecipe 均为新增字段提供兼容构造器与默认值;CelestialTravelData.fromTag 同时兼容 landing/travel key,codec 用 optionalFieldOf 双键合并,CoordinateRule/ReturnRule 支持对象与简短字符串两种 datapack 写法。
  • 褐矮星戴森球STABLE_SUPPLY_TICKS=40、分级增益 ×1.5/×2/×3/×5、RED_DWARF_MATTER=12800B 累积转化为红矮星——数值与 en/zh 使用说明文本完全一致;consumePrimordialMatter + drainFluid 的批量排液采用 suppressFluidSync 抑制中间同步再统一发送,模式正确。
  • RPC 按需同步CfaLogisticsInterfaceTooltipProvider/HeatableBlockTooltipProvider 用版本号 + 10gt 间隔 + resetClientState,服务端 TooltipDataValidator/HeatableBlockEntity.Validator 均用 AbstractContainerMenu.stillValid 做访问控制并限流(5gt/玩家、64 上限、200gt 过期),安全且省流量;HeatableSyncPacket 移除合理。
  • 旅行系统CelestialTravelManager 涵盖安全落点/跨维度/冷却/回程门复用/重复门清理/紧急黑曜石平台,CelestialBackGateBlockEntitytouchingEntities 防重触发、queueTouch 延迟到下 tick,isMatchingGate 同源校验严谨。
  • 对撞机重构outputColliderReservedItems 内部收敛 resetColliderStateserverTick 中显式重置调用被合并为一次,无回归;并补充了 collider 运行状态持久化(colliderCooldown/reservedAnvil/reservedHitBlock 等),比旧版"不持久化"更完善。
  • 掉落保留getDrops + prepareForPermanentRemoval + cachedDropData 的时序(无论 getDropsonRemove 前后)都能拿到含巨构/天体数据的完整快照,且清理了 searchCapturedSeed/portals/temple/accelerator 等运行时字段。

📋 声称验证表

声称 状态 对应文件
拆分搜索/引力/库存/快照/历史逻辑 CfaSearchController, CfaGravityController, CfaInventoryCodec, CelestialSnapshotCodec, CelestialSearchHistory
统一 CFA 状态持久化与服务端同步 CfaMegastructureManager, CfaBlockEntitySync, 各 BE save/load
巨构定义模型/注册表/内置注册 (稳定 ID、前置、环层、材料、旋转、处理器工厂) Megastructure, ModMegastructures, ModRegistries, ModRegistryKeys
旧版名称与索引兼容迁移 build/findLegacyId/findLegacyIdByIndex/loadActiveIdentity
星球资源配方→构建器 API (物品/流体/嵌套加权/offerings 随机) PlanetResourceRecipe(EntriesBuilder/ChoiceBuilder/select), offering.json
物流/热力→版本化 RPC 按需同步 + 缓存刷新 + 等待提示 CfaLogisticsInterfaceTooltipProvider, HeatableBlockTooltipProvider, HeatableBlockEntity, 移除 HeatableSyncPacket
统一 CFA 方块实体追踪同步 CfaBlockEntitySync
伽马/虫洞激光状态持久化与渲染 BaseLaserBlockEntity, CfaGammaLaserEffects, Portal/LaserInterface BE, LaserState
CFA 掉落表/模型/语言/星球生成数据 CelestialForgingAnvilBlock.getDrops, RegisterAdditionalEventListener, lang, loot
特殊天体登陆/返回规则 (同坐标/缩放/固定/随机/旧NBT+tracel 兼容) CelestialTravelData, SpecialCelestialBodyRecipe/Data
返回门 + 服务端旅行管理器 (安全落点/跨维度/冷却/复用/清理/紧急平台) CelestialBackGate(Block/BlockEntity), CelestialTravelManager
独立 overworld_like 维度 + 原版生物群系源 VanillaOverworldBiomeSource, ModBiomeSources, dimension json, ServerLevel/MinecraftServer/ChunkGenerator Mixin
褐矮星戴森球 (原始物质分级、40gt 稳定、12800B 转红矮) ModMegastructures, DysonSphereHandler
恒星/巨行星数据扩展 (红矮星标记、褐矮星能量、环位/引力/前置) StarData(energy/specialRedDwarf), GiantPlanetData(energy), Megastructure 前置
锻星砧传送门/流体接口独立运行、批量排液、占位碰撞 Portal BE, FluidInterfaceBE.drainFluid, InterfacePlaceholderBlock 碰撞体
创造发电机上限 65536 服务端/滑杆/文案 CreativeGeneratorBlockEntity, SliderScreen, en/zh tooltip
返回门 BE/世界生成组件/Mixin/模型/免疫标签/语言注册 ModBlockEntities, ModBlocks, mixins.json, collision/dragon/wither tags, lang

结论: 需要修改 (REQUEST_CHANGES / 有条件的 COMMENT)
建议合并前重点确认 #1 (虫洞 portals 持久化)#2 (waiting 中文),并对 #5 (新维度种子遮挡) 做一次运行时验证。其余为低风险改进/风格建议。

🧪 测试建议

被测目标 推荐测试场景 优先级
CelestialTravelManager.tryLand/tryReturn 跨维度往返、同坐标/缩放/固定/随机出生点、冷却内重复、无安全地形紧急平台、重复门清理 🔴
overworld_like 维度 不同世界种子下地形/生物群系/结构一致性、getSeed 与 BiomeManager 遮挡对齐 🔴
WormholeStabilizerHandler 存档重载后已连接虫洞传送门是否保留、portals 恢复 🔴
DysonSphereHandler 40gt 稳定分级、250→2000mB 供给、12800B 累积转红矮、能量/尺寸边界 🟡
CfaMegastructureManager 旧存档 (index/name) 迁移、auxiliary 与主结构共存、build/canBuild 竞态 🟡
HeatableBlockTooltipProvider/物流 RPC 频繁切换目标、玩家离开交互范围后 RPC 被拒、版本号缓存命中 🟡
getDrops/prepareForPermanentRemoval 移除带回天体/巨构数据的掉落,重放置后恢复;无 Inventory 双份掉落 🟡

由 Hermes Agent 审查

I've completed a thorough review of this large CFA refactor. The review is ready to be delivered via the webhook.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && echo "=== getActiveIndex callers that might misread -1 semantics ==="; grep -n "getActiveMegastructureIndex\|getActiveIndex" pr4480.diff | head; echo "=== Screen server/client build path us...

Reason: script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

I have a complete picture. Let me compile the final review.

The overworld_like recipe has landing with coordinate_rule: same and dimension: anvilcraft:overworld_like. I notice the coordinate_rule in the generated JSON uses only type: same (SAME type), and the codec for SAME in CelestialTravelManager.landingOrigin uses destination.getSharedSpawnPos().getY(). For the overworld_like dimension, getSharedSpawnPos — since it uses overworld dimension type with a deterministically derived seed and a custom generator, the spawn might be at the overworld's spawn search. Should be fine.

One thing worth checking: the overworld_like dimension dimensions/LevelStem — there's a dimension/overworld_like.json but for a custom dimension to be loaded as a playable level, NeoForge auto-loads datapack dimension entries. The type: minecraft:overworld reuses the vanilla overworld dimension type, which is fine. But there's a concern: worldGenOptions().seed() on getSeed() — for the overworld_like dimension, this reads the source world seed and derives a stable derived seed. The getSeed mixin only triggers for overworld_like dimension. OK.

I'm confident in my analysis now. Compiling the final review.

代码审查摘要 — PR #4480 (Refactor CFA 重构锻星砧)

概览

操作: edited
范围: 71 个 Java 文件 + 资源 (86 files / 10,703 行 diff, 21 新增 / 1 删除)
性质: 大规模 CFA(锻星砧)重构 —— 巨构注册表模型化、状态持久化统一、服务端同步改为版本化 RPC、新增天体旅行/返回门/overworld_like 维度、褐矮星戴森球。

这是一次架构级的、整体质量很高的重构。核心设计(Megastructure 注册表 + CelestialRefactorOption 解析 + CfaMegastructureManager 统一持有 handler + 兼容旧 NBT 的惰性 ID 迁移)方向正确,且大量兼容性细节(旧 index/name NBT、add-on 兼容构造器、travel/landing 别名)处理得非常周到。绝大多数评审点都是通过验证的。

🔴 关键问题

未发现会阻断合并的编译错误或数据丢失级 bug。以下是需在合并前重点核实的两处行为回归风险(建议确认,非必然 bug):

  1. Heatable 进度客户端同步中断(RPC 化回归风险)
    HeatableBlockEntity.setDuration() 移除了原有的 HeatableSyncPacket 周期推送,改为仅在 HeatableBlockTooltipProvider 展示 tooltip 时按 10gt 间隔拉取。如果客户端有任何非 tooltip 逻辑直接读 HeatableBlockEntity.getDuration() 做动画/进度渲染(不是本 PR 内可见的 tooltip 路径),该处将退化为旧值/0。

    • 请确认:除 tooltip provider 外,客户端没有其它消费者依赖服务器实时推送的 heatable duration。若存在,需为该路径保留同步或补 RPC。
    • 另外 setDuration()if (this.duration == duration) return; 在客户端跳过赋值——若客户端本地有递减逻辑(原动画依赖服务器每 10gt 覆盖重建),此短路可能使客户端动画停在错误状态。
  2. RPC 编解码顺序耦合(后续字段追加脆弱性)
    SpecialCelestialBodyRecipeSTREAM_CODEC encode 在末尾追加 landing,decode 也在末尾读——本 PR 内自洽。但配方是跨网络发送的 wire format,后续任何人在中间插入字段都会破坏二进制兼容(forge 同版本模块两侧同步发布,实际风险低,仅提示)。

⚠️ 警告

  • getActiveIndex() 语义弱化CfaMegastructureManager
    新实现把 getActiveIndex() 变成「有活动巨构即返回 ≥0」的布尔旗标(Math.max(legacyActiveMegastructureIndex, 0)),真正的索引需靠 getActiveId() 惰性解析。任何仍以「索引值」语义消费该方法的第三方代码(渲染器、add-on)会拿到不确定的 0 而非真实偏移。本 PR 内部调用点已全部迁移到 hasActiveMegastructure()/getActiveId(),但作为公开方法其语义变化可能影响扩展模组。建议方法注释中明确标注,或提供返回真实解析索引的替代。

  • CelestialForgingAnvilPortalBlockEntity 触碰清理 AABB 变高(行为变化)
    tick() 中触碰清理由 new AABB(worldPosition)(单格)改为 portalSpaceexpandTowards(0,1,0) 两格)。这是有意为之的行为修正(清理盒与投掷检测盒对齐),但会改变实体离开传送门空间的「免打扰」窗口——实体停在上层格时不会立即清除触碰记录。请确认不是笔误(若只想清理下层,应保持原盒)。

  • CfaMegastructureManager.loadAdditional 后调用 getActiveId(this) 的时机
    CelestialForgingAnvilBlockEntity.loadAdditional 在 handler 全部加载后调用 megastructureManager.getActiveId(this) 解析惰性 ID。若 getCelestialBodyData() 在该点尚未从 NBT 恢复(顺序问题),findLegacyId/findLegacyIdByIndex 会因 body 为 null 解析失败,导致旧存档结构在首次 tick 前丢失活动 ID。循环依赖风险请人工验证加载顺序(从 diff 看 body 在 handler 之前已恢复,应该安全)。

💡 建议

  • DysonSphereHandler.transformToRedDwarf 数据替换后同步markPowerStateChanged 通过 sendBlockUpdated(...,3) 触发更新包中携带 celestialBody,客户端能收到;但未显式加入搜索历史且未重置玩法其它状态(如 planetaryResourceSet 只置空未重新生成)。确认这是预期(红矮星的资源应在下次处理中重新生成)。
  • overworldLikeSeed 复用 RANDOM_SALTOVERWORLD_LIKE_SALTRANDOM_SALT 同值 0x6A09E667F3BCC909L,但用于不同目的(维度 seed 派生 vs 随机出生点盐),无功能问题,仅提示若将来需要彼此独立可拆分常量。
  • SliderScreen.SLIDER_BOUNDnumberOfTrailingZeros(65536)+1 = 17,log2 滑杆最大可表达 2^(17-1)-1 = 65535,与 MAX_POWER=65536 上限自洽。经核对 SliderdefaultArgFunction 语义无误。

🟢 看起来不错

  • 巨构注册表化Megastructure builder + ModMegastructures 15 个内置定义,CelestialRefactorRegistry 拆掉旧的名称硬编码链,add-on 可贡献前置/环/材料/处理器,设计干净。
  • 兼容性迁移做得扎实:旧 activeMegastructure index/name/ring NBT 全部保留读取,findLegacyId/findLegacyIdByIndex 惰性迁移,travel/landing 双别名,SpecialCelestialBodyData/CelestialRefactorOption 兼容构造器——对旧存档和扩展模组平滑。
  • 辅助结构(加速器)统一:加速器从「独立单例」改为注册的 auxiliary 巨构,serverTick/gridTick/clear/save-load 均通过 handler 映射遍历,消除了旧的双重 save 隐患(accelerator 同时被 handler 和单独调用保存)。
  • 激光需求统一syncLaserRequirements 由名称 if-else 改为 getLaserRequirement() 接口默认值,excavator(16,false)/decompressor(1,true)/其它(0,false) 与原行为等价。
  • CG 功率上限 65536setPower/loadAdditionalMath.clamp(-65536,65536),滑杆 UI 同步,服务端校验闭环。
  • worldgenoverworld_like 维度 + VanillaOverworldBiomeSource + getSeed/StructureCheck/MinecraftServer biome-zoom 三处 seed 派生一致,独立于主世界种子。
  • 无 quickMoveStack 存根、无布尔逻辑 == 反相、无 Screen 坐标复制粘贴错误、无硬编码密钥、无 TODO 残留、EOF 换行缺失仅 3 处(正常)。

📋 声称验证表(要点)

声称 状态 主要文件
拆分搜索/引力/库存/快照/历史 + 统一持久化同步 CfaSearchController, CfaGravityController, CfaInventoryCodec, CelestialSnapshotCodec, CelestialSearchHistory, CfaBlockEntitySync
巨构定义模型+注册表+内置注册 Megastructure, ModMegastructures, CelestialRefactorRegistry, CfaMegastructureManager
保留旧名/索引兼容 CfaMegastructureManager (findLegacyId), loadActiveIdentity
星球资源配方→构建器 API + offerings 宝石随机 PlanetResourceRecipe, PlanetResourceGenerator, ChoiceBuilder/select()
物流/热力→RPC 按需同步 + 缓存刷新 HeatableBlockEntity, HeatableBlockTooltipProvider, CfaLogisticsInterfaceTooltipProvider, 删除 HeatableSyncPacket
伽马/虫洞激光持久化 CelestialForgingAnvilPortalBlockEntity, CfaGammaLaserEffects, BaseLaserBlockEntity
天体登陆/返回规则 + 兼容旧 CelestialTravelData, CelestialTravelManager, SpecialCelestialBodyData/Recipe
返回门+旅行管理器+安全落点+紧急平台 CelestialBackGate(BE), CelestialTravelManager
overworld_like 维度+生物群系源 dimension JSON, VanillaOverworldBiomeSource, ModBiomeSources, ServerLevel/MinecraftServer Mixin
褐矮星戴森球+红矮星转化 DysonSphereHandler, StarData/GiantPlanetData, ModMegastructures
锻星砧传送门/流体接口独立运行 CelestialForgingAnvilPortalBlockEntity, FluidInterfaceBlockEntity
CG 功率上限 65536 CreativeGeneratorBlockEntity, SliderScreen
resolved #3737/#4423/#4429 ⚠️ 无法从 diff 直接验证 issue 关闭,需人工确认

结论: COMMENT(建议合并)

这是高质量的大型重构。设计合理、兼容性处理细致、逻辑自洽,未发现会破坏存档或导致崩溃的关键缺陷。合并前请重点确认两点:(1) heatable 时长在移除周期推送后,客户端非 tooltip 路径是否还有依赖(以及 setDuration 相等短路对客户端动画的影响);(2) getActiveIndex() 语义弱化对第三方调用的影响。若这两点确认无碍,即可合并。

🧪 测试建议

被测目标 推荐测试场景 优先级
CfaMegastructureManager 旧 index NBT 存档 → 新 ID 迁移;add-on 移除后 ID 失效回退 🔴
DysonSphereHandler 褐矮星 40gt 稳定供给倍率阶梯;过量物质 ≥12800B 红矮星转化 + NBT 持久化回读 🔴
CelestialTravelManager.tryLand/tryReturn SAME/SCALED/FIXED/RANDOM_SPAWN 各坐标规则;无安全地形紧急平台;重复门清理;传送冷却 🔴
HeatableBlockEntity RPC 客户端 tooltip 拉取、超时/异常回退、reach 校验拒绝 🟡
PlanetResourceRecipe.WeightedEntry.select() 嵌套权重随机命中边界;直接条目往返 JSON 编解码不变性 🟡
CelestialTravelData codec/STREAM_CODEC landing/travel 双字段、旧 NBT 兼容、非法字符串参数回退 🟡

由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'data-migration-pr-review' (1 replacement).

@alpha-hhh

alpha-hhh commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

1、返回传送门会被流体冲毁
2、已生成的返回门,如果玩家偏离原进入位置进入对应的传送门,可能导致返回门改变位置生成,且原返回门消失

Copilot AI review requested due to automatic review settings August 20, 2026 09:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Gugle2308

Copy link
Copy Markdown
Collaborator

I have a comprehensive understanding. Let me write the review now.

The review is ready to be posted as the comment (the webhook will publish the reply automatically). I'll write it in Chinese to match the project's convention.


审查意见:PR #4480 — Refactor CFA 重构锻星砧

规模:92 个文件、+6273/−1856 行(仅 12 个生成/语言资源文件,其余 78 个为 Java,逻辑审查为主)。整体是一次高质量、面向扩展的架构重构:把锻星砧状态拆分成独立控制器(搜索/引力/库存编解码/天体快照/搜索历史),用 Megastructure 注册表替换硬编码选项链,新增天体传送系统、overworld_like 独立维度与褐矮星戴森球。旧世界兼容(NBT 旧键、旧 name/index 巨构迁移、travellanding 别名)设计得很完整,多数改动我验证过 forward/backward 兼容性。

✅ 做得好的地方

  • NBT 双向兼容StarData/GiantPlanetData/SpecialCelestialBodyData 新增字段全部带 tag.contains() 兜底默认值;handleUpdateTaggamma/emittingGammalanding/travel 键都保留了旧键读取。旧存档不会丢数据。
  • 服务端 build 前校验canBuild() + configureMaterialSlot/buildMegastructure 增加 locked/isSearching/isAcceleratorActive 守卫,且 canBuildgetClientVisibleOptions() 二次解析,杜绝过期客户端索引误建。这是对旧漏洞的实质修复。
  • RPC 按需同步(物流接口/可热方块):@RemoteCallable + IRemoteCallableValidator(校验 SERVERBOUND、level.isLoadedstillValid 范围),带 allowTooltipRequest 频率限制和 tooltipDataVersion 版本合并,清理了旧的每 10gt HeatableSyncPacket 广播。方向正确。
  • 世界生成隔离ChunkGeneratorMixin 只保留 minecraft 命名空间的结构集、MinecraftServerMixin/ServerLevelMixin 用独立 seed,避免 mod 结构污染 overworld_like 维度,思路严谨。
  • 创造发电机 65536:服务端 MAX_POWER clamp、客户端 SliderScreen 边界、en_us/zh_cn tooltip 三处一致,无漂移。

⚠️ 需要关注的问题

1. 增幅搜索功率 4000→32000(8 倍跳变)getInputPower() 搜索期间增幅档从 4000 提到 32000。虽然配合创造发电机新上限可达,但对生存玩家是陡峭门槛。若是有意平衡请忽略;若是想小幅上调,这个量级可能超出预期,建议确认。低风险但值得记录。

2. buildMegastructure(CelestialRefactorOption, be) 重载的 options.indexOf(option) 脆弱 — 该重载依赖记录相等的 indexOf。实际菜单点击走的是 buildMegastructure(int)(安全),但若外部/附属用 option 对象重载,且传入的是 resolve() 出来的新对象(其 ContextgetClientVisibleOptions() 中缓存的不同),indexOf 会返回 -1 静默失败——p.4431private buildMegastructure(..., int optionIndex,...)if (optionIndex < 0) return; 直接吞掉。建议改为按 id()+ring() 查找索引,而不是依赖记录相等。

3. 传送门 BE 持久化渲染态saveAdditional 新增持久化 emittingGamma/gammaLevelCelestialForgingAnvilPortalBlockEntity)。这是客户端取向状态写盘,语义上略奇怪,但无副作用、读取兼容旧键。属风格问题。

4. RPC 按需读取的线程安全syncTooltipData/createTooltipData 直接读 itemHandler(FilteredItemStackHandler)与 colliderTargetItems 等可变集合;物流接口的 serverTick 会在主线程改写库存。若该 RPC 库在玩家主线程派发则无碍,但务必确认不是网络/工作线程执行,否则存在库存读取竞态。建议在 IRemoteCallableValidator 或调用侧显式断言主线程。

5. getActiveIndex() 语义 — 新 ID 存档(activeMegastructureId 已设、legacyActiveMegastructureIndex 未解析)时返回 Math.max(-1,0)=0,把"索引未知"伪装成"第 0 个选项"。注释已说明是 active 标志用,但任何把它当精确索引消费的调用方可能得到误导值。属设计取舍,提示一下。

附带说明

  • 20 个新 Megastructure 注册项与 CfaMegastructureManager 构造器的 stellar_evolution_accelerator 硬校验一致;加速器以 .auxiliary() 注册、被排除在 ring 占用判定之外,逻辑自洽。
  • DysonSphereHandler 褐矮星→红矮星转化会 setCelestialBodyData(new StarData(specialRedDwarf=true)),而活跃巨构 ID 保持 dyson_sphere_brown_dwarfgetOutputPowerspecialBrownStar 分支随之工作——转化链路完整。
  • CfaSearchController 将快照/种子捕获延迟到 match 时按 ItemStack.isSameItemSameComponents 校验,修复了旧版"搜索期间移除种子仍授予天体"的问题;loadPersistent 对无法安全补种的在途搜索主动中止而非误授,处理得当。

整体:结构优秀、可上。建议作者对 #2(indexOf 脆弱)做一个低成本的健壮性修复,并确认 #1 的数值预期与 #4 的线程派发。

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'data-migration-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

Confirmed my analysis. The drop strip of activeMegastructure* is new. And the dyson sphere applyBoost confirm: line 8514 reads tier but the small-dwarf path (line 8529+) returns based on bodyClass, never using tier.

I have everything I need. Let me write the comprehensive review.

代码审查总结

结论:已审查 💬(2 个警告,5 条建议,1 个待确认)

PR: #4480 — synchronize: Refactor CFA 重构锻星砧
作者: @WhereisFff
修改文件: 92 个(78 Java + 资源,约 11,100 行,其中约 5,000 行为新增)

这是一个规模巨大、架构质量很高的重构 PR。核心是把 CFA 的巨构系统从「BlockEntity 内硬编码 + 索引」重构为「注册表驱动的 Megastructure 定义 + 稳定 ID」,同时新增褐矮星戴森球、天体旅行系统(overworld_like 维度 + 返回门)、按需 RPC 同步等。整体设计清晰、迁移兼容处理到位。


⚠️ 警告

  1. DysonSphereHandler#serverTick — 小型戴森球「消耗物质但增益不走稳定期」的不一致

    • dyson_sphere_small 挂在 M/K/G 主序星上时,现在每 tick 都会 consumePrimordialMatter() 把连接流体接口里的所有原始物质抽干(旧实现 serverTick 是空壳,不消耗任何物质)。这是行为变更。
    • applyBoost()(8513 行起)读取了 tier = activeSupplyTier(),但小球的增益分支(8529 行起)直接按 star.bodyClass() 返回倍率,完全没用 tier。也就是说 stableSupplyTicks/stableSupplyTier 在小球路径上只涨不参与发电——「稳定 40gt 后的倍率」实际只对褐矮星生效。
    • 结果:小球无条件拿 body-class 倍率、却无条件抽干物质,且 stable* 追踪对小球是死代码。而大型戴森球则完全不消耗物质。
    • 建议:要么让小球倍率也按 activeSupplyTier() >= TIER 门控(与褐矮星设计一致),要么明确注释小球抽物质是有意的燃料机制。当前实现「稳定 40gt」这个目标在小球上形同虚设,容易造成玩家困惑。
  2. CelestialForgingAnvilBlock#saveBlockEntityDataToDrop — 拆下重放不再保留已建巨构(相对旧实现的回归)

    • onRemove 生成方块物品时保留 activeMegastructure,捡起锻星砧再放下,巨构会跟着天体数据一起重建。
    • getDrops 会刻意 remove("activeMegastructureId"/"activeMegastructure"/"activeMegastructureName"/"activeMegastructureRing"),却保留天体数据(celestialBody)。
    • 既然天体数据保留、材料和巨构需求也以天体为准,这里显式丢弃已建巨构与「保留拆除时所需的方块实体数据」的 PR 描述不一致。若是有意为之(捡起后需重新建造),建议在描述/注释中说明;否则属于破坏性数据丢失。

💡 建议

  1. 增幅搜索功耗 4000 → 32000(8 倍)未在描述中说明

    • CelestialForgingAnvilBlockEntity#getInputPowerisAmplify ? 32000 : 1000。这与本次把创造发电机上限提到 65536 相关(单台满配可满足 32000),但把增幅搜索所需供电基础设施门槛大幅拉高。建议在 PR 描述中补充这一平衡性改动,避免下游插件/攻略基于旧数值误判。
    • 注意:getInputPower() <= 0 || grid.isWorking()hasEnoughPower 判定对增幅搜索会变得极难满足(需 32000+ 电网)。
  2. MinecraftServerMixin / ServerLevelMixin 的 mixin 索引是硬编码下标

    • args.set(8, …)ModifyArg index=8 依赖 ServerLevel/StructureCheck 构造器参数顺序。已核对当前签名确实是第 9 个 long(biome/结构种子),正确。但这是对上游类签名高度敏感的注入,升级 MC 版本时容易静默偏移,建议在 @ModifyArgs 上留注释或改用 @WrapOperation/按类型取参更稳健。
  3. SpecialCelestialBodyRecipe CODEC 的 travel 别名字段 getter 恒返回 Optional.empty()

    • optionalFieldOf("travel").forGetter(r -> Optional.empty()) 是只读的兼容别名(encode 只写 landing,decode 时 travel 仅作回退)。设计上可接受,但注意 datapack 若用 travel 写、再被 CODEC 重新序列化时只落到 landing。已在 SpecialCelestialBodyData.fromTag 里同时兼容 landing/travel,建议在配方层面也对 encode 做一次对称处理,避免两边不一致。
  4. WeightedEntry.CODEC encode:单选项嵌套条目往返会丢内层 choice 权重

    • isDirect()(单一 choice)的条目,encode 走 DirectEntry 形态,内层 choice 的 weight(当 chooseOne(w, b -> b.item(x, 3)) 时 inner weight=3)会落为 1。由于 select() 对 direct 条目直接返回 resourceId() 不看内层权重,语义无影响——但属于「encode 非无损」的隐蔽点,建议在 isDirect()/legacyDefinition 处加注释说明。
  5. BaseLaserBlockEntity.java 结尾缺少换行符(EOF newline)

    • diff 末尾 \ No newline at end of file。当前项目整体风格是带换行,建议补一个换行以避免后续 patch 误判。

✅ 表现良好

  • 巨构注册表重构非常干净Megastructure + ModMegastructures + CelestialRefactorRegistry 把原本散落于选项注册表和 BE 管理器的规则集中到数据定义,新增第三方巨构只需注册一个定义即可;CfaMegastructureManagerLinkedHashMap<ResourceLocation,IMegastructureHandler> 并用 put 返回值做重复检测,registerLegacyputIfAbsent 保留已建 handler 运行时状态,考虑周全。
  • 旧档/插件迁移activeMegastructureId/activeMegastructureName/activeMegastructureRing/activeMegastructureIndex 四路兜底 + resolveLegacyIdentity 惰性解析;findLegacyIdByIndex 用旧硬编码顺序而非新注册表迭代顺序,正确地避免了索引漂移。specialRedDwarf/energy/travel/landing 的 NBT 迁移都带向后兼容构造器与合法默认值。
  • 按需 RPC 同步:把物流/热力 tooltip 从每 10gt 全量 sendToAllPlayers/BE update packet 改成版本化 RPC,并且 validator 都带 stillValid 距离校验 + per-player 5gt 限流 + 64 上限过期清理,既降带宽又防滥用(ESP 防护)。
  • 伽马激光沉降isEmittingGamma() 上收到公共基类 + CfaGammaLaserEffects 统一世界效果,LaserState 不再依赖具体类型清单,新增发射器类型(如创造激光)即插即用。
  • 旅行系统CelestialTravelManager 对 SAME/SCALED/FIXED/RANDOM_SPAWN 落点、findSafeLanding*/应急黑曜石平台/返回门复用/重复门清理处理得相当完整;overworld_like 独立种子 + 结构集白名单 mixin 思路成熟,索引也核对无误。
  • 方块掉落重构:从 onRemove 手工生成物品改为 loot table + getDrops,并在拆除前 prepareForPermanentRemoval 缓存 BE 数据,配合精确的运行时字段剔除清单,比旧实现更符合规范。

🧪 测试建议

被测目标 推荐测试场景 优先级
CelestialRefactorRegistry.findLegacyIdByIndex 旧 1.21 存档 activeMegastructure 索引在增幅/非增幅、不同天体下解析到稳定 ID;索引越界返回 null 不崩 🔴
DysonSphereHandler.transformToRedDwarf 褐矮星累积 12800B 过量物质后转红矮星:StarData.specialRedDwarf=true、资源集清空、energyeffectiveEnergy 决定 🔴
CfaMegastructureManager.resolveLegacyIdentity name+ring、index 两条旧路径均能迁移;新存档直接从 ID 读取不回退 🔴
CelestialTravelManager.tryLand 落点为海中时生成应急平台;返回门复用(同源端口 8gt 半径内复用而非新建);重复门仅清理同源 🟡
BaseLaserBlockEntity.emitGammaLaserBeam 伽马目标查找、棱镜销毁、CfaGammaLaserEffects.damageEntities 伤害计算、余烬金属区域加热 🟡
HeatableBlockEntity.getDuration RPC 超 8gt 距离/未加载区块/非 heatable 时报错或返回 -1,不破环校验 🟡
TempleHandler 存根 重构后 quickMoveStack 是否仍正确(非 return getSlot(i).getItem() 吞物品) 🟢

由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Skill 'registry-driven-refactor-pr-review' created.

@PigeonNian
PigeonNian merged commit bcb956f into Anvil-Dev:dev/1.21/1.6 Aug 20, 2026
2 checks passed
@Gugle2308

Copy link
Copy Markdown
Collaborator

The PR was closed. Per the skill instructions and the webhook constraint, if the operation is "closed" or "labeled", I should stop here and not post a comment.

The PR #4480 is closed ("PR #4480 closed"), so I stop and do not publish a review comment.

No comment needed for closed PRs.

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.

[TODO] 可登陆星球-类主世界 [TODO] 锻星砧内容增加 [TODO] 额外锻星砧传送门内容

5 participants