Fabric Dimensions slight desync on teleportation on multiplayer
LordDeatHunter opened this issue ยท 4 comments
When teleporting a player with FabricDimensions#teleport
on multiplayer, there's a slight desync on the client side.
For the player, they initially "teleport" to spawn with no items, xp, buffs, etc (basically a "fresh" new player instance), and then get teleported to the specified location a second later with all the items/xp/etc. they originally had.
My guess is that the teleport code runs both on client and server side for some reason, and that on the client side, there's a new player instance with default, non-copied data, and after teleporting client-side, the server syncs the player with a proper teleportation packet.
Tested with the following versions:
Minecraft: 1.18.2
Fabric API: 0.53.0
Fabric Dimensions: 2.1.17
I made a PoC test mod for both this and #2238, but I figured making a whole repo for it would be overkill. Here's a single file containing all you need to replicate both issues.
package wraith.fabricdimpoc;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.fabric.api.dimension.v1.FabricDimensions;
import net.minecraft.entity.Entity;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.LiteralText;
import net.minecraft.world.TeleportTarget;
public class FDPEvents {
public static void initialize() {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) ->
dispatcher.register(CommandManager.literal("fdp")
.then(CommandManager.literal("2238")
.executes(context -> {
ServerPlayerEntity player = context.getSource().getPlayer();
if (player == null) {
context.getSource().sendFeedback(new LiteralText("You must be a player to execute this command."), false);
return 1;
}
Entity entity = player.world
.getOtherEntities(player, player.getBoundingBox().expand(100, 100, 100))
.stream()
.findFirst()
.orElse(null);
if (entity == null) {
context.getSource().sendFeedback(new LiteralText("No entities found."), false);
return 1;
}
TeleportTarget target = new TeleportTarget(entity.getPos(), entity.getVelocity(), entity.getYaw(), entity.getPitch());
FabricDimensions.teleport(entity, (ServerWorld) entity.world, target);
return 1;
}
)
)
.then(CommandManager.literal("2239")
.executes(context -> {
ServerPlayerEntity player = context.getSource().getPlayer();
if (player == null) {
context.getSource().sendFeedback(new LiteralText("You must be a player to execute this command."), false);
return 1;
}
if (!context.getSource().getServer().isDedicated()) {
context.getSource().sendFeedback(new LiteralText("This command can only be executed on dedicated servers."), false);
return 1;
}
TeleportTarget target = new TeleportTarget(player.getPos(), player.getVelocity(), player.getYaw(), player.getPitch());
FabricDimensions.teleport(player, (ServerWorld) player.world, target);
return 1;
}
)
)
)
);
}
}
Call FDPEvents.initialize()
on mod init, then /fdp 2239
for this issue and /fdp 2238
for the other.
(I think this issue doesn't happen 100% of the time. It might be dependent on the server's performance or distance from spawn, but so far I've been able to replicate it more than 90% of the time)