Teleporting laggy players

Sometimes when the player lags really bad they will not get teleported

This is my script

local function retryTeleport(player, targetCFrame)
	if not player or not player.Character then return false end

	-- Wait for character and HumanoidRootPart to exist
	local rootPart = player.Character:FindFirstChild("HumanoidRootPart")
	while not rootPart do
		player.Character:WaitForChild("HumanoidRootPart", 5)
		rootPart = player.Character:FindFirstChild("HumanoidRootPart")
		if not rootPart then
			warn("Still waiting for HumanoidRootPart of", player.Name)
			task.wait()
		end
	end

	-- Retry teleport until success
	while player and rootPart do
		rootPart.CFrame = targetCFrame
		task.wait()

		local distance = (rootPart.Position - targetCFrame.Position).Magnitude
		if distance <= 5 then
			print(player.Name .. " teleported successfully.")
			return true
		end
	end

	return false
end

for i, player in ipairs(eligiblePlayers) do
		player.Team = game.Teams:FindFirstChild("Police")

		repeat task.wait() until player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		local character = player.Character
		local humanoid = character:FindFirstChildOfClass("Humanoid")

		if humanoid and humanoid.Health > 0 and RoundInProgress.Value == true then
			local rootPart = character:FindFirstChild("HumanoidRootPart")

			local spawnLocation = spawnPoints[math.random(1, #spawnPoints)]
			local randomYaw = math.rad(math.random(0, 360))
			local rotation = CFrame.Angles(0, randomYaw, 0)
			
			Police += 1

			local baseCFrame = GetRandomPointInPart(spawnLocation)
			rootPart.CFrame = baseCFrame * rotation
			
			CamResetEvt:FireClient(player)
			
			task.delay(0.5, function()
				local distance = (rootPart.Position - baseCFrame.Position).Magnitude
				if distance > 5 then
					warn(player.Name .. " might have failed to teleport! Retrying...")
					coroutine.wrap(retryTeleport)(player, rootPart, baseCFrame * rotation)
				end
			end)

			MorphPolice(player)

			local giveSpecial = table.find(specialIndices, i) ~= nil
			PoliceSpawnWeapons(player, giveSpecial)

			SetupPlayer(player)
			IntroEvt:FireClient(player)
		end
	end

I checked and it’s returning false positive

You can temporally remove network ownership of player’s RootPart
That could help idk

Didn’t help

local function Teleport(player, targetCFrame, maxAttempts, timeout)
	maxAttempts = 10
	timeout = 2

	if not player or not player.Character then return false end

	local rootPart = player.Character:FindFirstChild("HumanoidRootPart")
	while not rootPart do
		player.Character:WaitForChild("HumanoidRootPart", 5)
		rootPart = player.Character:FindFirstChild("HumanoidRootPart")
		if not rootPart then
			warn("Still waiting for HumanoidRootPart of", player.Name)
			task.wait()
		end
	end

	for attempt = 1, maxAttempts do
		pcall(function()
			rootPart:SetNetworkOwner(nil)
		end)

		player.Character:MoveTo(targetCFrame.Position)

		local success = false
		local startTime = tick()
		while tick() - startTime < timeout do
			local distance = (rootPart.Position - targetCFrame.Position).Magnitude
			if distance <= 5 then
				success = true
				break
			end
			task.wait(0.1)
		end

		pcall(function()
			rootPart:SetNetworkOwner(player)
		end)

		if success then
			print(player.Name .. " teleported successfully on attempt", attempt)
			return true
		else
			warn(player.Name .. " failed to teleport on attempt", attempt, "- Retrying...")
		end
	end

	warn(player.Name .. " failed to teleport after", maxAttempts, "attempts.")
	return false
end
1 Like

You don’t need to pcall it btw
It may error if part is anchored only as far as i know
Try using PivotTo :thinking:

I’ll report back after playtest with a large group of ppl

Try also firing a remote to tell the player to teleport right before you teleport them on the server.

Nope, didn’t work))))))))))))))

It seems to work? but im not sure. I’ll report back

Still didn’t work. I even make failsafe check and it returns false positive

Local script

TeleportEvt.OnClientEvent:Connect(function(targetCFrame)
	task.wait(0.1)
	
	local rootPart = Char:FindFirstChild("HumanoidRootPart") or Char:WaitForChild("HumanoidRootPart", 10)
	if not rootPart then return end

	local startTime = tick()

	while true do
		task.wait(0.1)
		local distance = (rootPart.Position - targetCFrame.Position).Magnitude

		if distance > 10 then
			TeleportEvt:FireServer(targetCFrame)
		else
			break
		end

		if tick() - startTime > 20 then
			TeleportEvt:FireServer("RESET")
			break
		end
	end
end)

Server script

TeleportEvt.OnServerEvent:Connect(function(plr, location)
	if location == "RESET" then
		warn(plr.Name .. " teleport timeout - reloading character")
		plr:LoadCharacter()
		return
	end

	local char = plr.Character
	if typeof(location) == "CFrame" and char then
		local hrp = getHRP(char)
		if hrp then
			char:PivotTo(location)
		end
	end
end)

Why teleport the character through a remote event? That’s what can be causing your high ping players not being able to teleport. Have the Character teleport on their own client side so there is no networking involved.

I thought doing it on server is the right and valid way???

Well, the client sends the server their position and everything. This is why you see exploiters flying and walkspeed e.t.c because the Client can only control their Character and the server just does a few checks and says Okay! and replicates it to the rest of the clients when its received. I personally always did client teleportation / walkspeed (Unless its a gamepass 2x Walkspeed?) on a local script because using a remote event is just a hassle + you use network usage, which you don’t want to be making pointless network requests / memory usage.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.