Links
Tags
Creators
Details
All versions
Changed —
2.0.2
Beta
Fake Player Plugin (FPP) 2.0.24 months ago 1,025
Compatibility
Minecraft: Java Edition
26.2
26.1.x
1.21.x
Platforms
BungeeCord
Folia
Paper
Purpur
Velocity
Changes
v2.0.2 (Beta)
Fixed — Permissions No Longer Bypass LuckPerms
- Removed the hard-coded
player.isOp()shortcuts (Perm.hasOrOp,BotAccess.isAdmin,BotListGui.isAdmin,BotSettingGui.isOp) that granted admin access to server operators even when a permissions plugin like LuckPerms explicitly denied the relevantfpp.*node. Every permission check now goes throughhasPermission()only, so LuckPerms grants/denies are always respected, operators included. - Fixed
canUse()gates that were stricter than the granular permission nodes they were meant to allow — players granted onlyfpp.left-click.once/.stop,fpp.right-click.once/.stop,fpp.despawn.own,fpp.move.to/.coords, orfpp.inventory.ownwere previously blocked at the command dispatcher before those fine-grained nodes were ever checked. - Added the missing
fpp.inventory.ownpermission constant and wired it into the/fpp inventorycommand and the right-click-to-open-inventory listener — this node was documented inplugin.ymlbut had no effect at all.
Fixed — Folia Compatibility
- Fixed a
TickThreadcrash ("Accessing entity state off owning region's thread") when refreshing a bot's floating name-tag activity line. The nametag refresh loop now dispatches to each bot's owning region thread on Folia instead of running on the global region thread. - Fixed bots showing their vanilla over-head name doubled up with the custom name-tag display on Folia. Folia's
Scoreboard/Team API is a documented gap (global state the project hasn't implemented for regionised ticking), so
hiding the vanilla name no longer touches
Bukkit.getScoreboardManager()/Teamat all — aPlayerTeamis built directly from NMS and itsClientboundSetPlayerTeamPackets are sent straight down each viewer's connection. - Fixed a client-crashing bug in that same rework: sending a "remove from team" packet for a bot whose name had never actually been added (e.g. a second bot's very first spawn) made the vanilla client throw and disconnect ("Network Protocol Error"). The plugin now only sends a removal for a name it actually tracked as hidden.
- Fixed
onDisable()crashing on Folia withIllegalPluginAccessException("Plugin attempted to register task while disabled") when despawning bots during shutdown.FppSchedulernow detects a disabled plugin and runs the work directly instead of scheduling it — safe, since Folia halts all region ticking beforeonDisable()runs. - Fixed Head-AI being hard-disabled on Folia entirely. The restriction predated the current per-bot region-thread dispatch and was never removed after the rest of the tick loop became Folia-safe; it now runs on Folia the same as on Paper.
Changed — /fpp spawn Is Now In-Game Only
/fpp spawncan no longer be run from the server console (or dispatched as console) — it requires a real player sender, matching most other bot commands.- Removed world/coordinate targeting (
/fpp spawn <world> [x y z]) — a bot always spawns at the commanding player's own location now. Thefpp.spawn.coordspermission node is gone along with it.
Performance
- Removed reflective
Method.invoke()calls from every hot per-tick NMS path inNmsPlayerSpawner(doTick(),getHandle(), and everything built on it —setJumping,setHeadYaw,setMovementForward,setMovementStrafe,applyServerVelocity, and more) in favor of direct calls.ServerPlayer.tickPhysics()'sdoTick()invocation alone accounted for ~69% of the plugin's own profiled self-time in benchmark reports; this scales linearly with bot count, so the win grows with server size.
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:oioBwOz4:w1dVYdvm"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:oioBwOz4:w1dVYdvm"
}

