IsleOfBerk-DeadLockFix

IsleOfBerk-DeadLockFix

用于修复Isle of Berk(Claw of Berk)中的一个bug,当调用 "isWaterBelow()" 时,龙会导致服务器崩溃。

Bug修复

IsleOfBerk DeadlockFix

一个微小的 Forge 1.18.2 兼容性模组,用于修复由 GACMD 团队(Ghanou Craft、Apprentice Necromancer、TooTHleZZ 和 Arsian)制作的《驯龙高手》龙类模组 Isle of Berk 中一个导致服务器崩溃的区块生成死锁问题。

ℹ️ Isle of Berk 本身已正式停止维护——此补丁适用于仍在 1.18.2 整合包中运行最终版 isleofberk-1.2.0.jar 的服务器,例如 kesselot 制作的 Isle of Berk (Claws of Berk)。

如果你的服务器在安装了 IsleOfBerk 后,因为出现 "A single server tick took 60.00 seconds" 错误被 ServerHangWatchdog 杀死——这个模组能解决这个问题。


🐉 问题所在

在世界生成过程中,SpeedStinger.checkSpawnRules 会调用 ADragonBase.isWaterBelow(),该方法会针对完整的 ServerLevel 执行 Level.getBlockState(BlockPos) 读取。当该读取操作针对的区块位于尚未完成生成的相邻区块时,世界生成工作线程会在 ServerChunkCache.getChunk(...).join() 内部阻塞,等待一个正在等待它自己生成的区块——这会在 Worker-Main-N 线程之间形成循环死锁。

60 秒后,服务器看门狗触发,并导致整个服务器崩溃。

日志中的典型症状:

[Server Watchdog/FATAL]: A single server tick took 60.00 seconds (should be max 0.05) ……堆栈信息落在 SpeedStinger.checkSpawnRules → ADragonBase.isWaterBelow 下的 ServerChunkCache.getChunk 处。


🔧 修复方法

一个精确定位的 Mixin(在 isWaterBelow() 方法开头处使用 @Inject):

  • 如果调用线程名称以 Worker-Main 开头(即世界生成线程),则直接短路返回 false——不进行离程线程的方块读取,避免死锁。
  • 世界生成时的生成检查是该方法的唯一非主线程调用方,因此短路操作仅影响区块生成过程中的生成放置决策(SpeedStinger 仍然可以正常生成;它们只是在世界生成期间跳过了水检测)。
  • 所有实时 AI 用途(DragonSleepGoal、AIDragonLand 等)都在主 Server thread 上运行,完全不受影响——龙的行为与之前完全一致。
  • 使用 @Pseudo,因此即使缺少 IsleOfBerk 或 refmap 生成无法找到目标类,也能干净地加载。

✅ 兼容性

规格 值
Minecraft 1.18.2
Forge 40.x+
加载器 Forge (FML)
端 两端(服务端修复;客户端安装无害)
所需模组 isleofberk ≥ 1.2.0

此模组仅修补 IsleOfBerk——与其他模组零交互,可安全放入任何包含 IsleOfBerk 的 1.18.2 整合包中(例如 Claws of Berk)。


📦 安装

  1. 将 isleofberk-deadlockfix-1.0.0.jar 放到 mods/ 文件夹中,与 isleofberk-1.2.0.jar 并列。

  2. 启动服务器。在日志中确认: [IoB-DeadlockFix] Loaded. Mixin will short-circuit ADragonBase.isWaterBelow() during off-main-thread worldgen.

  3. 享受一个在区块生成期间不再崩溃的服务器。🎉


📜 许可与源代码