CleanJoin

CleanJoin

在大型登录潮期间,通过异步预加载区块、将初始实体数据包分散到多个tick,并在工作线程上对远处怪物AI进行节流,来减少服务器延迟。

Bug修复

CleanJoin 是一款面向高负载 NeoForge 服务器的性能优化模组,专为应对登录潮时刻而设计:区块加载、实体追踪和数据包序列化都会在同一游戏刻内涌向主线程,拖累 TPS 并触发看门狗。

它在服务端完成其工作。在客户端也同样安装是可选的,能为玩家端带来更平滑的进入体验——未安装该模组的客户端也能正常连接和游玩。

服务端

区块预加载。 当玩家加入时,其出生点周围的区块会以异步方式加载,而非按需加载,因此玩家最初几秒的移动以及任何后续传送都会落在已加载好的区块上。在 Bukkit 混合端上,CleanJoin 还会读取 EssentialsSpawn 和 Multiverse-Core 的配置文件,以判断插件将把玩家传送至何处,并在该位置而非登录位置进行预加载。

节奏化实体同步。 原版会在单个游戏刻内,将所有视野范围内的实体一次性发给新加入的玩家——在人口稠密的基地中,这就是每个人都能感受到的卡顿峰值。CleanJoin 会暂缓这一突发流量,并在接下来的两秒内按实际重要性顺序释放:首先是其他玩家、敌对生物和弹射物,然后才是其余实体,物品展示框、盔甲架、掉落物和 XP 球则排在最后。玩家骑乘的实体,以及同乘者,则永远不会被延迟。维度切换也以相同方式进行节奏化处理。

异步生物 AI 节流。 当没有玩家靠近被动生物时,其 AI 会被挂起,直到有玩家重新进入范围内,这在高负载期间将其寻路和目标选择逻辑移出了游戏刻循环。距离分析会在 Java 21 虚拟线程的辅助线程上运行;只有标志位本身会在主线程上被写回。已命名、被拴绳和骑乘的生物、坐骑和村民永远不会被影响,并且 CleanJoin 挂起的所有内容都会在区块卸载和服务端关闭时恢复——你的存档中不会留下任何被冻结的状态。

所有阈值、范围和速率都可在 config/cleanjoin-server.toml 中进行配置,并且这三个系统均可独立关闭。

客户端(可选)

在客户端添加 CleanJoin 并不会改变 TPS——它改变的是加入的那一秒,即“正在加入世界”与首个流畅画面之间的间隔:

  • 同步覆盖层。 在原版风格的淡入效果上增加一个进度条,用于世界数据流入期间,而非显示冻结画面。
  • 区块网格节流。 在加入期间限制区块网格重建的频率。这正是玩家们口中抱怨为“加入时卡顿”的问题所在。
  • 粒子抑制。 在加入期间会丢弃新的粒子。在实体众多的基地中是实实在在的优化。
  • 自适应节奏。 客户端会报告其帧时间,服务端会据此调整向玩家发送实体的速率——15 FPS 的玩家会获得更长、更平缓的窗口,而 200 FPS 的玩家则会更快完成同步。

以上四项均可独立在 config/cleanjoin-client.toml 中关闭。

兼容性

CleanJoin 旨在运行于 Arclight 及其他 Bukkit 混合端之上。它会在运行时检测 Bukkit 层,将对游戏状态的所有写入操作都经由主线程路由,以避免与 Bukkit 事件系统产生竞争,并以防御性方式包装 NMS 访问,使得重映射的方法在失败时降级为无操作,而不会导致服务器崩溃。

服务端专用、客户端专用以及双端安装都是有效的组合,并且它们都不会在服务器列表中造成版本不匹配。仅客户端安装单独运行不会产生任何效果——该模组需要一个进行节奏控制的服务端配合。

给混合端运营者的一点提示:节奏化实体同步通过混入 ChunkMap 来实现,这是 Arclight 大量修补的区域。如果在混合端服务器上,实体在玩家加入后立即出现异常行为,这应是首先要排查的地方——将 dripFeed.enabled = false 设置后,模组的其余功能将继续正常工作。