-
Notifications
You must be signed in to change notification settings - Fork 7
Configuration Guide
This guide describes how to configure CoordinateOffset to apply "offsets" to each player.
The default plugin config will randomize all players' (except OPs) coordinates every time they log in. Give coordinateoffset.bypass
permission to see real coordinates.
An "offset" refers to a specific shift of a player's X- and Z-coordinate that will be applied to every packet sent to that player. For example, the plugin might apply an offset of [x=1600, z=-128]
to a player named SomePlayer
. When SomePlayer
joins the server, this is what they will see:
-
SomePlayer
spawns at the Overworld spawn point, which is located at(100, 100)
. They press F3, and the coordinates they see are(-1500, 228)
. -
SomeAdmin
, who is an operator on the server, has no offset. They teleport toSomePlayer
. WhenSomeAdmin
presses F3, the coordinates they see are the "real" coordinates of the world:(100, 100)
. -
SomePlayer
andSomeAdmin
both see the same world, and see each other. The only difference is the numbers they see in the F3 menu.
Offset values must be kept secret from players, or they will be useless. The default configuration applies a random offset to each player. Their offset changes every time they quit and re-join the server. However, there is much more flexibility for calculating and changing these offsets. This flexibility is configured through "Offset Providers".
The main configuration for CoordinateOffset is through "Offset Providers" in plugins/CoordinateOffset/config.yml
. In this file, you can configure any number of Offset Providers and apply them per-player, per-world, and more. Let's look at the set of Offset Providers provided in the default-generated config.yml
:
offsetProviders:
constant:
class: ConstantOffsetProvider
offsetX: 1024
offsetZ: 1024
worldScaling:
world_nether: 0.125
disabled:
class: ConstantOffsetProvider
offsetX: 0
offsetZ: 0
random:
class: RandomOffsetProvider
resetOnDeath: false
resetOnWorldChange: false
persistent: false
persistenceKey: default
randomBound: 100000
worldAlignment:
- world:world_nether:8
zeroAtLocation:
class: ZeroAtLocationOffsetProvider
resetOnDeath: false
resetOnWorldChange: false
worldAlignment:
- world:world_nether:8
Each provider consists of:
- A name for the provider (
constant
,disabled
,random
,zeroAtLocation
) - The provider class (
ConstantOffsetProvider
,RandomOffsetProvider
,ZeroAtLocationOffsetProvider
) - Configurations to apply to the provider class
You are allowed to define as many Offset Providers in this section as you want. Note that these providers will not be active unless you configure them to be applied: See Applying Offset Providers below.
The plugin offers 3 basic classes to define an Offset Provider:
The Constant Offset Provider class is the most basic way to define a static offset. There are only two required configuration keys for Constant Offset Providers:
Key | Type | Description |
---|---|---|
offsetX |
integer | The X-component of the offset that will always be created from this provider. |
offsetZ |
integer | The Z-component of the offset that will always be created from this provider. |
worldScaling |
Map | Optional scaling for specific worlds. Offsets in a world in this list will be multiplied by the value specified. This is a simple way to ensure that Nether Portals don't allow players to work out this offset - it is recommended to leave world_nether: 0.125 in vanilla-like servers. |
Remember that these numbers will subtracted from players' real coordinates.
As used in the default configuration, you can create a provider that uses offset components of 0 to behave as "no offset" - that is, players will be able to see their real, unshifted coordinates.
Example use cases for ConstantOffsetProvider:
- You want to shift the entire world so that players see the spawn point at (0, 0).
- You want to groups of players to be able to share coordinates within their group, but not leak those coordinates to other groups (each group uses a different constant offset).
The Random Offset Provider class generates a random offset for each player. This random offset can be kept constant for the same player, or re-rolled frequently to prevent coordinates from being useful.
Key | Type | Description |
---|---|---|
resetOnDeath |
boolean | If true, each player's random offset will be re-rolled whenever they respawn after dying. |
resetOnWorldChange |
boolean | If true, each player's random offset will be re-rolled whenever they enter a different world for any reason (e.g. using a portal, teleporting). |
persistent |
boolean | If true, players will have the same offset even after they quit and rejoin, and across server restarts. |
persistenceKey |
string | This is a unique identifier used to save players' persistent offset. It only has an effect when persistent=true . See Using Persistence. |
randomBound |
integer | The maximum possible X or Z value of a randomly-generated offset. Offsets will be within the range (-randomBound, randomBound) . |
worldAlignment |
List | Configuration for aligning worlds to use linked offsets. See Using World Alignment. |
Each world has its own independently-generated random offset. These offsets will only be linked together by using worldAlignment
rules.
Example use cases for RandomOffsetProvider:
- You want to prevent players from sharing coordinates, while still allowing them to use their own coordinates for navigation, world-map mods, and waypoints. (
persistent=true
,resetOn*=false
) - You want to buff in-game Death Compasses by shuffling coordinates when a player dies, preventing them from using "death point" mods. (
persistent=true
,resetOnDeath=true
,resetOn*=false
) - You want to completely negate the ability to use coordinates, in conjunction with
/gamerule reducedDebugInfo
, by randomizing the offset as frequently as possible. (persistent=false
,resetOn*=true
)
When persistent
is enabled, each player's random offsets are saved within their NBT data. You can use a tool like NBTExplorer to modify these offsets, or delete them so that they will be re-rolled.
Offsets are stored at the following location in player NBT, which is stored within <main world folder>/playerdata
:
BukkitValues:coordinateoffset.random-persistence.<persistenceKey>
This NBT entry acts like a Map, where "keys" are world names and "values" are offsets.
persistenceKey
on a provider, all players who previously had a persistent offset will have a different offset the next time they log in. Similarly, providers using the same persistence key will provide the same offsets to the same player. The provider will only load saved offsets that have a matching persistence key.
The Zero at Location Offset Provider class always generates an offset equal to the player's coordinates when the offset is generated. This means that players will see themselves at reasonably-sized coordinates while still not seeing their real coordinates.
Key | Type | Description |
---|---|---|
resetOnDeath |
boolean | If true, each player's coordinate system will be re-centered on their spawn point after they die. |
resetOnWorldChange |
boolean | If true, each player's coordinate system will be re-centered on the place where they first enter a world whenever their world changes. |
worldAlignment |
List | Configuration for aligning worlds to use linked offsets. See Using World Alignment. |
Example use cases for ZeroAtLocationOffsetProvider:
- You want to obfuscate coordinates between players and across sessions, but you don't want players to see their coordinates at the absurdly high values generated by the Random provider.
- You want to buff in-game Recovery Compasses by re-centering coordinates when a player dies, preventing them from using "death point" mods. (
resetOnDeath=true
)
After creating or configuring your Offset Providers, they will have no effect until you apply them. There are a few ways to do this:
Unless otherwise specified, players will use the Offset Provider specified in defaultOffsetProvider
.
You can optionally define a list of override rules in the configuration key offsetProviderOverrides
. Overrides look like this:
offsetProviderOverrides:
- provider: constant
permission: coordinateoffset.provider.my_custom_permission
world: world
- provider: zeroAtLocation
world: world_nether
playerUuid: 00000000-0000-0000-0000-000000000000
Override rules are processed in the order they are listed in the config. The first override for which all optional keys match the offset context will be selected. If no overrides match, the default offset provider will be selected.
Rule Name | Effect |
---|---|
provider |
(Required) Name of the provider configured in offsetProviders that any matches to this rule will use. |
world |
Filter this rule to a specific world by name (e.g. world , world_nether , world_the_end by default) |
playerUuid |
Filter this rule to only apply to a specific player. You can determine a player's UUID here. |
permission |
Filter this rule to only apply players that have a specific permission node. It is highly recommended that you define your own permission nodes here with the naming convention coordinateoffset.provider.something , and then give those permissions nodes to their intended groups, rather than trying to use a permission node defined by another plugin. |
world
filter rule in an override to apply different offset providers in different worlds.
Why?
CoordinateOffset needs to calculate a new offset very early in the world-change process so that the server can start sending new chunks to the player. At the point these permission checks run, most permissions plugins have not yet updated their context for that player to the new world. That means that when we ask "does this player have permission X?", the answer will apply to the old world, but the offset we're calculating will apply to the new world. On the other hand, the world
filter is correctly compared with the world the player is going to.
Randomize everyone's offset in the Overworld and Nether, but display real coordinates in The End:
defaultOffsetProvider: random
offsetProviderOverrides:
- provider: disabled
world: world_the_end
Obfuscate most players' coordinates, but allow trusted players to see their real coordinates:
defaultOffsetProvider: zeroAtLocation
offsetProviderOverrides:
- provider: disabled
permission: coordinateoffset.provider.see_real_coords # give this permission to the "Trusted" group
Only obfuscate coordinates for one player:
defaultOffsetProvider: disabled
offsetProviderOverrides:
- provider: random
playerUuid: 57d28dac-55f7-4584-97a7-7fb303c01a95
Give two opposing factions different offsets that players within the faction all share, but let everyone in the End see real coordinates:
defaultOffsetProvider: random
offsetProviderOverrides:
- provider: disabled # must come first, otherwise the faction providers would always apply to members.
world: world_the_end
- provider: constant_factionA
permission: coordinateoffset.provider.factionA # give this permission to Faction A
- provider: constant_factionB
permission: coordinateoffset.provider.factionB # give this permission to Faction B
offsetProviders:
disabled:
class: ConstantOffsetProvider
offsetX: 0
offsetZ: 0
constant_factionA:
class: ConstantOffsetProvider
offsetX: -30336
offsetZ: 14816
worldScaling:
world_nether: 0.125
constant_factionB:
class: ConstantOffsetProvider
offsetX: -89008
offsetZ: -36096
worldScaling:
world_nether: 0.125
One potential downside of obfuscating coordinates is that it can make multiworld scenarios difficult to navigate. For example, the Nether is commonly used for fast travel because one block of movement in the Nether will translate to eight blocks in the Overworld. Linking up Nether portals often involves coordinate conversions, by multiplying or dividing by 8.
World Alignment is an optional provider configuration for RandomOffsetProvider
and ZeroAtLocationOffsetProvider
. It allows you to specify a list of world pairs that use linked coordinate systems. The default on each of these providers will behave predictably with the Vanilla behavior of the Overworld and Nether:
worldAlignment:
- world:world_nether:8
With this config, any player who enters world_nether
while they already have an offset for world
will receive an offset that is 1/8th of their offset in world
. Likewise, any player who enters world
while they already have an offset for world_nether
will receive an offset that is 8 times larger than their offset in world_nether
. This means that players are fully able to use any coordinate translation techniques on the coordinates that they see, as if the offset were not configured at all.
resetOnWorldChange
setting, or world alignment will not work at all since the offsets do not persist across worlds.
If you have multiple sets of worlds, or worlds using different names than the defaults, you can add any number of pairs to this list:
worldAlignment:
- spawnworld:spawnworld_nether:8
- premiumworld:premiumworld_nether:8
If you have worlds that link coordinates 1:1 (meaning that there is no scaling), you can use a scale factor of 1:
worldAlignment:
- world:world_parallel:1
If you use Multiverse-NetherPortals scaling, you can match different scaling factors per world. Note that you need to list all possible pairs of worlds that someone might travel between:
worldAlignment:
- world:world_nether:8
- world_nether:world_supernether:8
- world:world_supernether:64
Config | Description |
---|---|
fixCollision |
If true, the blocks listed (bamboo and dripstone) will be patched to have no server-side collision. This fixes a movement glitch near these blocks described in #8. If false, the block will not be patched. It is strongly recommended to leave this enabled unless it causes problems, because disabling it makes moving through bamboo and dripstone extremely glitchy while an offset is applied. |
bypassByPermission |
If true, players with the coordinateoffset.bypass permission will bypass all providers and see their real coordinates. If false, all players are subject to the standard offset rules.It may be useful to disable this while testing the plugin, since server operators have this permission by default. However, for a live server, you should really enable this and give the permission to moderators or admins, so they will be able to see where they are and use commands that take coordinates. |
obfuscateWorldBorder |
If true, world border packets will be modified so that only nearby "border walls" can be determined. See here for more details. |
verbose |
Enables extra logging whenever the plugin generates an offset for a player. Use this to confirm which provider is being selected for a player, to debug overrides. |
allowUnsafeResetOnDistantTeleport |
This option allows the use of resetOnDistantTeleport as a provider option in Random and ZeroAtLocation providers - see here for why it is considered unsafe. |