Link: https://docs.papermc.io/paper/anti-xray
Help: https://discord.gg/papermc
Anti-Xray can be configured per world in the paper.yml configuration file. To understand how per world configuration works please read this first. Note that after changing any settings for Anti-Xray you have to restart your server. Executing the /reload
command (you should never do this) won't apply the settings to worlds that are already loaded.
The official documentation for the Anti-Xray settings and what they mean can be found here.
Basically Anti-Xray has two different modes. engine-mode: 1
replaces specified ores by "fake" stone, netherrack or end stone blocks depending on the world type and engine-mode: 2
randomly places specified fake ores when a chunk packet is sent to the client. The following picture[1] shows how this looks like for a player using Xray on your server.
engine-mode: 1
is less computationally intensive but engine-mode: 2
works better to prevent Xray. As you can see in the picture above, engine-mode: 1
isn't perfect because only ores that are completely covered by solid blocks can be hidden. This means that ores exposed to air in caves, for example, are still visible. In engine-mode: 2
fake ores obstruct the view to these ores and additionally fake air blocks can also be added.
These are the default settings for Anti-Xray. As already mentioned above, you should take a look at the official documentation. I've added some additional info in the comments below that isn't currently there.
world-settings:
default:
# Other default world-settings.
anti-xray:
# enabled controls the on/off state for the Anti-Xray system.
enabled: false
# engine-mode is described above.
engine-mode: 1
# As of 1.15.2 build #248 chunk-edge-mode doesn't exist anymore.
# This setting isn't necessary anymore because neighbor chunks are now usually loaded anyway.
# Sets how the engine handles chunk edges.
# Where 1 is not to obfuscate the edges of chunks with unloaded neighbors,
# 2 is to not send the chunk until its neighbors are present (similar to a x-1 view distance),
# and 3 is to load the neighbor so it can properly obfuscate the current edge (similar to an x+1 view distance).
chunk-edge-mode: 2
# As of 1.17 build #1 max-chunk-section-index doesn't exist anymore.
# This setting is replaced by the max-block-height setting.
# max-chunk-section-index controls the height the engine should operate to.
# y = (max-chunk-section-index + 1) * 16
# A max-chunk-section-index greater than 15 defaults to 15. A max-chunk-section-index smaller than 0 doesn't make sense.
max-chunk-section-index: 3
# max-block-height controls the height (y-coordinate) the engine should operate to.
# Only integer multiples of 16 are possible values.
# If another value is specified, it is "rounded down" to the nearest multiple of 16.
# As of 1.18 some ores are generated much higher.
# Please adjust the max-block-height setting at your own discretion.
# https://minecraft.fandom.com/wiki/Ore might be helpful.
max-block-height: 64
# update-radius is the radius for block updates, which send the real blocks to the client when a block is broken.
# There are only 3 valid options: 0, 1 and 2.
# An update-radius greater than 2 defaults to 2. An update-radius smaller than 0 defaults to 0.
# Don't use update-radius: 0 in production. This is only a test mode.
update-radius: 2
# Whether or not to obfuscate blocks touching lava.
# Doesn't work well with non-stone-like ore textures.
lava-obscures: false
# Whether or not to enable support for the paper.antixray.bypass permission.
# Depending on your permission plugin, this may cause performance issues.
use-permission: false
# In engine-mode: 1 hidden-blocks are replaced by stone, netherrack or end_stone depending on the world type.
# all types of air blocks are ignored in this list.
# In engine-mode: 2 hidden-blocks are randomly placed.
# tile entities such as chest or spawner are ignored in this list.
# blocks can be added multiple times to this list, those are used accordingly more often.
# an empty or invalid list or a list that only contains ignored blocks results in [diamond_ore].
# the default block states are placed.
hidden-blocks:
- copper_ore
- deepslate_copper_ore
- gold_ore
- deepslate_gold_ore
- iron_ore
- deepslate_iron_ore
- coal_ore
- deepslate_coal_ore
- lapis_ore
- deepslate_lapis_ore
- mossy_cobblestone
- obsidian
- chest
- diamond_ore
- deepslate_diamond_ore
- redstone_ore
- deepslate_redstone_ore
- clay
- emerald_ore
- deepslate_emerald_ore
- ender_chest
# In engine-mode: 1 replacement-blocks are not used. Changing this list in engine-mode: 1 has no effect.
# In engine-mode: 2 replacement-blocks and hidden-blocks are randomly replaced by hidden-blocks.
# tile entities such as chest or spawner are ignored in hidden-blocks.
# tile entities can be added to replacement-blocks.
# all types of air blocks aren't be replaced regardless of where they are added.
replacement-blocks:
- stone
- oak_planks
- deepslate
# Other default world-settings.
world-settings:
default:
# Other default world-settings.
anti-xray:
enabled: true
engine-mode: 1
chunk-edge-mode: 2
max-chunk-section-index: 3
# As of 1.18 some ores are generated much higher.
# Please adjust the max-block-height setting at your own discretion.
# https://minecraft.fandom.com/wiki/Ore might be helpful.
max-block-height: 64
update-radius: 2
lava-obscures: false
use-permission: false
hidden-blocks:
# There's no chance to hide dungeon chests but buried treasures will be hidden.
- chest
- coal_ore
- deepslate_coal_ore
- copper_ore
- deepslate_copper_ore
- raw_copper_block
- diamond_ore
- deepslate_diamond_ore
- emerald_ore
- deepslate_emerald_ore
- gold_ore
- deepslate_gold_ore
- iron_ore
- deepslate_iron_ore
- raw_iron_block
- lapis_ore
- deepslate_lapis_ore
- redstone_ore
- deepslate_redstone_ore
replacement-blocks:
- stone
- oak_planks
- deepslate
# Other default world-settings.
# world_nether: needs to be changed if your world is named differently.
world_nether:
anti-xray:
max-chunk-section-index: 7
max-block-height: 128
hidden-blocks:
- ancient_debris
- nether_gold_ore
- nether_quartz_ore
# world_the_end: needs to be changed if your world is named differently.
world_the_end:
anti-xray:
enabled: false
world-settings:
default:
# Other default world-settings.
anti-xray:
enabled: true
engine-mode: 2
chunk-edge-mode: 2
max-chunk-section-index: 3
# As of 1.18 some ores are generated much higher.
# Please adjust the max-block-height setting at your own discretion.
# https://minecraft.fandom.com/wiki/Ore might be helpful.
max-block-height: 64
update-radius: 2
lava-obscures: false
use-permission: false
hidden-blocks:
# You can add air here such that many holes are generated.
# This works well against cave finders but may cause client FPS drops for all players.
- air
- copper_ore
- deepslate_copper_ore
- raw_copper_block
- diamond_ore
- deepslate_diamond_ore
- gold_ore
- deepslate_gold_ore
- iron_ore
- deepslate_iron_ore
- raw_iron_block
- lapis_ore
- deepslate_lapis_ore
- redstone_ore
- deepslate_redstone_ore
replacement-blocks:
# Chest is a tile entity and can't be added to hidden-blocks in engine-mode: 2.
# But adding chest here will hide buried treasures, if max-chunk-section-index is increased.
- chest
- amethyst_block
- andesite
- budding_amethyst
- calcite
- coal_ore
- deepslate_coal_ore
- deepslate
- diorite
- dirt
- emerald_ore
- deepslate_emerald_ore
- granite
- gravel
- oak_planks
- smooth_basalt
- stone
- tuff
# Other default world-settings.
# world_nether: needs to be changed if your world is named differently.
world_nether:
anti-xray:
max-chunk-section-index: 7
max-block-height: 128
hidden-blocks:
# See note about air above.
- air
- ancient_debris
- bone_block
- glowstone
- magma_block
- nether_bricks
- nether_gold_ore
- nether_quartz_ore
- polished_blackstone_bricks
replacement-blocks:
- basalt
- blackstone
- gravel
- netherrack
- soul_sand
- soul_soil
# world_the_end: needs to be changed if your world is named differently.
world_the_end:
anti-xray:
enabled: false
[1] This picture was made by the user Oberfail#2096 on the PaperMC Discord.
Of course you can, however, I wouldn't add too many blocks if it's not absolutely necessary because that also increases the packet size. Adding
air
doesn't mean it's 100% safe either because more clever hacks could detect those fake air blocks by distinguishing them from real caves for example. Another thing is that if you addcave_air
, then I could also ask: Why not add water, lava, ...?The reason why you see the fake blocks as spectator in
engine-mode: 2
is theair
in thehidden-blocks
list. There is a permission nodepaper.antixray.bypass
that you can set to true for admins to bypass Anti-Xray. For this you have to enable the settinguse-permission
in the config. You can link that permission node via contexts to spectator mode using LuckPerms for example or you create an alias for the gamemode command that additionally sets this permission. Note that the fake blocks won't dynamically appear/disappear when the permission note is set. Resending chunks (e.g. rejoining or moving away from your current location and going back) is required. I have written a plugin that can resend chunks with a command. You can also add this command to your gamemode command alias, in case you define one.