我的大脑在哪里 (WMB)

我的大脑在哪里 (WMB)

智能群体AI优化模组

管理

WHERE'S MY BRAIN (WMB)

一个轻量级、与加载器无关的 Minecraft 1.20.1 优化模组,专注于更智能的生物 AI 调度、基于距离的节流以及自适应自动调优。在玩家附近保持游戏体验的同时,减少远处或空闲生物浪费的 CPU。

通过 Architectury 同时支持 Forge 和 Fabric。

加入我们的 Discord

功能

  • 异步实体追踪

    • 在主线程之外进行每个玩家的实体可见性/追踪决策,以减少主线程工作。
    • 全局或按维度划分的线程池,带自适应背压(队列感知调度)。
    • 遵循 asyncTracker.updateInterval、cacheDuration 和 maxTrackingDistance。
    • 与 AutoTuner 集成,在负载下调整调度。
    • 超时与优雅回退保证主线程安全。
  • 区域/区块级 TPS 管理器 (R‑TPS)

    • 将每个维度划分为正方形区域(默认:regionalTPS.regionSize = 4 区块边长),并持续测量每个区域的负载。
    • 追踪每个区域的指标:平均 AI 时间 (ms)、平均内存 (MB)、玩家存在、红石更新、BE/计划刻数量以及活动新鲜度。
    • 使用命名级别(例如 normal=1、warning=2、critical=4)为每个区域应用可缩放的刻倍率。
    • 迟滞(regionalTPS.hysteresisPct,默认 0.15)可防止负载在阈值附近徘徊时来回翻转。
    • 静态覆盖允许你将特定区域固定到某个级别。
    • 安全性:全局 TPS 在滑动窗口上计算,紧急触发受预热和冷却限制,以避免误报。
    • 门控与区块随机/计划刻集成,在压力较大的区域减少工作,同时在玩家附近保持不可见。
  • 基于距离的 AI 分桶 (DAB)

    • 根据每个生物最近的玩家距离动态节流 AI 刻。
    • 支持按维度和按实体覆盖。
    • 迟滞死区可防止在阈值附近抖动。
    • 合理的豁免(拴绳、命名、拥有/驯服、持久以及可配置的 Boss 豁免)。
  • 邻近快照服务

    • 将最近玩家计算集中到周期性快照,减少冗余工作。
    • 生物侧缓存缩减至 2 刻,以实现响应迅速的 DAB 更新,同时开销最小。
  • 寻路优化

    • 每个生物的最小路径重新计算间隔和分组窗口。
    • 可选的实验性路径共享。
    • 带 TTL 的缓存,避免重复的路径求解。
  • 自动调优 (PID)

    • 目标为期望的平均刻时间 (ms),并温和调整寻路重算间隔。
    • PID 控制器(kp/ki/kd),带积分限幅和步长限制,实现平滑收敛。
    • 如果 PID 增益为零,则透明地回退到简单的步进控制器。
  • 可选 AI 剔除(保守)

    • 通过多重安全门跳过远处、空闲且未交战的生物的 AI 处理。
  • 可选可见性剔除(保守)

    • 对远离任何玩家区块范围的生物跳过 AI,使用相同的安全门。
  • 指标与命令

    • 轻量级内部计数器,用于 /wmb stats。
    • 查看 DAB 阈值、邻近设置、寻路参数和调优器状态。

工作原理

  • DAB 持续将每个生物放入相对于最近玩家的距离桶(近/中/远/极远),并为每个桶分配一个刻间隔倍率。
  • 异步实体追踪在主线程之外计算每个玩家的追踪实体集,并在刻后应用更新;间隔通过调优器和背压自适应。
  • 邻近服务每 N 刻(可配置)快照玩家位置,以摊销距离查询。
  • 寻路和 AI 重算通过每个生物的最小间隔和可选分组进行速率限制。
  • 自动调优器读取窗口内的平均刻时间,并调整 pathfinding.minRecalcInterval,使服务器趋向 tuning.targetTickMs。
  • 剔除和可见性功能添加可选的保守门控,在安全时跳过 AI。

图表

异步实体追踪:流程

[服务器刻]
  ├─ PreTick
  │   ├─ shouldSchedulePlayer?(interval + tuner + backpressure)
  │   ├─ Snapshot(Player)
  │   ├─ CollectEntitySnapshots (AABB around player)
  │   └─ Submit Task → Executor
  │        └─ [主线程之外]
  │            ├─ Filter by distance ≤ maxTrackingDistance (2D)
  │            ├─ Diff with current tracked set → {toAdd, toRemove}
  │            └─ Enqueue TrackingResult
  └─ PostTick
      ├─ Drain completed results (batched)
      ├─ Apply adds/removes to tracking sets
      ├─ Update metrics (durations, queue size, counts)
      └─ Periodic maintenance (cleanup/disconnects)

线程模型:全局池 vs 按维度池

选项 A:全局池

  [AsyncTracker Executor (N threads)]
      ↑ tasks from all dimensions

选项 B:按维度池

  [Overworld Executor (M)]   [Nether Executor (M)]   [End Executor (M)]
       ↑ OW tasks                  ↑ Nether tasks          ↑ End tasks

Backpressure: bounded queues + CallerRunsPolicy; scheduling slows when queues grow.

自动调优器:控制回路

tickNanos → EMA → window(avg)
            │
            ▼
      Controller (PID or Simple)
            │
     ┌───────┴─────────────────────────────┐
     │                                     │
pathfinding.minRecalcInterval += step   trackerIntervalAddend = clamp(-step)
     │                                     │
cooldown ticks prevent rapid toggling      additive scheduling shift for tracker

DAB 分桶与迟滞

distance (blocks) → 0 ── d0 ── d1 ── d2 ──▶
bucket             NEAR    MID    FAR  DISTANT
multiplier         x1      x2     x4   x8   (defaults; configurable)

hysteresisBlocks (±h) creates a deadband around d0/d1/d2 to reduce bucket flipping.

区域 TPS:决策流水线

[服务器刻]
  ├─ PreTick
  │   ├─ Global TPS sample ← steady after 5+ samples; clamped [0..20]; warm‑up (≥200 ticks) before emergency checks
  │   └─ Update player→region mapping
  ├─ PostTick (per region)
  │   ├─ Accumulate AI nanos, BE & scheduled ticks, redstone updates, memory, players
  │   ├─ Windowed averages (regionalTPS.windowTicks)
  │   ├─ Decide target level using thresholds + hysteresis
  │   ├─ Smoothly adjust region multiplier toward target (±1 per tick)
  │   └─ Apply gating hooks (e.g., chunk random/scheduled ticks)
  └─ Global
      ├─ Emergency trigger if: warm‑up passed ∧ samples≥20 ∧ TPS<15 with cooldown
      └─ Periodic logging & eviction of stale regions

热力图:客户端流程与交互

/wmb heatmap [radius] → server builds window around player
                        ↓
                 send Heatmap to client
                        ↓
                HeatmapScreen (press H to reopen last)
                        ↓
   交互:
   - 鼠标滚轮:缩放
   - 右键拖动:平移
   - 左键单击标题栏:切换模式(AI ms、Mem MB、Players、Priority)
   - 单击 LOD:切换合并视图与按区域视图
   - 悬停:工具提示(合并 + 区域详情)
   - 侧边栏:详细面板(紧急状态、目标倍率、良好/不良连续刻等)
   - 全局 TPS 显示在标题栏中

安装

  • Minecraft:1.20.1
  • 加载器:Fabric 或 Forge(Architectury)
  • 将模组 jar 放入你的 mods/ 文件夹。
  • 启动游戏一次,生成带有内联注释的 wmb.toml 配置文件。

按加载器的配置文件位置:

  • Fabric:.minecraft/config/wmb.toml
  • Forge:<instance>/config/wmb.toml

命令

  • /wmb regions here

    • 打印当前区域的坐标、级别和摘要。
  • /wmb regions top [n]

    • 按平均 AI ms 列出最重的前 N 个区域。
  • /wmb heatmap [radius]

    • 在你的位置周围生成热力图(默认半径 8 个区域)并发送到你的客户端。
  • /wmb reload

    • 从磁盘重新加载 wmb.toml 并应用运行时值。
  • /wmb metrics on|off

    • 切换统计命令使用的内部指标收集。
  • /wmb tuning on|off

    • 在运行时启用/禁用 AutoTuner。
  • /wmb preset <vanilla|balanced|aggressive>

    • 应用从保守到更强优化的运行时预设。使用 /wmb reload 恢复到文件中的值。
  • /wmb stats

    • 显示 DAB 阈值和倍率、邻近快照间隔、异步生成/追踪线程设置、寻路和调优器参数以及指标(如果启用)。
  • /wmb trackerstats

    • 打印追踪器状态和队列/任务指标。
  • /wmb debug entity

    • 检查玩家附近最近的生物的有效 DAB 间隔。
  • /wmb debug chunk

    • 总结你当前区块中生物的平均 DAB 间隔。

按键绑定

  • 热力图:H(默认)

    • 在客户端打开最后收到的热力图。如果你还没有请求过,请先使用 /wmb heatmap。
  • /wmb profile start|stop

    • 用于 AI 步骤计时的轻量级分析器;停止时打印摘要。
  • /wmb stresstest start <entity> [count] [radius] [duration] [pathEvery] [waypoints]

    • 生成受控场景用于压力测试。使用 status、report 和 stop 进行管理。

配置参考

所有选项都在生成的 wmb.toml 中有内联文档。以下是结构化概述。

基于距离的 AI 分桶 (DAB)

  • dab.enabled (bool)

    • 全局开启/关闭距离感知 AI 节流。
  • dab.d0、dab.d1、dab.d2 (double, blocks)

    • 分隔近/中/远/极远桶的距离阈值。
  • dab.multipliers.near|mid|far|distant (int)

    • 每个桶的 AI 刻间隔。1 表示每刻(无节流),更高的值表示 AI 更新频率更低。
  • dab.hysteresisBlocks (double, blocks)

    • 阈值周围的死区,以避免在边界附近快速翻转桶。
  • dab.perEntity["namespace:id"]

    • 按实体覆盖和豁免。
    • 键:exempt (bool)、highPriority (bool)、near、mid、far、distant (ints)。
    • 如果 exempt 或 highPriority 为 true,则该实体类型的 DAB 被禁用。
  • dab.perDimension["namespace:dimension"]

    • 按维度覆盖 d0/d1/d2 和嵌套的 multipliers.near|mid|far|distant。

注意:

  • 某些高重要性实体(例如 Boss)可以在代码中或通过按实体覆盖默认豁免 DAB。
  • 拴绳、命名、拥有/驯服和持久实体不会被节流。

邻近

  • proximity.updateIntervalTicks (int)
    • 玩家位置快照的频率。值越大 = CPU 越少,DAB 响应越慢。典型值:3–10。

寻路

  • pathfinding.enabled (bool)

    • 启用围绕路径重算和缓存的优化。
  • pathfinding.minRecalcInterval (int, ticks)

    • 每个生物重算之间的最小刻数。这是调优器调整的执行器。
  • pathfinding.groupWindowTicks (int, ticks)

    • 在小窗口内分组/错开重算,以分散 CPU 峰值。
  • pathfinding.cacheTtlTicks (int, ticks)

    • 求解出的路径在过期前保留的时间。
  • pathfinding.experimentalShareEnabled (bool)

    • 实验性:允许相似的生物共享路径结果。
  • pathfinding.shareTtlTicks (int, ticks)

    • 如果启用共享,共享路径条目的 TTL。

自动调优

  • tuning.enabled (bool)

    • 启用对 pathfinding.minRecalcInterval 的闭环调优,以趋向目标刻持续时间。
  • tuning.targetTickMs (double, ms)

    • 期望的平均刻持续时间(50.0 ms = 20 TPS)。
  • tuning.windowTicks (int)

    • 每个平均窗口的刻数。
  • tuning.cooldownTicks (int)

    • 连续调整之间的最小刻数。
  • tuning.minRecalcMin / tuning.minRecalcMax (int)

    • 将执行器(最小重算间隔)限制在此范围内。
  • tuning.kp、tuning.ki、tuning.kd (double)

    • PID 增益。如果全部为零,调优器回退到简单的基于步进的控制器。
  • tuning.maxStepPerWindow (int)

    • 每个窗口对执行器的最大绝对变化。
  • tuning.integralMaxAbs (double)

    • 积分项的绝对限幅,以避免积分饱和。

检查

  • checks.suffocationInterval (int, ticks)
    • 原版窒息检查的调优。值越大 = CPU 越少,检测稍慢。

异步生成

  • asyncSpawn.enabled (bool)

    • 启用主线程之外的生成准备工作。
  • asyncSpawn.threadPoolSize (int)

    • 用于异步生成任务的工作线程数。推荐:1–4。

异步实体追踪器

  • asyncTracker.enabled (bool)

    • 启用异步的每个玩家实体追踪。
  • asyncTracker.threadPoolSize (int)

    • 当 perDimensionPools = false 时,全局追踪器执行器的工作线程数。
  • asyncTracker.updateInterval (int, ticks)

    • 在缓存重用之前,每个玩家重算之间的最小刻数。
  • asyncTracker.cacheDuration (int, ticks)

    • 在强制重算之前,重用上次可见性结果的时间。
  • asyncTracker.perDimensionPools (bool)

    • 如果为 true,则为每个维度使用一个执行器以隔离负载。
  • asyncTracker.threadPoolSizePerDim (int)

    • 当 perDimensionPools = true 时,每个按维度执行器的核心线程数。
  • asyncTracker.maxTrackingDistance (double, blocks)

    • 实体被视为追踪的最大水平 2D 距离。

剔除(可选)

  • culling.enabled (bool)

    • 对远处、空闲生物进行保守的 AI 跳过,带有多重安全门。
  • culling.minDistance (double, blocks)

    • 仅考虑距离最近玩家至少这么远的生物。
  • culling.requireNoTarget / requireNoPath / requireLowMotion (bool)

    • 安全门,确保仅对空闲、未交战的生物跳过 AI。
  • culling.lowMotionSpeed (double, blocks/tick)

    • requireLowMotion 使用的阈值。
  • culling.allowEveryNTicks (int, ticks)

    • 即使符合条件,每 N 刻允许完整 AI,以避免饥饿。
  • culling.exemptNamed|Leashed|Owned|Persistent (bool)

    • 保护性豁免,永不跳过重要生物。

可见性(可选)

  • visibility.enabled (bool)

    • 对远离任何玩家区块范围的生物应用类似的跳过规则。
  • visibility.playerChunkRange (int, chunks)

    • 玩家周围被视为"活跃"的切比雪夫区块距离。超出此范围,生物可能根据门控被跳过。
  • visibility.requireNoTarget / requireNoPath / requireLowMotion (bool)

    • 与剔除相同的安全门。
  • visibility.lowMotionSpeed (double, blocks/tick)

    • requireLowMotion 使用的阈值。
  • visibility.allowEveryNTicks (int, ticks)

    • 即使符合条件,每 N 刻允许完整 AI,以避免饥饿。
  • visibility.exemptNamed|Leashed|Owned|Persistent (bool)

    • 保护性豁免,永不跳过重要生物。

区域 TPS

  • regionalTPS.enabled (bool)

    • 基于区块的 TPS 系统的总开关。
  • regionalTPS.regionSize (int, chunks)

    • 正方形区域的边长(以区块为单位)。默认:4。
  • regionalTPS.windowTicks (int, ticks)

    • 每个区域指标和决策的平均窗口。
  • regionalTPS.thresholds.maxTickMs (double, ms)

    • 区域平均 AI 时间在提高级别之前的软上限。
  • regionalTPS.thresholds.maxEntities (int)

    • 区域窗口内实体数量的启发式上限。
  • regionalTPS.thresholds.maxBlockEntities (int)

    • 区域窗口内方块实体的启发式上限。
  • regionalTPS.hysteresisPct (double, 0.0–0.45)

    • 应用于阈值周围的百分比死区,以防止级别快速翻转。默认:0.15(15%)。
  • regionalTPS.scaling.levels.<name> (int)

    • 命名级别到刻倍率的映射,例如 normal=1、warning=2、critical=4。
  • regionalTPS.staticRegions["dim:rx,rz"] = "levelName"

    • 将特定区域(按维度和区域坐标)固定到选定的级别。

配置版本与自动合并

  • 配置文件包含 configVersion。截至 v1.2‑SNAPSHOT,架构版本为 5。
  • 加载时,WMB 会自动合并任何缺失的键并使用安全默认值,同时推进 configVersion。
  • 现有的用户值会被保留。键不会被自动移除。
  • 生成的 wmb.toml 包含每个选项的内联注释。

调优指南

  • 从 tuning.enabled = false 开始。使用 /wmb stats 观察基线。
  • 为你的硬件和整合包设置一个现实的 tuning.targetTickMs。50.0 ms 是 20 TPS;目标略低于你的典型平均负载。
  • 从简单控制器开始:kp > 0、ki = 0、kd = 0。建议:kp = 0.25。
  • 如果看到稳态误差,温和地引入 ki(例如 0.01–0.05)。
  • 如果超调或振荡,添加 kd(例如 0.05–0.2)。
  • 保持 maxStepPerWindow 较小(1–2)以实现平滑。通过 integralMaxAbs 限制积分。
  • 始终使用 minRecalcMin/minRecalcMax 约束执行器。
  • 追踪器集成:调优器还会以加法方式调整追踪器调度;保持 asyncTracker.updateInterval 适中,让调优器平滑负载。

兼容性

  • 设计为对游戏关键 AI 保守且安全。
  • Boss、命名、拴绳、拥有/驯服和持久生物默认受到保护。
  • 应具有广泛的兼容性;实验性功能(如路径共享)是可选加入的。

常见问题

  • DAB 会改变玩家附近的战斗行为吗?

    • 不会。near 桶通常使用倍率 1,保持近距离 AI 行为响应迅速。
  • 异步追踪会导致实体突然出现或不同步吗?

    • 不会。追踪集在主线程之外计算,但每刻安全地在主线程上应用。超时会优雅回退。
  • 如果我的服务器有多个高负载维度怎么办?

    • 启用 asyncTracker.perDimensionPools,按维度隔离追踪器负载,并相应调整 threadPoolSizePerDim。
  • 自动调优会与我手动设置冲突吗?

    • 调优器仅调整 pathfinding.minRecalcInterval。其他一切都保持你配置的原样。
  • 如果我不想要任何剔除怎么办?

    • 两个剔除系统默认都禁用。它们严格是可选加入且保守的。
  • 这是魔法 TPS 加速器吗?

    • 不是。它是一组智能权衡,在不影响游戏体验的情况下节省 CPU。

更新日志

1.2 (2025-09-04)

  • 新功能 — 区域/区块级 TPS 管理器 (R‑TPS)

    • 每个区域的负载追踪(平均 AI ms、内存 MB、玩家、红石更新、BE/计划刻、活动)。
    • 命名缩放级别(例如 normal=1、warning=2、critical=4)作为每个区域的刻倍率应用。
    • 通过 regionalTPS.hysteresisPct(默认 0.15)实现迟滞,以稳定级别转换。
    • 静态区域覆盖,将热点固定到特定级别。
    • 与区块随机/计划刻门控集成;在玩家附近不可见。
  • 新功能 — 区域 TPS 热力图 UI

    • 使用 /wmb heatmap [radius] 请求;使用 H 键重新打开上次热力图。
    • 鼠标滚轮缩放;右键拖动平移;平移/缩放时实时请求窗口。
    • 模式:AI ms、Mem MB、Players、Priority;LOD 切换(合并与按区域图块)。
    • 工具提示和详细侧面板(紧急状态、目标倍率、连续良好/不良刻、历史记录)。
    • 标题栏中显示全局 TPS。
  • 改进 — 全局 TPS 测量与安全

    • 延迟初始化刻计时;仅在 5 个以上样本后计算 TPS;限制在 [0..20]。
    • 在预热(≥200 刻)之前门控紧急触发,并要求 ≥20 个样本;添加冷却以避免日志垃圾。
  • 改进 — 区域决策与采样

    • 对区域缩放决策应用迟滞;引入 levelIndex 追踪转换。
    • 将区域门控的 Y 采样标准化为 level.getMinBuildHeight() + 1。
  • 网络与客户端

    • 更新热力图/详情序列化,包含内存、玩家数量、优先级、全局 TPS、目标倍率和历史记录。
    • 客户端可以刷新现有屏幕(setHeatmap)而无需重新打开;记住上次热力图以供 H 键使用。
  • 修复

    • 通过初始化局部变量修复热力图工具提示编译错误。
    • 消除启动时或零星尖峰时的虚假全局 TPS 紧急情况;减少警告垃圾。
  • 配置

    • 配置架构升级到 5;添加 regionalTPS.* 键,包括 hysteresisPct。
    • 更新 wmb.toml 中的默认值和内联注释。
  • 迁移说明

    • 现有配置自动合并新键并安全推进 configVersion。为你的整合包检查 regionalTPS.thresholds 和 regionalTPS.scaling.levels。

许可证

请参阅仓库中的 LICENSE.txt。