AntiESP
A Paper plugin that makes ESP / wallhack / xray cheats far less useful by never
sending the client information it should not be able to see in the first place.
Three independent protections in one plugin:
| # | Protection | What it does |
|---|---|---|
| 1 | Player hiding | Players behind walls are removed client-side for the viewer (optionally keeping a floating nametag and their tab-list entry). |
| 2 | Block disguise | Chests, shulkers, spawners, barrels … look like plain stone from a distance. |
| 3 | Ore obfuscator | Self-written anti-xray: real ores are hidden, fake ore veins are scattered in, and caves can be filled with solid rock (freecam-proof). |
Everything is configurable in config.yml, and every feature can be turned off
individually.
Requirements
- Paper 1.21.8 (or a compatible build) — the plugin uses the Paper API
- Java 21
- Optional: PacketEvents
— required for packet mode (cave filling / freecam protection) and for keeping
hidden players in the tab list. Without it the plugin still runs, just with the
block-mode feature set.
Installation
- Drop
AntiESP-1.0.0.jarinto your server'splugins/folder. - (Recommended) Drop
PacketEventsintoplugins/as well. - Start the server —
plugins/AntiESP/config.ymlis generated on first run. - Before going live with packet mode, run the
identity-testonce (see
Ore obfuscator).
Building from source
mvn clean package
The jar ends up in target/AntiESP-1.0.0.jar. Both dependencies are provided,
so nothing is shaded in — the jar stays tiny.
1) Player hiding
For every viewer/target pair the plugin ray-traces the line of sight
(Amanatides & Woo voxel traversal, RayTracer) and picks one of three states:
- VISIBLE — close by or in clear sight: nothing changes.
- NAMETAG — occluded at medium range: the player model and hitbox are hidden,
but a floating name (a proxyTextDisplay) stays visible. - GONE — occluded and far away: completely invisible.
Hiding starts at min-distance (default 12 blocks) and only when more than
walls-to-hide opaque blocks are in the way. Several target points on the body
are checked — a player is only hidden when all of them are occluded, so nobody
pops out of existence while half-visible around a corner.
Key options:
| Option | Default | Meaning |
|---|---|---|
check-interval-ticks | 10 | How often visibility is recalculated |
min-distance | 12.0 | Below this distance players are always visible |
max-distance | 96.0 | Upper bound for the check (0 = no limit) |
walls-to-hide | 2 | Hide when the wall count is greater than this |
require-occlusion | true | Only hide genuinely occluded players |
keep-nametags | true | Keep the floating name for hidden players |
nametag-max-distance | 48.0 | Beyond this the nametag disappears too |
keep-tablist | true | Keep hidden players in the tab list (needs PacketEvents) |
Sneaking hides the nametag immediately instead of waiting for the next tick.
Note: a visible nametag still roughly gives away a position. Set
keep-nametags: falsefor the strongest protection.
2) Block disguise
Valuable block-entities are replaced with stone (disguise-as) via
sendBlockChange for viewers that are far away or looking through walls. Walk
closer than reveal-distance and the real block comes back, so containers open
normally. Uses only the Bukkit API — no ProtocolLib, no PacketEvents.
By default chests, trapped chests, ender chests, barrels, hoppers, droppers,
dispensers, all shulker boxes, spawners, trial spawners, vaults, brewing stands,
beacons, furnaces, blast furnaces, smokers and decorated pots are disguised. Edit
the block-disguise.blocks list, or set all-block-entities: true to cover every
block-entity (signs and banners included — this is noticeable).
3) Ore obfuscator (anti-xray)
A fully self-contained anti-xray implementation — no Paper anti-xray, no
Orebfuscator. Real ores are sent as stone/deepslate and fake ore veins are grown
in natural Y ranges and vein sizes.
Two modes:
| Block mode | Packet mode (recommended) | |
|---|---|---|
| Needs PacketEvents | no | yes |
| Hide enclosed real ores | ||
| Scatter fake ore veins | ||
| Fill small enclosed pockets | ||
| Fill large open caves (freecam-proof) | ||
| How | sendBlockChange after chunk load | rewrites the CHUNK_DATA packet itself |
Ores that border air are left real — you would see them anyway — so the world
"normalizes" itself exactly where a player could legitimately look. In packet
mode a proximity reveal flood-fills through the connected cave air you are
standing in and uncovers the whole cave system, direction-independently, spread
across a few ticks. Revealed blocks stay revealed until relog. Nether and End are
not obfuscated at all.
The fake pattern is seeded from a secretSalt generated with SecureRandom at
every server start (RAM only) XOR'd with the chunk coordinates: stable per chunk
(no flickering), but not reproducible without the salt.
Test packet mode first. Rewriting the chunk binary format is version
sensitive. Setore-obfuscation.identity-test: true, restart, and check that
the world looks normal — that decodes and re-encodes every chunk packet without
changing anything. If it looks fine, set it back tofalse.
Full details, tuning advice and the honest limitations (notably: anyone who
knows the world seed can regenerate ore positions server-side, no client-side
obfuscation can prevent that) are in docs/ANTI-XRAY.md.
Commands & permissions
| Command | Description |
|---|---|
/antiesp reload | Reload config.yml and clear the chunk cache |
/antiesp status | Show the active settings, mode and cache sizes |
| Permission | Default | Description |
|---|---|---|
antiesp.admin | op | Access to /antiesp |
antiesp.bypass | false | This player is never hidden from others and sees the real, unobfuscated world |
packet-modeandidentity-testare only applied on a server restart, not
via/antiesp reload.
Project layout
src/main/java/dev/antiesp/
AntiESPPlugin.java entry point, events, commands
PlayerVisibilityService.java player hiding + proxy nametags
TabListKeeper.java keeps hidden players in the tab list (PacketEvents)
BlockDisguiseService.java container/block-entity disguise
OreObfuscationService.java anti-xray, block mode
ChunkPacketObfuscator.java anti-xray, packet mode (CHUNK_DATA rewriting)
ProximityRevealer.java persistent flood-fill cave reveal
RayTracer.java voxel ray tracing for occlusion counting
src/main/resources/
config.yml, plugin.yml
docs/ANTI-XRAY.md in-depth anti-xray documentation (German)
Performance notes
- Packet mode computes per chunk on the Netty threads; results are cached
(max-cache-chunks, default 6000) and invalidated when blocks are mined. - Only player block-breaking invalidates the cache — TNT, pistons and water do
not, currently. - The proximity reveal only re-floods when you move to a new block, mine, or
join; standing still and turning around costs nothing.
Similar projects
Plugin →VeinMiner
Mine the whole vein on mining a single ore/block. Make the tedious mining experience to something satisfying and fun! FTB Ultimine alternative
99.3MSueta
Simple Voice Chat
A working voice chat in Minecraft!
76.8MSueta
Chunky
Pre-generates chunks, quickly and efficiently
18.4MSueta
VeinMiner Enchantment
Veinminer Addon - Adds vineminer enchantment to enchanting tables. Only tools with the enchantment can veinmine
18MSueta
JourneyMap
Real-time map used for mapping in-game or your browser as you explore.
14.7MSueta
WorldEdit
A Minecraft Map Editor... that runs in-game! With selections, schematics, copy and paste, brushes, and scripting. Use it in creative, or use it temporarily in survival.
11.6MSueta