Signal Bus 网络
基本信息
| 属性 | 值 |
|---|---|
| 性质 | 非标准多方块 —— 无固定尺寸、无控制器、无框架判定 |
| 唯一使用者 | Signal Bus(SignalBusLogic,成员) |
| 主控类 | SignalBusMasterLogic(MultiblockMasterBaseLogic) |
| 框架文件数 | 7(lib/multiblock/,共 981 行) |
| 成员接口 | IMultiblockMember |
| 成员方块 | 仅 TMechworks:signalBus |
| 结构大小 | 无上限,按 6 面邻接图自由聚合 |
| 破坏顺序 | 任意顺序均可拆除,无「先控制器后成员」要求 |
与本 wiki 其它多方块的区别
本 mod 的多方块不是 3×3×3 / 5×5×5 这类固定体积结构,而是自组织邻接网络:
| 特征 | GTNH 常见多方块 | 本网络的 Signal Bus |
|---|---|---|
| 尺寸 | 固定 N×M×K | 无固定尺寸 |
| 控制器 | 必须有且唯一 | 无控制器,任一成员可为主控 |
| 成型条件 | 遍历固定偏移校验 | getNeighboringMembers() 动态返回邻居 |
| 拆除限制 | 多为「先控制器后成员」 | 任意顺序,onDetached 自动重算 |
| 跨区块 | 通常不支持 | 支持(MultiblockRegistry 按 chunk 预注册) |
因此本条目不列「几×几×几、控制器在哪个、能否旋转拆除」 —— 这些字段对本结构不存在。
框架组件(7 个文件)
| 文件 | 行数 | 职责 |
|---|---|---|
MultiblockBaseLogic.java |
348 | 成员基类:邻接发现、attachBlock / detachBlock、isCompatible 传播 |
MultiblockMasterBaseLogic.java |
380 | 主控基类:信号聚合调度、doMultiblockTick、NBT 序列化 |
MultiblockRegistry.java |
118 | 全局注册表:CopyOnWriteArraySet<MultiblockMasterBaseLogic> + 按 dimensionId/chunkCoord 的预加载表 |
IMultiblockMember.java |
52 | 成员契约(onAttached / onDetached / onChunkLoad / getNeighboringMembers / getNewMultiblockMasterObject) |
BlockMultiblock.java |
17 | 供多方块成员方块继承的 Block 薄封装 |
MultiblockEventHandler.java |
38 | Forge 事件钩子(区块加载 / 卸载时通知注册表) |
MultiblockServerTickHandler.java |
28 | 仅服务端注册(TMechworks.preInit 中 if (event.getSide() == Side.SERVER)) |
lib/multiblock/BlockMultiblock.java(17 行)在本 mod 无任何子类 —— Signal Bus 直接继承 Block,未走这个薄封装。
聚合流程
- 放置 Signal Bus →
SignalBusLogic.addPlacedSide(side)置位该面 SignalBusLogic.getNeighboringMembers()枚举 6 面(跳过未placedSides的面),返回相邻的ISignalBusConnectableMultiblockBaseLogic逐个isCompatible(other)检查 →attachBlock归入主控- 邻接变化触发
onAttached/onDetached,全网重算 SignalBusMasterLogic.doMultiblockTick()聚合localHighSignals(byte[16])→getSignals()updateBusSignals(CoordTuple bus, byte[] signals)分发给已注册的 Signal Terminal
跨区块加载
MultiblockRegistry 用两层表处理「成员先于主控加载」:
preInitMembers/preInitMasters:HashMap<dimensionId, HashMap<chunkCoord, List<IMultiblockMember>>>loadedMembers:加载完成后转入onChunkLoaded(world, chunkCoord):先处理主控再处理成员,逐个onChunkLoad()
数值
| 数值 | 值 |
|---|---|
| 框架文件数 | 7(981 行) |
| 成员方块种类 | 1(TMechworks:signalBus) |
| 结构尺寸 | 无固定尺寸 |
| 控制器 | 无 |
| 主控实现 | SignalBusMasterLogic(getNewMultiblockMasterObject() 每成员各建一个) |
| 信号数组 | byte[16](16 通道) |
| 聚合缓存 | cachedReceivedSignals byte[16] + cachedConnectableCount int |
| 增量标志 | southboundSignalsChanged / northboundSignalsChanged / forceCheck |
| Tick 端 | 仅服务端(MultiblockServerTickHandler) |
| 跨区块 | 支持(按 chunk 预注册) |
| 拆除限制 | 无 |
源码缺陷
BlockMultiblock是死类(17 行,lib/multiblock/BlockMultiblock.java):全仓无任何类继承它。MasterBaseLogic380 行 > 成员基类 348 行,但 Signal Bus 的主控只用了getSignals()/updateBusSignals()/getSignals()/endMerging()/ NBT 五个方法 —— 框架本身比它唯一的用户更复杂,属过度设计。MultiblockRegistry.masters是静态CopyOnWriteArraySet且从不清理世界引用:tick(World)遍历全部 master 比对logic.worldObj == world,世界卸载时若unregister未被调用会泄漏 World 引用。MultiblockEventHandler(38 行)的钩子覆盖是否完整无法从字段判断。loadedMembers字段被声明但onChunkLoaded走的是preInit*表:本条目未确认loadedMembers的写入点,若为零则该字段是死字段。- 无跨维度网络:
MultiblockRegistry的所有表都以world.provider.dimensionId为第一层 key,天然隔离维度。Spool of Wire 的targetDim因此被限制在同维度(见其缺陷条目)。 - 无控制器意味着「网络归属」语义模糊:
getNewMultiblockMasterObject()每个成员都建一个 master 对象,聚合时靠MultiblockBaseLogic选一个存活者。源码无「谁是 master」的可观测输出,玩家无法从游戏内判断网络状态。
相关条目
- Signal Bus - 唯一的多方块成员
- Signal Terminal - 网络的收发端
- Spool of Wire - 建立网络归属的工具
- 命令行 -
/tmech_blockInfo可查看总线 TE 的 NBT