ShardService is what replaces each of them.
atlas in your paper-plugin.yml so it loads first. Everything on the interface is safe from the main thread unless documented otherwise, and futures complete on the main thread.
The checklist
Never Player#teleport across a region
Use
transfer. A raw teleport is intercepted and rerouted, but the event is cancelled, so your code is told it failed.Never assume a player is here
Use
locate and summon for anyone who might be on another shard.Never write a block you do not own
Check
isOwned, or use askAt and the scheduler to have the owner do it.Always skip ghosts
isGhost before anything with a side effect. A ghost is a puppet of an entity living elsewhere.Where a player is
locate asks the shard that owns them, so the answer is live rather than as old as their last save. The stored record is up to a minute stale, which is the wrong answer for anyone walking. onlinePlayers() lists everyone in the mesh.
A
NetworkPlayer carries coordinates and a world name rather than a Location, because a location needs a world object and a shard only has its own.Moving a player
summon finds whoever holds them and has that shard do it.
Working on ground you do not own
askAt runs a registered query on whichever shard owns a location and gives you the answer. ShardScheduler.runAt is the same thing without a reply, for “make this happen over there”.
safeLanding is the one everybody needs: somewhere near a point that a player can stand without being hurt by it, resolved by the shard that owns the ground. It is allowed to fail, and a caller that teleports anyway is the bug it exists to prevent.