### Performance Optimizations
- Rotation broadcast cache —
lastSentVisualRotationmap caches last broadcast yaw/pitch per bot; rotation packets dropped when delta < 0.5°, eliminating redundant head-rotation broadcasts under heavy load.- Direct NMS fast-paths —
sendRotationDirect()andsendPositionSync()callPacketSendListenerdirectly on the NMSServerGamePacketListenerImplinstead of Bukkit'ssendPacket(Player)wrapper.- Tab-list batching —
broadcastTabListRemove()sends a singleClientboundPlayerInfoRemovePacketper bot instead of N individual packet sends. Applied to all despawn paths.- Frozen bot early return — Skips all per-bot work (AI, physics, handlers, fall damage, position sync) for frozen bots at the top of the tick lambda.
- Location reuse —
beforeLocation captured once per tick and reused across head-AI target distance, mining-lock check, gaze vector, fall-damage delta, and position-sync threshold — eliminates redundantbot.getLocation()calls.- Throttled subsystems — Auto-eat runs every ~4 ticks per bot. Fall damage runs every other tick (accumulated fall distance is still tracked via NMS
getFallDistance()).- Active-bot UUID snapshot —
activeBotUuidsset built once per tick for O(1)contains()in head-AI filtering and tab-list remove.- Mining-lock optimization — Reuses
beforeLocation fordistanceSquaredcheck instead of callingbot.getLocation()again.
### Bugfixes
- Position sync dependency on Head AI —
onlineSnapshotand player-position arrays now always populated regardless ofdoHeadAi. Previously, when Head AI was disabled, position sync packets were never sent — bots appeared frozen on other clients.- Swim AI jumping-field reset — Removed incorrect
&& (isNavigating || isInWaterOrBubbleColumn(bot))guard that skippedtickSwimAi(). Thejumpingfield stuck attrueafter a bot exited water becausesetJumping(bot, false)was never called.- Ground detection for partial blocks —
isBotOnGround()restored toloc.clone().subtract(0, 0.08, 0).getBlock().isPassable(). ThegetBlockAt(getBlockX(), getBlockY()-1, ...)replacement misdetected slabs and stairs.isInBubbleColumn()deprecation — Replaced deprecatedPlayer.isInBubbleColumn()with block-type check.-Xlint:deprecationadded tocompileJava.
### Performance Subsystem
/fpp perfcommand —check/top/report/history/sparksubcommands. Background monitor samples TPS, MSPT, CPU, GC, memory everysample-interval-ticks, keeps rollinghistory-minutes, warns on consecutive threshold breaches.- Built-in self-profiler —
BuiltinFppProfilerwith lock-freeLongAddersampling, thread-local call stack, adaptive detail reduction. Enabled viaperformance.self-profiler.enabled.- Benchmark sessions —
/fpp perf reportstarts a 10-minute method-level benchmark, reminds every 2 minutes, exports Spark-style call tree toplugins/FakePlayerPlugin/performance-report/.- Perf providers —
SparkPerfProvider(preferred, reads Spark-API snapshots) andBuiltinPerfProvider(fallback via CraftServer + JMX).- Auto-export —
PerformanceReportExporterwrites.txtreports on: benchmark finish, threshold warning (export-on-warning: true), plugin disable, and fatal exceptions.- Perf placeholders —
%fpp_perf_tps%,%fpp_perf_mspt%,%fpp_perf_cpu_process%,%fpp_perf_cpu_system%,%fpp_perf_gc_avg_time%,%fpp_perf_gc_avg_frequency%,%fpp_perf_health%.- Profiling instrumentation — Hot paths in
FakePlayerManager.tick(),NmsPlayerSpawner.tickPhysics(),PacketHelper,tickSwimAi(),tickAutoEat(),fireTickHandlers(),tickFallDamage()profiled when self-profiler is active.- Language keys — Full
perf-*set inen.ymlfor all/fpp perfoutput.
### Config
- New
performance:block —enabled,spark-enabled,placeholders,sample-interval-ticks,history-minutes,warn-mspt,warn-tps,warn-consecutive-samples,warn-cooldown-minutes,auto-profiler-timeout-seconds,self-profiler.enabled,self-profiler.method-level,self-profiler.export-on-warning.- Swap player-aware settings — New
swap.player-aware.*keys for nearby-player detection radius, idle threshold, idle bonus percent, active penalty percent.ConfigMigrator— Updated for config-version 76 to handle new keys.FppMetricsintegration — FastStats metrics startup with graceful fallback when FastStats is unavailable.
### API & Internal
FppApi— AddedgetOnlineCount(),removePlayerBody(UUID)(shutdown-safe),disableAllAddons().FppScheduler—runAtEntityRepeatingWithId()returnsint taskIdfor per-entity repeating tasks.CommandManager—/fpp perfregistered withfpp.perfpermission (child offpp.opinplugin.yml).NmsPlayerSpawner—tickPhysics()reverted to originaldoTickMethod.invoke()via reflection; guard restored to|| doTickMethod == null.FakePlayerEntityListener— Removed exact damage-canceller detector/tracer in favor of simplerbody.damageableswitch.FakeChannelPipeline— Handler insertion refactored for channel-active vs connection-set path.BotPersistence—saveForShutdown()saves snapshot without clearingactive-botsto prevent destructive overwrite on restart.- Shutdown lifecycle — Profiler stopped before monitor; extension class loaders closed;
disableAllAddons()called;saveForShutdown()runs before body removal.
### Core Updates
- nLogin compatibility —NmsPlayerSpawnernow suppresses nLogin (com.nickuc.*)PlayerJoinEventlisteners for fake players alongside the existing SimpleVoiceChat suppression. Auth plugins that expect normal client login pipelines no longer kick/despawn FPP bots during spawn.
###Main Focus
- Fix bot despawn after spawn bug — bots no longer instantly despawn due to stale spawn-protection checks or missing WorldGuard session state after teleport/respawn
- PacketEvents fail injection — suppressed kicks caused by
"packetevents"+"inject"errors that triggered an infinite despawn loop on every bot join- LuckPerms patch — pre-caches LuckPerms user data before
placeNewPlayer()to preventServerThreadLookupExceptionon Folia and ensure Vault/WG hooks resolve correctly at spawn time
###Debug GUI & Chat Broadcasting
- Debug Settings GUI —
/fpp settingsnow has aᴅᴇʙᴜɢ category with 23 clickable toggles for every
debug.ymlcategory (master, general, startup, NMS, database, packets, network, config-sync, chat, swap, commands, head-ai, right-click, etc.)- Debug Chat Broadcast — new
debug-chat: falsekey indebug.yml. When enabled, allFppLogger.debug()output is sent to online players withfpp.oporfpp.notifyas in-game chat messages (gray prefix:[ꜰᴘᴘ DEBUG/<topic>] <message>)- Runtime debug toggling — debug categories can be flipped on/off without restarting via the GUI; changes are saved to
debug.ymlimmediately
###Left-Click Command Improvements
- Auto-target hostile mobs — bots now automatically detect and attack hostile mobs (Monsters, Slimes, Ghasts, Phantoms, Hoglins, Shulkers, EnderDragon) in their forward cone when no block is targeted
- Auto-aiming — bot head and body smoothly rotate to face the targeted mob
- Multi-flag parsing — fixed
--once,--repeat,--hold, and--stopflag handling so multiple flags can be specified correctly in a single command
###Bug Fixes & Stability
- LuckPerms cache warmup —
NmsPlayerSpawnerpre-loads LuckPerms user data beforeplaceNewPlayer()to preventServerThreadLookupExceptionon Folia- WorldGuard session refresh — complete rewrite using cold re-initialization via reflection (
tryRemoveSession+Session.initialize()) to prevent stale region data after bot teleports/world changes- Teleport/respawn WG refresh —
FakePlayerEntityListeneraddsPlayerTeleportEvent.MONITORandPlayerRespawnEventhandlers with delayed (1-2 tick) WG session refresh- Spawn protection teleport fix —
BotSpawnProtectionListenernow allowsPLUGINandCOMMANDteleports during the grace window so/fpp tphand cross-world moves work correctly; portals are still blocked- Despawn reason tracking — all
removeBot()calls now pass descriptive reasons (spawn_body_failed,command_despawn,gui_delete,badword_cleanup,packetevents_kick,kicked_by_server,api_despawn,rename_swap,body_remove, etc.) instead of"unspecified"- PacketEvents kick suppression —
FakePlayerKickListenersilently cancels kicks containing"packetevents"+"inject"instead of despawning the bot, preventing instant-despawn loops- Attribution/logging cleanup — silenced license heartbeat, JSON response, and integrity check logs unless explicitly enabled via
debug.yml- Placeholder formatting — cleaned up
formatUptimeone-liner inFppPlaceholderExpansion- Help GUI formatting — fixed indentation in lore builder
###Folia Config Patch
- Folia config issue patched — formatting normalization acrossbuild.gradle.kts,Config.java, andplugin.ymlto resolve Folia-related configuration loading problems
###Performance & Cleanup
- Silent License Verification — No more startup spam (Team ID, challenge, JSON response removed)
- Debug Logging Fixed — All NMS-BOT messages now respect
debug.yml(17 calls fixed)- Cleaner Startup Logs — Removed backups count, name pool size, debug section from banner
- Minimal Shutdown Log — Reduced from 7 lines to 4 lines
###Click Commands
- Left-Click Command — Replaced MineCommand (
/fpp left-click)- Right-Click Command — Replaced UseCommand (
/fpp right-click)- Legacy Removed — 2162 lines of mine/use/place code deleted
- Net Reduction — ~500 lines of code removed overall
###Config System
- debug.yml — All debug settings moved to separate file
- Config v75 — Auto-migrates and removes
logging.debug.*keys from config.yml- License Category Removed — No longer needed (silent verification)
###Other Changes
- Folia Support — Full compatibility with region-threaded spawning
- Permission Checks — Bot ownership validation for
/fpp attack --all,/fpp follow --all- New Flags —
/fpp despawn --own,/fpp delete --own- PlaceholderAPI — Updated to 2.12.2
###Documentation
- Updated: Changelog, Configuration, FAQ, Getting-Started, Home
- AGENTS.md added for development reference
### License System Updates
- License server migration — Switched license verification from
license.fpp.wtftoapp.lukittu.com- Frontend credential fetch — Credentials now fetched from
fpp.wtf/api/license/freewith HMAC signature verification- Improved license logging — Better error messages and debug logging for license verification failures
- API key authentication — Added Bearer token authentication for frontend API requests
### Bug Fixes
- License credentials fetch — Fixed API key encoding for frontend authentication
### Breaking Changes
- Folia support removed — FPP no longer supports Folia due to fundamental incompatibilities with regionised threading and entity ticking. Use Paper/Purpur instead.
- Body disable system removed —
body.enabledconfig option removed. Bots always spawn with physical bodies (tab-list only mode no longer available).- SpigotMC distribution removed — Plugin no longer distributed on SpigotMC. Download from Modrinth, PaperMC Hangar, or BuiltByBit.
### Features Removed
%fpp_body%placeholder — Removed along with body disable system.- Body toggle in GUI — Removed from Settings GUI (body category).
- Skin system toggle — Removed from Settings GUI.
### New Features & Improvements
- Pathfinding overhaul — Major improvements to
BotPathfinder.javaandPathfindingService.javawith better A* navigation, gap walking, block break/place support, and stuck detection.- Mine command improvements — Added actual block breaking via
nms.gameMode.destroyBlock(), improved progress tracking, and pickup flow.- Use command enhancements — Combined Use+Place functionality with
UseModeenum, flexible targeting from bot look direction, and better ray-tracing.- Head AI action locking — Added
actingBotsconcurrent set to fully disable head AI while bots perform actions (mining, using, placing).
### Bug Fixes
- PacketEvents injection error — Added try-catch wrapper around PacketEvents registration to prevent GrimAC/ViaVersion compatibility issues from breaking bot spawns.
- UseCommand NPE — Fixed null pointer when storing ray-trace targets; only stores non-null targets.
- Head AI during actions — Bots now properly disable head rotation while performing mine/use/place actions.
- Mining not breaking blocks — MineCommand now actually breaks blocks via NMS game mode.
### Code Quality
- Removed
spawnBody()config method and all references to body disable logic- Cleaned up
FakePlayerManager.javaspawn logic (no more bodyless mode)- Updated startup banner, metrics, and placeholders to remove body enable references
- Removed unused custom metrics from
FppMetrics.java- Removed outdated
AGENTS.mdfile- Added
note.mddevelopment tracking document
### Documentation
- Updated all wiki pages to reflect Paper/Purpur-only support
- Removed Folia-Support wiki page
- Updated FAQ to explicitly state Folia is not supported
- Updated legal documents (copyright, privacy-policy, extensions, terms-of-service)
- Updated README.md with platform changes
## v1.6.6.11
### Bug Fixes
- Online player count — bots now correctly subtracted from real-player count in
/fpp statsand network totals (commit6afca8a)- Database flush — runs outside the main thread to prevent server lag spikes (
f671781)- Batching logic — added proper batching for DB writes and network heartbeats (
528cf0e)- Removed dead writer/health-check logic that caused unnecessary DB overhead (
fcbe072)- Removed pointless bot record update before clearing the list on shutdown (
8c1eb56)
### Code Quality
- Removed unnecessarily fully qualified class names across codebase (
001416d)- General cleanup of dead code, unused fields, and redundant calls (
14d1803)
### Documentation
- Updated command reference with
extension --list,spawn --notp, andattack --moveflags- Synced config docs with
pathfinding.*,skin.*,help.*,ping.*,metrics.debug, andheartbeat.enabled
