What are you searching for?

Where's my Brain (WMB)

Where's my Brain (WMB)

Smart mob AI optimization mod

download 802 Downloads · favorite 9 Followers · Updated 5 months ago
Fabric Forge Management Optimization Utility 1.20.1 1.20.2 1.20.3 1.20.4 1.20.5 +10 more

Versions

inventory_2
WBM - FORGE 1.2 - FIXED

1.2-SNAPSHOT · 5 months ago · 169.19 KB

Release download
Forge 1.20.1 1.20.2 1.20.3
inventory_2
Where's my Brain (WMB) 1.2-SNAPSHOT

1.2-SNAPSHOT · 5 months ago · 377.26 KB

Release download
Fabric 1.20.1 1.20.2 1.20.3
inventory_2
Where's my Brain (WMB) 1.1-SNAPSHOT

1.1-SNAPSHOT · 5 months ago · 322.00 KB

Release download
Fabric 1.20.1 1.20.2 1.20.3
inventory_2
WMB (Wheres My Brain) 1.0-SNAPSHOT

1.0-SNAPSHOT · 5 months ago · 296.62 KB

Release download
Fabric 1.20.1 1.20.2 1.20.3

About

WHERE'S MY BRAIN (WMB)

A lightweight, loader-agnostic Minecraft 1.20.1 optimization mod focused on smarter mob AI scheduling, distance-aware throttling, and adaptive auto-tuning. Keep gameplay feel near players while cutting wasted CPU on far-away or idle mobs. Works on both Forge and Fabric via Architectury.

Join our Discord

Features

  • Async Entity Tracking

    • Off-thread per-player entity visibility/tracking decisions to reduce main thread work.
    • Global or per-dimension thread pools with adaptive backpressure (queue-aware scheduling).
    • Respects asyncTracker.updateInterval, cacheDuration, and maxTrackingDistance.
    • Integrates with AutoTuner to adjust scheduling under load.
    • Timeouts and graceful fallbacks keep the main thread safe.
  • Regional/Chunk-based TPS Manager (R‑TPS)

    • Divides each dimension into square regions (default: regionalTPS.regionSize = 4 chunks per side) and continuously measures load per region.
    • Tracks per-region metrics: average AI time (ms), average memory (MB), player presence, redstone updates, BE/scheduled tick counts, and activity recency.
    • Applies scalable tick multipliers per region using named levels (e.g., normal=1, warning=2, critical=4).
    • Hysteresis (regionalTPS.hysteresisPct, default 0.15) prevents flip‑flops when load hovers near thresholds.
    • Static overrides let you pin specific regions to a level.
    • Safety: global TPS is computed over a sliding window and emergency triggers are gated by warm‑up and cooldown to avoid false alarms.
    • Gating integrates with chunk random/scheduled ticks to cut work in stressed regions while remaining invisible near players.
  • Distance-based AI Bucketing (DAB)

    • Dynamically throttles AI ticks based on each mob’s nearest-player distance.
    • Per-dimension and per-entity overrides.
    • Hysteresis deadband to prevent thrashing near thresholds.
    • Sensible exemptions (leashed, named, owned/tamed, persistent, and configurable boss exemptions).
  • Proximity Snapshot Service

    • Centralizes nearest-player computations to a periodic snapshot, reducing redundant work.
    • Mob-side cache reduced to 2 ticks for responsive DAB updates with minimal overhead.
  • Pathfinding Optimizations

    • Minimum per-mob path recalculation interval and grouping window.
    • Optional experimental path sharing.
    • Caching with TTL to avoid repeated path solves.
  • Auto-Tuning (PID)

    • Targets a desired average tick time (ms) and gently adjusts pathfinding recalc interval.
    • PID controller (kp/ki/kd) with integral clamping and step-limits for smooth convergence.
    • Transparently falls back to a simple step controller if PID gains are zero.
  • Optional AI Culling (Conservative)

    • Skip AI processing for far, idle, and unengaged mobs behind multiple safety gates.
  • Optional Visibility Culling (Conservative)

    • Skip AI for mobs far outside any player’s chunk range, with the same safety gates.
  • Metrics and Command

    • Lightweight internal counters for /wmb stats.
    • See DAB thresholds, proximity settings, pathfinding parameters, and tuner state.

How It Works

  • DAB continuously places each mob into a distance bucket (near/mid/far/distant) relative to the nearest player and assigns a tick interval multiplier per bucket.
  • Async Entity Tracking computes per-player tracked entity sets off-thread and applies updates post-tick; intervals adapt via tuner and backpressure.
  • The proximity service snapshots player positions every N ticks (configurable) to amortize distance queries.
  • Pathfinding and AI recalculations are rate-limited with per-mob minimum intervals and optional grouping.
  • The Auto Tuner reads average tick time over a window and adjusts pathfinding.minRecalcInterval to steer the server towards tuning.targetTickMs.
  • Culling and visibility features add optional, conservative gates to skip AI when it’s safe to do so.

Diagrams

Async Entity Tracking: Flow

[Server Tick]
  ├─ PreTick
  │   ├─ shouldSchedulePlayer?(interval + tuner + backpressure)
  │   ├─ Snapshot(Player)
  │   ├─ CollectEntitySnapshots (AABB around player)
  │   └─ Submit Task → Executor
  │        └─ [Off-thread]
  │            ├─ 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)

Threading Model: Global vs Per-Dimension Pools

Option A: Global Pool

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

Option B: Per-Dimension Pools

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

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

Auto‑Tuner: Control Loop

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 Bucketing and Hysteresis

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.

Regional TPS: Decision Pipeline

[Server Tick]
  ├─ 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

Heatmap: Client Flow & Interactions

/wmb heatmap [radius] → server builds window around player
                        ↓
                 send Heatmap to client
                        ↓
                HeatmapScreen (press H to reopen last)
                        ↓
   Interactions:
   - Mouse wheel: zoom
   - Right‑drag: pan
   - Left‑click on header: toggle Mode (AI ms, Mem MB, Players, Priority)
   - Click LOD: toggle merged vs per‑region view
   - Hover: tooltips (merged + region details)
   - Sidebar: detailed panel (emergency, target multiplier, good/bad streaks, etc.)
   - Global TPS shown in header

Installation

  • Minecraft: 1.20.1
  • Loaders: Fabric or Forge (Architectury)
  • Drop the mod jar into your mods/ folder.
  • Start the game once to generate the wmb.toml config with inline comments.

Config location by loader:

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

Commands

  • /wmb regions here

    • Prints the current region’s coordinates, level, and summary.
  • /wmb regions top [n]

    • Lists the top N heaviest regions by average AI ms.
  • /wmb heatmap [radius]

    • Generates a heatmap around your position (default radius 8 regions) and sends it to your client.
  • /wmb reload

    • Reloads wmb.toml from disk and applies runtime values.
  • /wmb metrics on|off

    • Toggle internal metrics collection used by stats commands.
  • /wmb tuning on|off

    • Enable/disable the AutoTuner at runtime.
  • /wmb preset <vanilla|balanced|aggressive>

    • Apply a runtime preset of conservative to stronger optimizations. Use /wmb reload to revert to file values.
  • /wmb stats

    • Shows DAB thresholds & multipliers, proximity snapshot interval, async spawn/tracker thread settings, pathfinding and tuner parameters, and metrics (if enabled).
  • /wmb trackerstats

    • Prints tracker status and queue/task metrics.
  • /wmb debug entity

    • Inspect the nearest mob’s effective DAB interval near the player.
  • /wmb debug chunk

    • Summarize average DAB interval for mobs in your current chunk.

Keybinds

  • Heatmap: H (default)

    • Opens the last received heatmap on the client. If you haven’t requested one yet, use /wmb heatmap first.
  • /wmb profile start|stop

    • Lightweight profiler for AI step timing; prints a summary when stopped.
  • /wmb stresstest start <entity> [count] [radius] [duration] [pathEvery] [waypoints]

    • Spawns a controlled scenario for stress testing. Use status, report, and stop to manage.

Configuration Reference

All options are documented inline in the generated wmb.toml. Below is a structured overview.

Distance-based AI Bucketing (DAB)

  • dab.enabled (bool)

    • Turn distance-aware AI throttling on/off globally.
  • dab.d0, dab.d1, dab.d2 (double, blocks)

    • Distance thresholds separating near/mid/far/distant buckets.
  • dab.multipliers.near|mid|far|distant (int)

    • AI tick interval per bucket. 1 means every tick (no throttle), higher means less frequent AI updates.
  • dab.hysteresisBlocks (double, blocks)

    • Deadband around the thresholds to avoid rapid bucket flipping near the boundary.
  • dab.perEntity["namespace:id"]

    • Per-entity overrides and exemptions.
    • Keys: exempt (bool), highPriority (bool), near, mid, far, distant (ints).
    • If exempt or highPriority is true, DAB is disabled for that entity type.
  • dab.perDimension["namespace:dimension"]

    • Per-dimension overrides for d0/d1/d2 and nested multipliers.near|mid|far|distant.

Notes:

  • Some high-importance entities (e.g., bosses) can be exempted from DAB by default in code or via per-entity overrides.
  • Leashed, named, owned/tamed, and persistent entities are not throttled.

Proximity

  • proximity.updateIntervalTicks (int)
    • How often player positions are snapshotted. Larger = less CPU, slower DAB responsiveness. Typical: 3–10.

Pathfinding

  • pathfinding.enabled (bool)

    • Enable optimizations around path recalculations and caching.
  • pathfinding.minRecalcInterval (int, ticks)

    • Minimum ticks between recalculations per mob. This is the actuator adjusted by the tuner.
  • pathfinding.groupWindowTicks (int, ticks)

    • Group/stagger recalcs within a small window to spread CPU spikes.
  • pathfinding.cacheTtlTicks (int, ticks)

    • Keep solved paths for this long before expiring.
  • pathfinding.experimentalShareEnabled (bool)

    • Experimental: allow similar mobs to share path results.
  • pathfinding.shareTtlTicks (int, ticks)

    • TTL for shared path entries if sharing is enabled.

Auto Tuning

  • tuning.enabled (bool)

    • Enable closed-loop tuning of pathfinding.minRecalcInterval towards a target tick duration.
  • tuning.targetTickMs (double, ms)

    • Desired average tick duration (50.0 ms = 20 TPS).
  • tuning.windowTicks (int)

    • Number of ticks per averaging window.
  • tuning.cooldownTicks (int)

    • Minimum ticks between successive adjustments.
  • tuning.minRecalcMin / tuning.minRecalcMax (int)

    • Clamp the actuator (min recalc interval) within this range.
  • tuning.kp, tuning.ki, tuning.kd (double)

    • PID gains. If all are zero, the tuner falls back to a simple, step-based controller.
  • tuning.maxStepPerWindow (int)

    • Maximum absolute change to the actuator per window.
  • tuning.integralMaxAbs (double)

    • Absolute clamp for integral term to avoid windup.

Checks

  • checks.suffocationInterval (int, ticks)
    • Tuning of vanilla suffocation checks. Higher = less CPU, slightly slower detection.

Async Spawn

  • asyncSpawn.enabled (bool)

    • Enable off-thread spawn preparation work.
  • asyncSpawn.threadPoolSize (int)

    • Worker threads to use for async spawn tasks. Recommended: 1–4.

Async Entity Tracker

  • asyncTracker.enabled (bool)

    • Enable asynchronous per-player entity tracking.
  • asyncTracker.threadPoolSize (int)

    • Worker threads for the global tracker executor when perDimensionPools = false.
  • asyncTracker.updateInterval (int, ticks)

    • Minimum ticks between recalculations per player before cache reuse.
  • asyncTracker.cacheDuration (int, ticks)

    • How long to reuse the last visibility result before forcing a recalculation.
  • asyncTracker.perDimensionPools (bool)

    • If true, use one executor per dimension to isolate load.
  • asyncTracker.threadPoolSizePerDim (int)

    • Core threads for each per-dimension executor when perDimensionPools = true.
  • asyncTracker.maxTrackingDistance (double, blocks)

    • Maximum 2D horizontal distance from the player for an entity to be considered tracked.

Culling (Optional)

  • culling.enabled (bool)

    • Conservative AI skipping for far, idle mobs with multiple safety gates.
  • culling.minDistance (double, blocks)

    • Only consider mobs at least this far from the nearest player.
  • culling.requireNoTarget / requireNoPath / requireLowMotion (bool)

    • Safety gates to ensure we skip AI only for idle, unengaged mobs.
  • culling.lowMotionSpeed (double, blocks/tick)

    • Threshold used by requireLowMotion.
  • culling.allowEveryNTicks (int, ticks)

    • Even when eligible, allow full AI every N ticks to avoid starvation.
  • culling.exemptNamed|Leashed|Owned|Persistent (bool)

    • Protective exemptions to never skip important mobs.

Visibility (Optional)

  • visibility.enabled (bool)

    • Apply similar skipping rules to mobs far outside any player’s chunk range.
  • visibility.playerChunkRange (int, chunks)

    • Chebyshev chunk distance around players considered "active". Outside this range, mobs may be skipped subject to gates.
  • visibility.requireNoTarget / requireNoPath / requireLowMotion (bool)

    • Same safety gates as culling.
  • visibility.lowMotionSpeed (double, blocks/tick)

    • Threshold used by requireLowMotion.
  • visibility.allowEveryNTicks (int, ticks)

    • Even when eligible, allow full AI every N ticks to avoid starvation.
  • visibility.exemptNamed|Leashed|Owned|Persistent (bool)

    • Protective exemptions to never skip important mobs.

Regional TPS

  • regionalTPS.enabled (bool)

    • Master switch for the chunk‑based TPS system.
  • regionalTPS.regionSize (int, chunks)

    • Side length of a square region in chunks. Default: 4.
  • regionalTPS.windowTicks (int, ticks)

    • Averaging window for per‑region metrics and decisions.
  • regionalTPS.thresholds.maxTickMs (double, ms)

    • Soft ceiling for average AI time in a region before increasing level.
  • regionalTPS.thresholds.maxEntities (int)

    • Heuristic cap for entity counts within the region window.
  • regionalTPS.thresholds.maxBlockEntities (int)

    • Heuristic cap for block entities within the region window.
  • regionalTPS.hysteresisPct (double, 0.0–0.45)

    • Percentage deadband applied around thresholds to prevent rapid level flip‑flopping. Default: 0.15 (15%).
  • regionalTPS.scaling.levels.<name> (int)

    • Map of named levels to tick multipliers, e.g., normal=1, warning=2, critical=4.
  • regionalTPS.staticRegions["dim:rx,rz"] = "levelName"

    • Pin specific regions (by dimension and region coords) to a chosen level.

Config Versioning and Auto‑Merge

  • The config file includes configVersion. As of v1.2‑SNAPSHOT, the schema version is 5.
  • On load, WMB auto‑merges any missing keys with safe defaults and bumps configVersion forward.
  • Existing user values are preserved. Keys are not removed automatically.
  • The generated wmb.toml includes inline comments for every option.

Tuning Guide

  • Start with tuning.enabled = false. Observe baseline with /wmb stats.
  • Set a realistic tuning.targetTickMs for your hardware and modpack. 50.0 ms is 20 TPS; aim slightly below your typical average load.
  • Begin with a simple controller: kp > 0, ki = 0, kd = 0. Suggested: kp = 0.25.
  • If you see steady-state error, gently introduce ki (e.g., 0.01–0.05).
  • If you overshoot or oscillate, add kd (e.g., 0.05–0.2).
  • Keep maxStepPerWindow small (1–2) for smoothness. Clamp integral via integralMaxAbs.
  • Always bound the actuator with minRecalcMin/minRecalcMax.
  • Tracker integration: the tuner also adjusts tracker scheduling additively; leave asyncTracker.updateInterval moderate and let the tuner smooth load.

Compatibility

  • Designed to be conservative and safe around gameplay-critical AI.
  • Bosses, named, leashed, owned/tamed, and persistent mobs are protected by default.
  • Should be broadly compatible; experimental features (like path sharing) are opt-in.

FAQ

  • Does DAB change combat behavior near the player?

    • No. The near bucket usually uses a multiplier of 1, keeping AI behavior responsive up close.
  • Does async tracking cause entity pop‑in or desync?

    • No. Tracking sets are computed off‑thread but applied safely on the main thread each tick. Timeouts fall back gracefully.
  • What if my server has multiple heavy dimensions?

    • Enable asyncTracker.perDimensionPools to isolate tracker load by dimension and size threadPoolSizePerDim accordingly.
  • Will auto-tuning fight my manual settings?

    • The tuner only adjusts pathfinding.minRecalcInterval. Everything else remains exactly as configured.
  • What if I don’t want any culling?

    • Both culling systems are disabled by default. They’re strictly opt-in and conservative.
  • Is this a magic TPS booster?

    • No. It’s a set of intelligent trade-offs to save CPU in situations where it doesn’t affect gameplay feel.

Changelog

1.2 (2025-09-04)

  • New — Regional/Chunk-based TPS Manager (R‑TPS)

    • Per‑region load tracking (avg AI ms, memory MB, players, redstone updates, BE/scheduled ticks, activity).
    • Named scaling levels (e.g., normal=1, warning=2, critical=4) applied as tick multipliers per region.
    • Hysteresis via regionalTPS.hysteresisPct (default 0.15) to stabilize level transitions.
    • Static region overrides to pin hotspots to specific levels.
    • Integrates with chunk random/scheduled tick gating; invisible near players.
  • New — Heatmap UI for Regional TPS

    • Request with /wmb heatmap [radius]; reopen last heatmap with the H key.
    • Mouse wheel zoom; right‑click drag to pan; live window requests while panning/zooming.
    • Modes: AI ms, Mem MB, Players, Priority; LOD toggle (merged vs per‑region tiles).
    • Tooltips and a detailed side panel (emergency state, target multiplier, consecutive good/bad ticks, histories).
    • Global TPS display in the header.
  • Improvements — Global TPS measurement and safety

    • Lazy‑init tick timing; compute TPS only after 5+ samples; clamp to [0..20].
    • Gate emergency triggers until warm‑up (≥200 ticks) and require ≥20 samples; add cooldown to avoid log spam.
  • Improvements — Regional decisions and sampling

    • Applied hysteresis to regional scaling decisions; introduced levelIndex to track transitions.
    • Normalized Y sampling for region gating to level.getMinBuildHeight() + 1.
  • Networking & Client

    • Updated heatmap/detail serialization to include memory, player counts, priority, global TPS, target multiplier, and histories.
    • Client can refresh the existing screen (setHeatmap) without reopening; remembers last heatmap for the H key.
  • Fixes

    • Heatmap tooltip compile error fixed by initializing local variables.
    • Eliminated false global TPS emergencies at startup or sporadic spikes; reduced warning spam.
  • Config

    • Config schema bumped to 5; added regionalTPS.* keys including hysteresisPct.
    • Defaults and inline comments updated in wmb.toml.
  • Migration Notes

    • Existing configs auto‑merge new keys and bump configVersion safely. Review regionalTPS.thresholds and regionalTPS.scaling.levels for your pack.

License

See LICENSE.txt in the repository.

open_in_new View on Modrinth
Compatibility
Client: Optional Server: Optional
gavel LicenseRef-All-Rights-Reserved

Conversation

What are your thoughts?

Related projects

Optimization
Sodium
Sodium

by jellysquid3

The fastest and most compatible rendering optimization mod for Minecraft. Now available for both NeoForge and Fabric!

download 118.2M
favorite 32,788
Decoration Optimization
Iris Shaders
Iris Shaders

by coderbot

A modern shader pack loader for Minecraft intended to be compatible with existing OptiFine shader packs

download 90.5M
favorite 23,773
Optimization Utility
FerriteCore
FerriteCore

by malte0811

Memory usage optimizations

download 84.3M
favorite 12,712
Optimization
Entity Culling
Entity Culling

by tr7zw

Using async path-tracing to hide Block-/Entities that are not visible

download 84.0M
favorite 13,759
lock Cookie consent

SkinMC uses cookies to provide functionality and features.