Skip to content

[codex] Optimize liquid flow scheduling#192

Draft
boybook wants to merge 1 commit into
masterfrom
codex/liquid-flow-smoothing
Draft

[codex] Optimize liquid flow scheduling#192
boybook wants to merge 1 commit into
masterfrom
codex/liquid-flow-smoothing

Conversation

@boybook

@boybook boybook commented May 28, 2026

Copy link
Copy Markdown
Member

背景

本轮优化来自高空并排水源/收起水源后的压测与多份 JFR 对比。测试中发现:当大量流动水在同一平面高度同步消退时,TPS 会突然下降;早期热点集中在液体 setBlock -> updateAround -> normalUpdate -> scheduleUpdate 的普通更新放大,后续削减后,热点进一步转移到同一 tick 内大量 scheduled liquid update 集中执行,以及每个液体更新带来的 Block clone、事件、发包和调度器维护成本。

这个 PR 把相关优化全部做成 Level/global 级可控实验特性,默认关闭,避免影响普通生产世界;小游戏(例如 BedWars)可以按 Level 灰度启用并随时回撤。

主要改动

  • 新增 LevelOptimizationSettings,作为 Level 级优化配置入口,避免在 Level 上散落多个 bool。
  • nukkit.yml 读取全局默认液体优化配置,新 Level 初始化时复制一份配置,插件仍可按 Level 覆盖。
  • BlockUpdateScheduler 等价优化索引:
    • equivalentOptimizationEnabled=true 时启用位置 + block id 的 primitive 去重索引;
    • 降低 contains() 扫描所有 tick bucket 的成本;
    • 支持运行中开关切换、索引重建/清空;
    • 避免在热路径上对大索引做整批 removeAll
  • BlockLiquid 等价降分配:
    • 在安全位置复用 existing full-id API,降低重复 Block clone;
    • 将局部方向结果改成 bit mask;
    • 缓存单次更新内的相邻方块读取;
    • 保持 tickRate()、decay、事件和 setBlock(update=true) 语义。
  • 新增非等价实验开关用于削峰:
    • normalUpdateDeduplicationEnabled:同 tick 内 normal update 按坐标去重;
    • liquidUpdateAroundSuppressionEnabled:液体变化时抑制完整 6 邻域普通更新,但仍唤醒相邻液体,避免收水后水完全不更新;
    • maxLiquidNormalUpdatesPerTick:限制每 tick 液体 normal update;
    • maxLiquidScheduledUpdatesPerTick:限制每 tick scheduled liquid update。
  • maxLiquidScheduledUpdatesPerTick 使用随机抽样,而不是固定执行队列前 N 个,避免同一平面水流出现固定一侧先动、另一侧长期停滞。

行为与风险

  • 默认配置全部关闭,未配置服务器行为不变。
  • equivalentOptimizationEnabled 仍用于严格等价优化,不承载跳过事件/跳过更新之类非等价行为。
  • normalUpdateDeduplicationEnabledliquidUpdateAroundSuppressionEnabledmaxLiquidNormalUpdatesPerTickmaxLiquidScheduledUpdatesPerTick 都属于实验特性,可能改变极端水流场景的演化节奏。
  • scheduled liquid 限额不做追赶补算,目的是削掉同平面瞬时尖峰;代价是大规模水流消退可能更慢。
  • 语言模板更新已通过 fork 提交到 Nukkit/Languages PR: https://github.com/Nukkit/Languages/pull/77。由于当前账号没有 Nukkit/Languages 上游直接推送权限,本 PR 没有携带 Languages 子模块指针变更;代码读取缺失配置时会使用默认关闭值。

验证

  • ./gradlew :Nukkit:compileJava :ECBedWars:compileJava
  • git -C /Users/fangyizhou/Documents/coding/CodeFunCore/Nukkit diff --check
  • git -C /Users/fangyizhou/Documents/coding/CodeFunCore/Nukkit/src/main/resources/lang diff --check
  • git -C /Users/fangyizhou/Documents/coding/CodeFunCore diff --check -- ECBedWars/src/main/java/net/easecation/ecbedwars/stage/BedWarsStage.java
  • ./gradlew :Nukkit:shadowJar
  • _simple/nukkit.jar SHA256: 65404666c94923541082e20cd1fba20b56a1bf33cc417c4a77d3cfc921509006

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.

1 participant