Unofficial site, not affiliated with modrinth.com.What is this?
NeuroLag

NeuroLag

A smart, resource-aware optimization plugin that dynamically adjusts Mob AI based on server TPS and RAM to ensure a lag-free SMP experience

209
4
NeuroLag Icon

NeuroLag

Smart TPS-aware mob AI optimizer for Paper 1.21+

Modrinth Paper Java License

Protect your TPS before the lag even starts — then quietly undo everything when the server recovers.

📥 Download🐛 Report a Bug📄 Changelog


📖 Table of Contents

  • ✨ Features
  • 🔁 How It Works
  • 📦 Requirements
  • 🚀 Installation
  • ⌨️ Commands & Permissions
  • 🔧 Configuration
  • 🌐 Web Dashboard
  • 🔗 Multi-Server Sync
  • 🛡️ Protected Zones
  • 🗂️ Config Profiles
  • 💾 Backup System
  • 🧩 Developer API
  • 🔍 Troubleshooting
  • ❓ FAQ
  • 📄 Credits

✨ Features

🧠 Intelligent TPS State Machine

NeuroLag continuously samples TPS, CPU load, heap usage, player count, and predictive trend data to decide which of three states to apply per world:

StateDefault TriggerEffect
NORMALTPS ≥ 18.0No restrictions; full AI restored
MEDIUMTPS < 18.0Follow-range scaled, pathfinding limited, tick-throttle on
CRITICALTPS < 15.0Full AI disable, spawn suppression, smart culling

All thresholds are configurable per-world and can be overridden by config profiles. A hysteresis buffer (default 0.5 TPS) prevents oscillation at the boundary.


⚡ 18 Optimization Features

F1 — CPU Throttle Penalty

Monitors JVM CPU usage. When usage exceeds the configured threshold (default 80%), a 1.5 TPS penalty is applied to the effective TPS calculation, triggering stricter mob optimizations before the server thread becomes saturated.

F2 — Region-Based Pathfinding Cutoff

Divides each world into configurable regions. Mobs beyond the pathfinding distance threshold (disable-pathfinding-distance-chunks: 8) have their FOLLOW_RANGE attribute zeroed, eliminating expensive A* pathfinding for mobs no player will ever see.

F3 — Chunk-Based AI Toggle

Mobs outside a configurable chunk radius from any player (distance-chunks: 4) have their AI disabled entirely during CRITICAL state. Mobs within range always retain full AI regardless of server state.

F4 — Velocity Freeze

Distant AI-disabled mobs have their velocity zeroed to prevent passive drift. Configurable minimum chunk distance (freeze-distance-chunks: 6).

F5 — Spawn Suppression

During MEDIUM and CRITICAL states, monster and animal spawn limits are reduced (monster-limit: 30, animal-limit: 10) to slow mob population growth while the server is already under load.

F6 — Smart Culling

When the per-world entity count exceeds max-entities-per-world during CRITICAL state, the lowest-priority mobs are removed. Supports three culling strategies:

StrategyBehaviour
FAR_FROM_PLAYERRemove mobs furthest from any player first
GROUPRemove mob types that have the most instances
RANDOMShuffle and remove

Protected-zone mobs and named / tamed mobs (if whitelisted) are never culled.

F7 — Tick Throttling

During MEDIUM state, non-priority mobs have their AI ticked only once every N game ticks (ticks-per-ai-tick: 4) instead of every tick. This halves or quarters AI cost without fully disabling mobs.

F8 — Mob Weight System

Each entity type is assigned a weight score. Culling prioritizes heaviest entities first. Fully configurable (zombies.yml-style block in features.yml).

EntityDefault Weight
Bat0.3
Bee0.5
Zombie1.0
Skeleton1.2
Creeper1.5
Enderman2.0
Wither3.0
Ender Dragon4.0

F9 — AI Difficulty Scaling

Adjusts the effective TPS threshold based on world difficulty, so optimization triggers earlier on Easy (players care less) and later on Hard (players want full mob behaviour).

DifficultyTPS Offset
Peaceful+3.0 (never optimizes)
Easy−1.0 (optimizes sooner)
Normal0.0
Hard+1.0 (defers optimization)

F10 — Memory Pressure Penalty

Monitors JVM heap usage ratio. When used heap exceeds the configured threshold (default 80%), a configurable TPS penalty is added, pre-emptively triggering optimizations before a GC pause hits.

F11 — Predictive Scheduler

Tracks historical TPS over a sliding window and a configurable set of peak hours. If a downward TPS trend is detected early (before the threshold is crossed), an earlyOffset penalty is applied to trigger optimizations proactively.

Configurable peak hours example:

peak-hours: "17:00-19:00,19:00-22:00"

F12 — Protected Zones

Mobs inside defined cuboid zones (or WorldGuard regions) are never throttled, culled, or have their attributes modified. Follow range is always restored to default when a mob is found inside a protected zone.

F13 — Smart Group Culling

Instead of culling random mobs, groups entities by type and only targets types with more than min-type-before-cull instances, preserving ecological diversity while reducing the highest-density populations.

F14 — Per-Player Action Bar Notifications

Players near affected mobs receive an action-bar warning during MEDIUM/CRITICAL states. Configurable radius (radius-blocks: 64).

F15 — Alert System

Admin action-bar broadcasts on state transitions. Optional Discord webhook and in-game sound alerts. Sound names, particle types, particle count, and whether to show an action-bar alert are all configurable in monitors.yml under alerts.*. Includes per-player cooldown to prevent sensory spam on multi-world servers.

F16 — Player-Count Scaling

TPS thresholds dynamically tighten as more players join. Configure min-players, max-players, and max-threshold-offset to have the plugin optimize more aggressively during peak player counts.

F17 — Animation Freezing

Freezes the velocity of mobs beyond freeze-distance-chunks during CRITICAL state, preventing physics drift without requiring NMS or packet-level access.

F18 — Config Auto-Backup

Automatically creates timestamped ZIP bundles of all NeuroLag YAML files (including lang/) on a configurable schedule and keeps the N most recent copies. Each backup is accompanied by a .sha256 checksum file that is verified before any restore. Protects against zip-bomb attacks with per-entry (10 MB) and total-restore (50 MB) size caps.


📊 Monitoring & Reporting

FeatureDescription
BossBar DashboardReal-time TPS, state, CPU, and heap display for admins
Web DashboardEmbedded HTTP server at configurable port with JSON API
ASCII Graph/nlag graph — TPS history chart in chat
HTML Audit ReportsOn-demand or auto-generated reports covering server specs, plugin list, chunk stats, and mob analysis. Entity collection is capped at 5 000 per world to avoid main-thread spikes. Full HTML escaping prevents XSS.
Lag ReportsLogged when critical events last more than the minimum duration
Metrics APIPlugin-message channel (neurolag.api) for third-party integrations

🔗 Multi-Server Sync

Propagates TPS state across a network in real time. Supports:

  • Redis (recommended) — sub-100 ms latency via Pub/Sub
  • MySQL — polling-based, works with any shared database

Cascade warnings alert local admins when a peer server enters CRITICAL state.


🗂️ Config Profiles

Switch between named configuration presets at runtime:

/nlag profile survival
/nlag profile event
/nlag profile clear

Profiles override critical-tps, medium-tps, and max-entities without touching your base config files.


🧩 Developer API

NeuroLagAPI api = NeuroLagAPI.getInstance();

api.getCurrentTps();
api.getWorldState("world");           // "NORMAL" | "MEDIUM" | "CRITICAL"
api.isManualOverride();
api.getCriticalActivationCount();
api.getMediumActivationCount();

🔁 How It Works

Every check-interval seconds (default: 10):

  Raw TPS
    │
    ├─ Memory pressure penalty  (if heap > threshold)
    ├─ CPU throttle penalty     (if CPU > threshold)
    ├─ Predictive offset        (if downward trend detected)
    └─ Difficulty scaling       (per-world adjustment)
            │
            ▼
       Effective TPS
            │
   ┌────────┴─────────┐
   │  Hysteresis FSM  │   NORMAL ↔ MEDIUM ↔ CRITICAL
   └────────┬─────────┘
            │
   ┌────────┴────────────────────────────────┐
   │  Per-world optimization pass            │
   │  • Collect targets (cached 4 ticks)     │
   │  • Spawn suppression                    │
   │  • Smart culling (if CRITICAL)          │
   │  • Batched AI/range update (≤ 50/batch) │
   │  • Admin + player notifications         │
   └─────────────────────────────────────────┘

On recovery to NORMAL:
  → restoreWorld() — full AI + default FOLLOW_RANGE for all mobs

📦 Requirements

ComponentVersionNotes
Java21+Required
Paper1.21+Required; Spigot is not supported
WorldGuard7.xOptional — enables WG region integration
RedisAny recentOptional — for multi-server sync
MySQL8.xOptional — alternative sync backend

🚀 Installation

  1. Download NeuroLag-1.5.2.jar from Modrinth.

  2. Place it in your plugins/ folder.

  3. Start the server once to generate all config files.

  4. Edit the files in plugins/NeuroLag/:

    FilePurpose
    config.ymlTPS thresholds, target rules, per-world overrides
    features.ymlToggle and tune each optimization feature
    monitors.ymlDashboard, web API, alerts, Discord, audit
    systems.ymlSync, zones, profiles, backup, validator
  5. Run /nlag validate to catch configuration errors.

  6. Run /nlag status to confirm everything is active.

⚠️ Do not use /reload. Always do a full server restart or use /nlag reload for NeuroLag-specific changes.


⌨️ Commands

CommandDescriptionPermission
/nlag statusTPS, CPU, heap, per-world states, activation countsneurolag.admin
/nlag graphASCII TPS history chart (last 60 samples)neurolag.admin
/nlag togglePause / resume monitoring and mob optimizationsneurolag.admin
/nlag simulate <tps|clear>Force a TPS value for testing (0–20)neurolag.admin
/nlag dashboard [off]Show / hide BossBar dashboardneurolag.dashboard
/nlag auditGenerate an HTML audit reportneurolag.audit
/nlag zoneShow loaded protected zonesneurolag.zone
/nlag profile [name|clear]Switch or clear a config profileneurolag.profile
/nlag validateValidate all config values and report errorsneurolag.validate
/nlag backupCreate a manual backup ZIP nowneurolag.backup
/nlag backup listList available backupsneurolag.backup
/nlag backup restore [file]Restore from latest or named backupneurolag.backup
/nlag stresstest [count] [min]Spawn test mobs for load testingneurolag.stresstest
/nlag syncShow multi-server peer TPS statesneurolag.admin
/nlag reloadHot-reload all NeuroLag config filesneurolag.admin

Aliases: /neurolag, /nl, /neuromob


🔐 Permissions

PermissionDescriptionDefault
neurolag.adminFull control; grants all sub-commandsOP
neurolag.dashboardUse /nlag dashboardOP
neurolag.auditUse /nlag auditOP
neurolag.zoneUse /nlag zoneOP
neurolag.profileUse /nlag profileOP
neurolag.validateUse /nlag validateOP
neurolag.backupUse /nlag backupOP
neurolag.stresstestUse /nlag stresstestOP
neurolag.webWeb dashboard access control (outside Bukkit)OP
neurolag.apiRead plugin metrics via NeuroLagAPItrue

🔧 Configuration

NeuroLag uses a split-config layout. All files are in plugins/NeuroLag/.

config.yml — Core Settings

settings:
  language: en                # en, vi, es, fr, de, ja, zh
  check-interval: 10          # seconds between TPS samples
  enable-logging: true
  hysteresis-buffer: 0.5      # TPS gap before state recovers

tiers:
  medium:
    tps-trigger: 18.0
    range-multiplier: 0.5     # scale mob FOLLOW_RANGE to 50% in MEDIUM
  critical:
    tps-trigger: 15.0

targets:
  hostile-mobs: true
  passive-mobs: false
  water-mobs: true
  whitelist-types: [WARDEN, ELDER_GUARDIAN, ENDER_DRAGON, WITHER]
  protect-named-mobs: true
  protect-tamed-mobs: true

features.yml — Optimization Toggles

culling:
  enabled: true
  max-entities-per-world: 500
  priority: "FAR_FROM_PLAYER"   # FAR_FROM_PLAYER | GROUP | RANDOM

chunk-ai:
  enabled: true
  distance-chunks: 4

tick-throttle:
  enabled: true
  ticks-per-ai-tick: 4

spawn-suppression:
  enabled: true
  monster-limit: 30
  animal-limit: 10

cpu-throttling:
  enabled: true
  cpu-threshold: 80
  mode: THROTTLE_TASKS

memory-pressure:
  enabled: true
  percent: 0.80               # 80% heap used = apply penalty
  offset: 0.5

smart-culling:
  enabled: true
  cull-in-groups: true
  min-type-before-cull: 2
  removal-particle: POOF

monitors.yml — Dashboard & Alerts

dashboard:
  enabled: true
  type: BOSSBAR
  update-interval: 2
  bossbar:
    name: "Server Health"
    color: BLUE

web-dashboard:
  enabled: true
  port: 8080
  auth:
    token: "change-this-token-now"
    require-auth: true
    allow-query-token: false    # keep false for security

discord:
  enabled: false
  webhook-url: ""
  notify-on-critical: true
  notify-on-recovery: true

audit-reports:
  enabled: true
  generate-on: CRITICAL_EVENT
  output-format: HTML

systems.yml — Maintenance & Sync

stress-test:
  enabled: false
  max-mob-count: 2000
  cooldown-seconds: 300
  max-mobs-per-chunk: 80          # NEW 1.5.2 — crash-prevention density cap
  entity-types:
    - ZOMBIE
    - SKELETON
    - CREEPER

multi-server:
  enabled: false
  backend: REDIS              # REDIS or MYSQL

zone-protection:
  enabled: false
  integrate-worldguard: false
  zones:
    - "world 0 60 0 100 200 100"

config-profiles:
  enabled: true
  profiles:
    survival:
      critical-tps: 15.0
      medium-tps: 18.0
      max-entities: 500

auto-backup:
  enabled: true
  backup-interval-minutes: 60
  keep-backups: 10

🔒 Security (v1.5.2)

NeuroLag 1.5.2 ships with three security improvements to the web dashboard:

FeatureDefaultConfig Key
Auto-generated secure tokenEnabled (replaces placeholder on every start() call, even when dashboard is disabled)web-dashboard.auth.token in monitors.yml
Per-IP rate limiting60 req/minweb-dashboard.rate-limit in monitors.yml
IP allow-listDisabledweb-dashboard.ip-whitelist in monitors.yml

On first startup, if the token is still "change-this-token-now", NeuroLag automatically generates a cryptographically secure random token, saves it to monitors.yml (creating the file if needed), and prints it to the console. Use it as your Authorization: Bearer <token> header.

1.5.2 fix: Token generation now runs before the enabled check, so the placeholder is replaced even if you have web-dashboard.enabled: false. Previously, flipping the dashboard on after initial setup could expose the default token until the next restart.


🌐 Web Dashboard

The embedded HTTP server exposes a live dashboard and JSON API.

Routes:

RouteMethodDescription
/GETHTML live dashboard (auto-refreshes)
/api/statusGETJSON metrics snapshot
/api/cmdPOSTLimited command bridge

Allowed commands via /api/cmd: reload, status, graph, validate

Authentication:

Always use the Authorization: Bearer <token> request header. The ?token=... query-string fallback is disabled by default (allow-query-token: false) because tokens in URLs appear in server access logs and browser history.

# Correct
curl -H "Authorization: Bearer my-secret-token" http://localhost:8080/api/status

# Works but insecure — only if allow-query-token: true
curl "http://localhost:8080/api/status?token=my-secret-token"

⚠️ Always change the default token and never expose the web dashboard port publicly without a reverse proxy or firewall rule.


🔗 Multi-Server Sync

Share TPS state across a network so operators can see the health of every node from one place.

Redis (recommended)

multi-server:
  enabled: true
  backend: REDIS
  cascade-warnings: true
  redis:
    host: localhost
    port: 6379
    password: ""

MySQL

multi-server:
  enabled: true
  backend: MYSQL
  mysql:
    host: localhost
    port: 3306
    database: neurolag
    user: root
    password: ""

Use /nlag sync to see live peer states:

[NeuroLag] This server: MyServer_25565
  - LobbyServer_25565  →  19.8 TPS  [NORMAL]
  - SurvivalNode_25566 →  16.2 TPS  [MEDIUM]

v1.5.1: Redis subscriber now exits cleanly on reload. MySQL reconnect uses exponential back-off to avoid log spam during DB outages.


🛡️ Protected Zones

Define cuboid zones where mobs are never optimized, throttled, or culled.

zone-protection:
  enabled: true
  integrate-worldguard: false   # set true to also protect WorldGuard regions
  zones:
    - "world 0 60 0 100 200 100"       # world minX minY minZ maxX maxY maxZ
    - "world_nether -50 0 -50 50 128 50"

Protected mobs always have:

  • AI enabled
  • FOLLOW_RANGE restored to Minecraft default
  • Velocity unfrozen
  • Immunity from smart culling

v1.5.1: FOLLOW_RANGE is now unconditionally restored for protected mobs on every optimization pass, not just when the mob happens to re-enter the zone.


🗂️ Config Profiles

Switch between named presets at runtime without editing files.

config-profiles:
  enabled: true
  profiles:
    survival:
      critical-tps: 15.0
      medium-tps: 18.0
      max-entities: 500
    event:
      critical-tps: 14.0
      medium-tps: 17.0
      max-entities: 900
    minigame:
      critical-tps: 12.0
      medium-tps: 16.0
      max-entities: 1000
/nlag profile event     — switch to event profile
/nlag profile clear     — return to base config
/nlag profile           — show all profiles + current active

💾 Backup System

Automatic backups save all NeuroLag .yml files (including lang/) as timestamped ZIP bundles.

auto-backup:
  enabled: true
  backup-interval-minutes: 60
  keep-backups: 10

Backups are stored in plugins/NeuroLag/backups/.

/nlag backup                                          — create now
/nlag backup list                                     — list all
/nlag backup restore                                  — restore latest
/nlag backup restore config-bundle-2026-04-18_12-00-00.zip

v1.6.0 security improvements:

  • Each backup ZIP is accompanied by a .sha256 checksum file.
  • Restore verifies the checksum before extracting; a mismatch aborts with a SEVERE log.
  • Zip-bomb protection: 10 MB per-entry cap and 50 MB total-restore cap.
  • Backup list is cached in memory; purgeOld() uses filename-based sort — no filesystem stat calls.

v1.5.1: The lang/ subdirectory is included in all backup bundles so custom language files are not lost on restore.


🧩 Developer API

// Get the API instance
NeuroLagAPI api = NeuroLagAPI.getInstance();

// Read current TPS and world state
double tps       = api.getCurrentTps();
String state     = api.getWorldState("world");     // "NORMAL" | "MEDIUM" | "CRITICAL"
boolean override = api.isManualOverride();

// Read lifetime counters
int critCount    = api.getCriticalActivationCount();
int medCount     = api.getMediumActivationCount();

Subscribe to state changes via the plugin-message channel neurolag.api (requires neurolag.api permission set to true on the target player).


🔍 Troubleshooting

Stress test crashes the server when spawning many mobs at spawn

Fixed in 1.5.2. The stress test now checks per-chunk mob density (7×7 chunk grid around the spawn point) against stress-test.max-mobs-per-chunk (default 80) before spawning. If the limit would be exceeded, the count is reduced automatically. Update to 1.5.2.

Web dashboard token was still the default placeholder after enabling the dashboard

Fixed in 1.5.2. Token generation now runs before the enabled check, so the placeholder is always replaced regardless of whether the dashboard starts or not. Update to 1.5.2.

MySQL log spam: "connection lost — reconnecting" floods console during DB outage

Fixed in 1.5.2. Reconnect log messages are now suppressed using the same power-of-2 streak filter used for SQL errors (logs on streak 1, 2, 4, 8, 16 …). Update to 1.5.2.

Entity count stays above maxEntities permanently when zone protection is active

Fixed in 1.5.2. The culling pass now pre-filters protected mobs before calculating the removal count, so the math is correct and the engine converges to the target entity count even when a subset of mobs is zone-protected. Update to 1.5.2.

Mobs are frozen after /nlag toggle or /nlag reload

Fixed in 1.5.1. In-flight batch tasks were re-applying AI restrictions after restoreAll() ran. Update to 1.5.1 and the issue is resolved. If you are running 1.4.0, trigger a full server restart as a workaround.

TPS keeps spiking on a mob-heavy server even with NeuroLag active

Make sure collectTargets caching is active (1.5.1+). On older versions, the entity scan ran every tick. Also lower check-interval and reduce max-entities-per-world in features.yml.

FOLLOW_RANGE stays reduced after server recovers to NORMAL

Fixed in 1.5.1. Protected-zone mobs and mobs in worlds returning to NORMAL now always have FOLLOW_RANGE reset to the Minecraft default via the new restoreWorld() call.

Redis/MySQL exceptions flooding the log on reload

Fixed in 1.5.1. Redis subscriber now joins before pool close. MySQL reconnect uses exponential back-off so errors only log at streaks 1, 2, 4, 8, 16, …

Web dashboard token showing in server access logs

Set allow-query-token: false (now the default in 1.5.1) and use the Authorization: Bearer <token> header instead.

Custom language files lost after backup restore

Fixed in 1.5.1. Backup bundles now include the lang/ subdirectory. Restore from a 1.5.1 backup to get language files back.

Mobs inside protected zones being removed by smart culling

Fixed in 1.5.1. The cull() method now checks zoneManager.isProtected() before removing any mob. Update to 1.5.1.

No optimization happening at all
  1. Run /nlag validate — look for config errors.
  2. Run /nlag status — check that Override shows OFF.
  3. Check ignored-worlds in config.yml — your world may be excluded.
  4. Use /nlag simulate 10 to force CRITICAL state and verify mobs respond.
  5. Check targets in config.ymlhostile-mobs and water-mobs must be true.
Web dashboard returns 401 even with the correct token

Ensure you are sending the token in the Authorization header, not the query string (allow-query-token is false by default). Example:

curl -H "Authorization: Bearer your-token-here" http://localhost:8080/api/status
/reload breaks the plugin

Use /nlag reload instead of the server-level /reload command. Server /reload can leave dangling tasks and broken event registrations in any plugin.


❓ FAQ

Does NeuroLag affect player behaviour?

No. It only modifies non-player mob AI and attribute values (FOLLOW_RANGE). Players, their items, and their abilities are never touched.

Will mobs stay frozen permanently?

No. NeuroLag always restores full AI and default attributes when the server returns to NORMAL state, when the plugin is disabled, or when /nlag toggle is used to pause monitoring.

Does it support multiple worlds?

Yes. Each world is tracked independently with its own state machine. Per-world TPS thresholds can be configured in config.yml under world-settings.

Does it support Folia?

No. NeuroLag uses the Bukkit scheduler API which is not compatible with Folia's per-region threading. Folia support is planned for a future release.

Can I use it alongside other optimization plugins?

Yes, but ensure culling and AI-disable settings do not conflict. NeuroLag is designed to coexist with plugins like Spark, ClearLag, and Chunky.

How do I know it's working?

Run /nlag status — you will see current TPS, CPU, heap, per-world states, and lifetime activation counts. Run /nlag simulate 10 to force CRITICAL state and watch mobs respond in real time.

Is the config validator mandatory?

No, but strongly recommended. Run /nlag validate after every manual config edit to catch type mismatches, out-of-range values, and missing fields before they cause runtime errors.

What happens to mobs when I do /nlag reload?

As of 1.5.1: all pending batch tasks are cancelled, restoreAll() runs (mobs get full AI back), then all services restart with the new config. No mobs are left in a restricted state.


📄 Credits

Author: Duong2012G License: Apache 2.0 Modrinth: https://modrinth.com/user/Duong2012G

Open source — contributions welcome.


📋 Changelog

See CHANGELOG.md for a full version history.

Recent highlights:

  • 1.5.2 — 5 targeted bug fixes: wrong api-version in plugin.yml, web token not generated when disabled, culling count wrong with protected zones, AI update scheduler saturation, stress test crash on dense spawn areas, MySQL reconnect log spam
  • 1.5.1 — 4 critical + 5 high bug fixes: task leak, mob freeze, entity scan cache, FOLLOW_RANGE restore, query-token security, Redis/MySQL stability, zone culling, lang backup
  • 1.4.0 — Lifecycle overhaul, zone protection, backup bundles, web auth improvements
  • 1.3.0 — Predictive scheduler, zone manager, web dashboard, multi-server sync, config profiles, backup system, developer API

Совместимость

Minecraft: Java Edition

1.21.x1.5.x

Платформы

Поддерживаемые окружения

Сервер

Создатели

Детали

Лицензия:Apache-2.0
Опубликован:1 месяц назад
Обновлён:5 дней назад
Главная