
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
NeuroLag 1.3.0
release15 марта 2026 г.[1.3.0] — 2026-03-15
🐛 Bug Fixes (9 fixes)
BUG-A — ZoneManager: world name dropped from cuboid zones (cross-world contamination)
- Root cause:
ZoneManager.initialize()parsed zone entries as"world x1 y1 z1 x2 y2 z2"(7 parts) but stored onlyparts[1]..parts[6]in a rawdouble[], silently discardingparts[0](the world name). - Effect: A zone defined in world
survivalwould also protect mobs at the same coordinates inworld_nether,world_the_end, and any other loaded world. Mobs in unintended worlds were immune to optimization. - Fix: Replaced
List<double[]>withList<CuboidZone>whereCuboidZoneis a JavarecordholdingString world+ 6 coordinates.isProtected()now checksmob.getWorld().getName().equals(z.world())before testing coordinates.
BUG-B — RegionOptimizer: negative chunk coordinates mapped to wrong region
- Root cause: Region index was computed as
chunkX / regionSizeusing Java integer division, which truncates toward zero. Chunk-1 / 16 = 0and chunk1 / 16 = 0, so chunks in the negative quadrant near spawn mapped to the same region keys as their positive counterparts. - Effect: The HOT region around coordinate origin (0,0) was effectively double-sized. Mobs at negative chunk coordinates near spawn were optimized even when a player was present nearby.
- Fix: Replaced
/withMath.floorDiv()in bothrefresh()andisHot().Math.floorDiv(-1, 16) = -1(correct),Math.floorDiv(15, 16) = 0(correct).
BUG-C — DashboardManager: type: HOLOGRAM silently did nothing
- Root cause:
DashboardManager.start()returned early withif (!dashboardType.equals("BOSSBAR")) return— no log message, no error. Admins who setdashboard.type: HOLOGRAMsaw no dashboard and received no indication why. - Fix: Added an explicit
plugin.getLogger().warning()message when a non-BOSSBAR type is configured, clearly stating that only BOSSBAR is currently supported.
BUG-D — BackupManager: creationTime() unreliable on Linux (ext4)
- Root cause: Backup rotation used
Files.readAttributes(...).creationTime()to sort backups oldest-first. The ext4 filesystem does not store inode creation time — it returnsInstant.EPOCH(1970-01-01) for all files, making sort order undefined. - Effect: On Linux servers, the "oldest" backup was selected randomly. The wrong backup could be deleted or restored.
- Fix: Replaced
creationTime()withFiles.getLastModifiedTime(), which is reliably stored on all filesystems. Also removed the now-unusedBasicFileAttributesimport.
BUG-E — StressTestManager: always spawned at world[0] spawn, ignoring admin's location
- Root cause:
start()hardcodedBukkit.getWorlds().get(0).getSpawnLocation()as the spawn center regardless of where the admin was or which world they were in. - Effect: Running
/nlag stresstestfrom the Nether or End spawned mobs in the Overworld at spawn, making the test meaningless for other worlds. - Fix:
start()now accepts aCommandSenderparameter. If the sender is aPlayer, mobs spawn centered on the player's current location in their current world. Console fallback remainsworld[0]spawn.
BUG-F — WebDashboard: POST /api/cmd blocked by CORS preflight (OPTIONS)
- Root cause: Browsers send an HTTP
OPTIONSpreflight request before a cross-originPOST. The server had no handler forOPTIONSand returned405 Method Not Allowed, causing the browser to abort the actualPOST. - Effect: The "send command" button in external web dashboards or REST clients always failed silently.
- Fix: Added
sendCorsOptions()helper that returns204 No ContentwithAccess-Control-Allow-Methods: GET, POST, OPTIONSandAccess-Control-Allow-Headers: Authorization, Content-Type. Both/api/statusand/api/cmdnow handleOPTIONSbefore auth checks.
BUG-G — AuditManager: getLivingEntities() / getLoadedChunks() called on main thread
- Root cause:
snapshot()iterated all entities and chunks synchronously on the main thread before handing off to async write. - Effect: On servers with many mobs or chunks, this could stall the main thread for several milliseconds during audit generation.
- Mitigation: Added an explicit code comment documenting this limitation and the reason it is required by the Bukkit API. A full async snapshot would require a thread-safe entity iterator not currently available in Paper's public API.
BUG-H — ProfileManager: clearProfile() required a full cfg.reload() to restore values
- Root cause:
switchProfile()overwrotecfg.tpsCritical,cfg.tpsMedium, andcfg.maxEntitiesdirectly.clearProfile()only setactiveProfile = nulland left a comment saying "caller is responsible for reloading", whichNeuroLag.javaimplemented by callingcfg.reload() + engine.restoreAll() + startMonitor()— a heavy operation that re-read disk and restarted all tasks. - Fix:
ProfileManagernow saves the three base values insaveBaseValues()(called in the constructor and after everycfg.reload()).clearProfile()restores them directly — no reload required./nlag profile clearno longer triggers a full config reload cycle.
BUG-I — LagEngine: "Animation Freezing" comment/name mismatched actual behavior
- Root cause: Feature F4 was named "Animation Freezing" throughout the codebase, but the implementation only called
mob.setVelocity(0,0,0). This stops movement drift but does not freeze animation frames — mobs still visibly idle-animate. - Fix: Renamed the in-code comment to "Velocity Freeze" and added a note explaining that true animation-frame control requires NMS/packet-level access not available through the standard Bukkit API.
🔧 Other Changes
plugin.yml: version bumped to 1.3.0; permission descriptions clarified;neurolag.stresstestdescription now mentions mobs spawn at your locationpom.xml: version bumped to 1.3.0StressTestManager.start()signature changed tostart(int count, int durationMinutes, CommandSender sender)— callers updated inNeuroLag.javaProfileManager.saveBaseValues()is now public soNeuroLag.javacan call it after/nlag reload
NeuroLag 1.2.0
release14 марта 2026 г.[1.2.0] — 2026-03-14
🎉 All 18 Advertised Features — Now Fully Implemented
Every feature listed in the README and CHANGELOG since v1.1.0 now has real working code.
New Java Classes (15 new files)
| Class | Feature |
|---|---|
CpuMonitor.java | F1 — CPU throttling via com.sun.management.OperatingSystemMXBean |
RegionOptimizer.java | F2 — 16×16 chunk region grid, HOT/COLD classification |
MobWeightManager.java | F3 — Per-type weight budget per chunk |
DashboardManager.java | F6 — Live BossBar (BLUE→YELLOW→RED) for all operators |
AuditManager.java | F7 — Full HTML audit report (specs, plugins, mobs, chunks) |
MultiServerSync.java | F8 — Redis Jedis pub/sub + MySQL JDBC upsert |
WebDashboard.java | F10 — Embedded HTTP server (JDK HttpServer), live JS chart, JSON API |
PredictiveScheduler.java | F11 — Per-hour TPS pattern tracking + peak-hour config |
ZoneManager.java | F12 — Cuboid zone list + WorldGuard region soft-depend |
ProfileManager.java | F14 — Instant profile switching (critical-tps / medium-tps / max-entities) |
AlertManager.java | F15 — Sound + particle + chat alerts for CRITICAL enter/leave |
StressTestManager.java | F16 — Mob spawning stress test with auto-cleanup and report |
ConfigValidator.java | F17 — Range/sanity checks for all config fields |
BackupManager.java | F18 — Periodic backup + purge + restore |
NeuroLagAPI.java | F5 — Static public API + plugin messaging channel neurolag:metrics |
Features Integrated into Existing Classes
| Feature | Location |
|---|---|
| F4 — Animation Freezing (velocity zeroing for distant AI-disabled mobs) | LagEngine.applyAiBatched() |
F9 — AI Difficulty Scaling (getDifficulty() → TPS offset) | LagEngine.applyDifficultyScaling() |
| F13 — Smart Group Culling (type-aware, min-count guard, POOF particles) | LagEngine.cull() |
| F1 TPS penalty integration | LagEngine.tick() |
| F2 region check in optimization path | LagEngine.applyAiBatched() |
| F3 weight-sorted culling | LagEngine.cull() |
| F7 audit on critical event | LagReporter.onCriticalStart() |
| F12 zone protection skip | LagEngine.applyAiBatched() |
| F11 predictive penalty | LagEngine.tick() |
| F15 alert on state change | LagEngine.updateWorld() |
New Commands
/nlag dashboard [off]— toggle BossBar/nlag audit— generate HTML audit report/nlag zone— show loaded zone count/nlag profile [name|clear]— switch config profile/nlag validate— validate config with detailed errors/warnings/nlag backup [list|restore]— manage backups/nlag stresstest [count] [minutes]— run stress test/nlag sync— show Redis/MySQL peer server states
pom.xml Changes
- Jedis 5.0.0 (Redis) — shaded and relocated
- mysql-connector-j 8.3.0 — shaded and relocated
- WorldGuard 7.0.12 — provided/optional (soft-depend)
- Maven Shade plugin configured with relocation rules
plugin.yml Changes
softdepend: [WorldGuard]added
config.yml Changes
dashboard.enabledanddashboard.update-intervaladdedaudit-reports.generate-on-criticaladdedmulti-server.mysql.*section addedzone-protection.zoneslist addedconfig-profiles.profiles.*.medium-tpskey addedalerts.enabledtop-level flag addedstress-test.auto-generate-reportadded
Language Files
- All 7 language files updated to v1.2.0 header
- New keys:
dashboard-bar,alert-critical,alert-recovery,sync-no-peers,sync-peer
NeuroLag 1.1.0
release14 марта 2026 г.[1.1.0] — 2026-03-14
🎉 Major Release: 18 New Advanced Features!
✨ Added
Feature 1: CPU Throttling Mode
- Monitors server CPU usage (not just TPS)
- Activates automatic optimization when CPU > 80%
- Reduces Bukkit task frequency during critical CPU load
- Disables non-essential block physics updates
- Configuration:
cpu-throttling.enabledandcpu-throttling.cpu-threshold
Feature 2: Region-Based Optimization
- Splits world into 16×16 chunk regions
- Disables pathfinding for mobs in far regions
- Smart regional mob optimization instead of global
- Mobs near players always keep full AI
- Configuration:
region-optimization.enabledandregion-optimization.use-regions
Feature 3: Custom Mob Tier Weights
- Assign different "cost" to different mob types
- Zombies cost 1.0, Endermen cost 2.0, Ender Dragons cost 4.0
- Prevents over-optimization (allows more weak mobs)
- Configuration:
mob-weights.weights.*andmob-weights.max-weight-per-chunk - Result: More realistic mob balance during lag
Feature 4: Animation Freezing
- In CRITICAL state, mobs stop playing animations (head turning, arm swinging)
- Only applies to distant mobs (configurable)
- Reduces visual strangeness of frozen mobs
- Configuration:
animation-freezing.enabledandanimation-freezing.freeze-distance-chunks
Feature 5: Real-Time Metrics API
- Other plugins can query NeuroLag's current state
- Methods:
neurolag.getWorldState(),neurolag.getTPS(),neurolag.getAffectedMobCount() - Enable plugin ecosystem around NeuroLag
- Configuration:
metrics-api.enabledandmetrics-api.expose-via-plugin-message
Feature 6: In-Game Dashboard
- Live server health dashboard (BOSSBAR or HOLOGRAM)
- Changes color: BLUE (normal) → YELLOW (MEDIUM) → RED (CRITICAL)
- Updates every 2 seconds
- Configuration:
dashboard.type,dashboard.bossbar,dashboard.hologram
Feature 7: Detailed Lag Audit Reports
- Generate comprehensive lag analysis reports
- Include: server specs, plugin list, chunk stats, mob breakdown, player behavior, network stats
- Export to HTML for easy reading
- Configuration:
audit-reports.enabledandaudit-reports.include - Result: Deep understanding of what causes lag
Feature 8: Multi-Server Sync (Bungeecord/Velocity)
- Share TPS data across all servers
- Redis or MySQL backend support
- Cascade warnings to all servers if one is in CRITICAL
- Load-balance: suggest players move to less-lagged server
- Configuration:
multi-server.enabled,multi-server.backend,multi-server.sync-tps
Feature 9: AI Difficulty Scaling
- Easy mode = aggressive optimization
- Normal mode = balanced
- Hard mode = minimal optimization (players want challenge)
- Hardcore = zero optimization
- Configuration:
ai-difficulty-scaling.enabledandai-difficulty-scaling.scale-with-difficulty - Result: Respects player expectations
Feature 10: Mobile Web Dashboard
- Access metrics from any browser (phone, tablet, PC)
- Real-time TPS graph, mob count, heap usage
- Send commands remotely (
/nlag reload,/nlag toggle) - Token-based authentication
- Configuration:
web-dashboard.enabled,web-dashboard.port,web-dashboard.auth.token - Result: Monitor and control server on the go 📱
Feature 11: Predictive Lag Prevention
- Learns hourly patterns (6pm = always lag, etc)
- Pre-activates optimization before peak hours hit
- Configuration:
predictive-prevention.enabled,predictive-prevention.peak-hours - Result: Be proactive, not reactive
Feature 12: Custom Zones (WorldGuard Integration)
- Mark important regions as HIGH_PRIORITY via WorldGuard
- Examples: boss arenas, spawn, player shops, farms
- Full mob AI always kept in protected zones
- Aggressive optimization elsewhere
- Configuration:
zone-protection.enabledandzone-protection.integrate-worldguard - Result: Protect what matters most
Feature 13: Entity Grouping & Smart Removal
- Remove mobs intelligently during culling
- Never remove single mob types (won't inactivate farms)
- Remove in groups (visually less obvious)
- Particle effect on removal
- Configuration:
smart-culling.enabled,smart-culling.cull-in-groups,smart-culling.min-type-before-cull
Feature 14: Configuration Profiles
- Create multiple config profiles (survival, minigame, peaceful, etc.)
- Switch instantly with
/nlag profile <n> - Each profile can have different TPS triggers and entity limits
- Configuration:
config-profiles.enabledandconfig-profiles.profiles.* - Result: Perfect for multi-mode servers
Feature 15: Audio & Visual Alerts
- Sound alerts when entering/leaving CRITICAL
- Particle warnings around admin
- Chat notifications to all ops
- Customizable sounds (default: bass drop for CRITICAL, pling for recovery)
- Configuration:
alerts.enable-sound-alerts,alerts.alert-sounds.*,alerts.enable-particle-warnings - Result: Immediate awareness without checking commands
Feature 16: Stress Test Mode
- Simulate heavy server load without real players
- Spawn fake mobs (configurable count)
- Test for X minutes and auto-generate report
- Configuration:
stress-test.enabled,stress-test.spawn-fake-mobs,stress-test.fake-mob-count - Result: Safe testing environment 🧪
Feature 17: Configuration Validator
/nlag validatechecks config syntax and values- Warns about invalid settings
- Suggests optimizations
- Configuration:
config-validator.enabled - Result: Prevent config errors before they cause problems
Feature 18: Automatic Config Backup
- Auto-backup config every X minutes (default: 60)
- Keep last N backups (default: 10)
- Auto-restore if invalid config detected
- Configuration:
auto-backup.enabled,auto-backup.backup-interval-minutes,auto-backup.keep-backups - Result: Never lose your config
🌍 Multilingual Support (Added)
- English (EN) — Default
- Tiếng Việt (VI) — Vietnamese
- Español (ES) — Spanish
- Français (FR) — French
- Deutsch (DE) — German
- 日本語 (JA) — Japanese
- 中文 (ZH) — Chinese (Simplified)
Set language in config.yml: settings.language: EN
📝 Documentation
- Completely rewritten README with all 18 features documented
- Multilingual documentation in README (7 languages)
- Comprehensive CHANGELOG (this file)
- Detailed config.yml with all features documented
🔧 Command Enhancements
New commands added:
/nlag dashboard— Show in-game dashboard/nlag audit— Generate audit report/nlag zone— Zone management/nlag profile <n>— Switch config profiles/nlag validate— Validate configuration/nlag backup— Manage config backups/nlag stresstest— Run stress test
🔐 Permission Enhancements
New permissions added:
neurolag.stresstest— Run stress testsneurolag.dashboard— View dashboardneurolag.audit— View audit reportsneurolag.zone— Manage zonesneurolag.profile— Switch profilesneurolag.validate— Validate configneurolag.backup— Manage backupsneurolag.web— Access web dashboardneurolag.api— Access metrics API
📊 Configuration Changes
- Added 18 new configuration sections (one per feature)
- All features can be individually enabled/disabled
- Backward compatible with v1.0.6 configs
- Old config keys still work (will be migrated automatically)
🎯 Performance Improvements
- CPU throttling reduces unnecessary task execution
- Region-based optimization replaces global optimization
- Smart culling reduces entity processing
- Predictive prevention prevents lag spikes before they happen
🐛 Bug Fixes (from v1.0.6)
- ✅ Tick-rate throttling properly activates in MEDIUM state
- ✅ Manual override (
/nlag toggle) now truly pauses monitoring - ✅ Simulate mode no longer throws errors on invalid input
- ✅ Recovery notifications always fire (not suppressed by cooldown)
- ✅ Stale cooldown timestamps cleared on reload
📈 Version Info
- Version: 1.1.0
- Target: Paper 1.21+, Java 21+
- Release Date: 2026-03-14
- Total Features: 18 (from 16 in v1.0.6)
- Supported Languages: 7
- New Files: None (all backwards compatible)
NeuroLag 1.0.6
release11 марта 2026 г.[1.0.6] — 2025-03-11
Fixed
-
Bug — Tick-Rate Throttling (Feature 2) never activated
InapplyAiBatched,shouldHaveAiwas alwaystruefor MEDIUM state becauseglobalAiOn = !state.equals("CRITICAL")evaluates totrue. The throttle condition!shouldHaveAiwas therefore alwaysfalse, so distant mobs in MEDIUM were silently given full AI instead of being throttled.
Fix: chunk proximity is now evaluated independently first. Near-player mobs always get full AI; distant mobs in MEDIUM state enter the throttle queue; CRITICAL mobs getsetAI(false)as intended. -
Bug —
/nlag toggledid not actually pause monitoring
SettingmanualOverride = truehad no effect ontick()— the scheduler task continued running. Fix:monitorTask.cancel()is now called when pausing;startMonitor()is called when resuming (existing behaviour). -
Bug —
/nlag simulate clearthrewNumberFormatException
Tab-complete suggested"clear"as a valid argument, but the code passed it directly toDouble.parseDouble(), crashing with an unhandled exception.
Fix: an explicitequalsIgnoreCase("clear")check now runs before the parse. -
Minor — Recovery (NORMAL) action bar could be suppressed by cooldown
The 5-second notify cooldown was applied to all state transitions, including CRITICAL → NORMAL recovery. If a CRITICAL message had just been sent, admins would miss the recovery notification entirely.
Fix: cooldown only throttles MEDIUM/CRITICAL spam; NORMAL recovery always fires. -
Minor —
notifyTimesmap not cleared onrestoreAll()
Stale cooldown timestamps persisted across/nlag reloadand plugin restarts, causing the first post-reload notification to be silently dropped.
Fix:notifyTimes.clear()added torestoreAll().
[1.0.5] — 2025-03-10
Added
-
Feature 1 — Chunk-Based AI Throttling
Mobs within a configurable chunk radius of any online player always retain their AI, even in CRITICAL state. Only mobs in truly unobserved chunks are disabled. Controlled bychunk-ai.enabledandchunk-ai.distance-chunks. -
Feature 2 — Tick-Rate Throttling
In MEDIUM state, instead of hard-disabling mob AI, a dedicated per-tick task cycles through distant mobs and enables their AI for exactly 1 tick every N ticks. Mobs appear sluggish rather than completely frozen, which feels far more natural in-game. Controlled bytick-throttle.enabledandtick-throttle.ticks-per-ai-tick. -
Feature 3 — Spawn Rate Suppression
During MEDIUM or CRITICAL lag, world monster and animal spawn caps are temporarily lowered to reduce new mob generation. Limits are fully restored on recovery. Controlled byspawn-suppression.*. -
Feature 4 — Per-Player Action Bar Notification
When a player has affected mobs within a configurable radius, they receive a personal action bar message explaining why nearby mobs seem different. Previously only ops received any notification. Controlled byper-player-notify.*. -
Feature 5 —
/nlag simulate <tps>
Overrides the TPS value used by the engine without affecting the real server. Allows admins to test threshold configurations, Discord alerts, and reports without needing actual server lag. Running/nlag simulatewith no argument clears the override. -
Feature 6 — Auto Lag Reports
After recovering from a CRITICAL event that lasted longer thanmin-duration-seconds, a timestamped report is written toplugins/NeuroLag/lag-reports/. Each report includes world name, duration, lowest TPS reached, recovery TPS, affected mob count, online player count, and JVM heap statistics. -
Feature 7 — Entity Whitelist
SpecificEntityTypenames can be added totargets.whitelist-typesto permanently exempt them from all optimization and culling. Additionally,protect-named-mobsandprotect-tamed-mobsoptions prevent NeuroLag from touching player pets, named mobs, and boss entities. -
Feature 8 — Discord Webhook
Posts a rich Discord embed when a world enters CRITICAL lag and when it recovers. The recovery embed includes total CRITICAL duration and the lowest TPS reached. Uses Java 11+HttpClient— no external library required. Controlled bydiscord.*. -
Feature 9 — Memory Pressure Detection
Reads JVM heap usage ratio at each TPS check. When heap exceedstrigger-percent, an additional offset is subtracted from effective TPS before threshold evaluation, causing NeuroLag to act more aggressively when RAM is nearly exhausted. Controlled bymemory-pressure.*. -
Feature 10 — Player-Count Scaling
TPS thresholds are linearly scaled upward as the number of online players increases betweenmin-playersandmax-players. At maximum players, all thresholds shift up bymax-threshold-offsetTPS. Per-world threshold overrides are scaled the same way. Controlled byplayer-scaling.*. -
/nlag simulatetab-completion — suggests common TPS values (5, 10, 15, 18, 20). -
Heap stats in
/nlaghelp panel and/nlag status— shows used/max MB and percentage. -
World state icons in
/nlag status—●NORMAL,▲MEDIUM,✖CRITICAL. -
/nlag togglenow callsrestoreAll()before resuming the monitor, ensuring any frozen mobs are immediately unfrozen.
NeuroLag 1.0.4
release10 марта 2026 г.[1.0.4] — 2025-03-10
Fixed
- Deprecated BungeeCord API removed.
spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(...))was replaced with Paper's native Adventure API:player.sendActionBar(LegacyComponentSerializer.legacyAmpersand().deserialize(...)). The old API is not available on Paper 1.21.3 and would cause a crash or silent failure on action bar notifications. pom.xmlversion mismatch fixed.<version>was1.0.0whileplugin.ymldeclared1.0.3, causing Maven to produceNeuroLag-1.0.0.jarinstead of the expected filename.- Hysteresis buffer is now configurable. The recovery buffer (
0.5) was hardcoded incomputeStatus(). It is now read fromsettings.hysteresis-bufferinconfig.yml. /nlag graphwas undocumented. Added toplugin.ymlusage string and to the help message shown by/nlag.shouldOptimizeexplicit cast removed. The(Mob) entitycast afterinstanceof Mobcheck was unnecessary; replaced with pattern-matchinginstanceof Mob mobat the call site.togglecommand no longer leaves mobs frozen. When manual override is turned off,restoreAllAI()is now called before resuming the monitor task so any frozen mobs are immediately unfrozen.- TPS value capped at 20.0 before storing and displaying, preventing artificially high values (Paper can briefly report >20 TPS) from skewing the graph and average.
logEnablednow logs state transitions, including world name, new state, current TPS, and affected mob count — more useful for diagnosing server lag patterns.onDisablelog message added to confirm AI restoration on server shutdown.
Changed
config.ymlcomments rewritten in English and expanded with usage notes for each option.plugin.ymlusage string updated to list all four subcommands:reload,status,toggle,graph.computeStatusrefactored to useswitchexpression (Java 14+) for readability.drawGraphimproved: empty cells now render as░instead of a space, making the chart easier to read in chat.statuscommand now displays per-world states with a(no data yet)fallback when the monitor hasn't run yet.- Added
README.mdandCHANGELOG.md.
