Handling failed teleports for lobby system

So I have this teleport for a lobby system but I am unsure if I handled the teleports correctly as I have it setup for when players are in the server after they are teleported and also for if they leave the game that they are teleported to but don’t know if I have things correct for if a players teleport fails.

This is in the lobby that the players will be teleported from

local lobbyRE = replicatedStorage.Client.lobbyRE --RemoteEvent
local playersInLobby = {} --table that has the names of players that enter the lobby

function teleportLobby()
	local ID = 14025001954
	local reservedServer = teleportService:ReserveServer(ID)
	local teleportOptions = Instance.new("TeleportOptions")

	teleportOptions.ReservedServerAccessCode = reservedServer
	
	local success, result = pcall(teleportService.TeleportAsync, teleportService, ID, playersInLobby, teleportOptions)	
	if not success then
		lobbyRE:FireClient("teleportFail") --displays a failed teleport GUI
		warn("Teleport Failed")
		return
	end
	
	teleportOptions:SetTeleportData({
		["totalPlayersInLobby"] = #playersInLobby, --sends the amount of players to be teleported not taking into account players whos teleport failed
	})
	
	print("Teleporting players from lobby".. lobby.Name)
end

And this is in the server that players are teleported to

local userQueueConnectionType = replicatedStorage:WaitForChild("userQueueConnectionType") --RemoteEvent
local totalPlayers

local playersInGame = script.playersInGame --IntValue
playersInGame.Value = 0 

game.Players.PlayerRemoving:Connect(function(leftPlayer) -- this is what happens for if a player leaves the game after they are loaded in but i need this to also happen if the player fails to teleport
	userQueueConnectionType:FireAllClients(leftPlayer, "left")
	playersInGame -= 1
	if totalPlayers ~= "error" then
		totalPlayers -= 1
	end
end)

players.PlayerAdded:Connect(function(player)
	local joinData = player:GetJoinData()
	local lobbyData = joinData.TeleportData
	
	local success, result = pcall(function()
		totalPlayers = lobbyData.totalPlayersInLobby -- sets the value to the amount of players that were initially teleported still not taking into account failed teleports
	end)
	if not success then
		totalPlayers = "error" --for when in studio
	end
end)
4 Likes

The teleportLobby function in the lobby script seems to handle teleporting players to a different server. However, there are a couple of improvements you can make:

a. Properly handle failed teleports: You are already using a pcall to handle errors during teleportation, which is good. However, you should also handle the case where some players might successfully teleport while others might fail. In this case, you can use the result variable from pcall to check for the failed players and remove them from the playersInLobby table.

b. Setting TeleportData: You can directly set the totalPlayersInLobby in the TeleportOptions before teleporting, so you don’t need to retrieve it again in the server script. This ensures that even if some players fail to teleport, you have the correct count.

c. Use a more descriptive event name: Instead of “teleportFail,” consider using a more specific event name like “TeleportFailed” to make it clear what the event represents.

Here’s an example of updated teleportLobby function:

local lobbyRE = replicatedStorage.Client.lobbyRE -- RemoteEvent
local playersInLobby = {} -- table that has the names of players that enter the lobby

function teleportLobby()
	local ID = 14025001954
	local reservedServer = teleportService:ReserveServer(ID)
	local teleportOptions = Instance.new("TeleportOptions")
	teleportOptions.ReservedServerAccessCode = reservedServer
	teleportOptions:SetTeleportData({
		totalPlayersInLobby = #playersInLobby,
	})
	
	local success, result = pcall(teleportService.TeleportAsync, teleportService, ID, playersInLobby, teleportOptions)
	
	if not success then
		-- Handle failed teleports and remove failed players from playersInLobby table
		local errorMessage = result
		warn("Teleport Failed: " .. errorMessage)
		for i = #playersInLobby, 1, -1 do
			local player = playersInLobby[i]
			if player.Parent == nil then -- Check if player is still in the game
				table.remove(playersInLobby, i)
			end
		end
		lobbyRE:FireClient("TeleportFailed", errorMessage) -- Displays a failed teleport GUI
		return
	end
	
	print("Teleporting players from lobby " .. lobby.Name)
end

The server script for the destination game where players are teleported to looks fine. It handles the player removal when they leave the game correctly. However, you should also consider handling failed teleports for players who didn’t reach the server.

It seems you are using totalPlayers to store the count of players in the lobby. If a player successfully teleports, the count will be accurate. However, if there are failed teleports, you might need a fallback mechanism to ensure the count is updated even for failed players.

To handle failed teleports in the destination server, you can add a new RemoteEvent to notify the server when a player fails to teleport. Then, you can update the player count accordingly.

Here’s an example of updated destination server script:

local userQueueConnectionType = replicatedStorage:WaitForChild("userQueueConnectionType") -- RemoteEvent
local totalPlayers = 0

local playersInGame = script.playersInGame -- IntValue
playersInGame.Value = 0

game.Players.PlayerRemoving:Connect(function(leftPlayer)
	userQueueConnectionType:FireAllClients(leftPlayer, "left")
	playersInGame.Value -= 1
	if totalPlayers ~= "error" then
		totalPlayers -= 1
	end
end)

local teleportFailedRE = replicatedStorage.Server.teleportFailedRE -- Create a RemoteEvent to notify about failed teleports

teleportFailedRE.OnServerEvent:Connect(function(player, errorMessage)
	print("Player " .. player.Name .. " failed to teleport. Error: " .. errorMessage)
	playersInGame.Value -= 1
	if totalPlayers ~= "error" then
		totalPlayers -= 1
	end
end)

game.Players.PlayerAdded:Connect(function(player)
	local joinData = player:GetJoinData()
	local lobbyData = joinData.TeleportData
	
	local success, result = pcall(function()
		totalPlayers = lobbyData.totalPlayersInLobby
	end)
	if not success then
		totalPlayers = "error" -- For when in studio
	end
	
	playersInGame.Value += 1
end)

With these changes, your teleportation system should be more robust and handle failed teleports properly. Remember that this code assumes you’ve set up the teleportFailedRE RemoteEvent on the destination server, and you’ll need to fire it appropriately in the teleportLobby function if there are teleportation errors. That’s it, hope it helps you boy!

1 Like

Wow, this is perfect and exactly what I needed thank you!
I was wondering, about the teleportFailedRE RemoteEvent. When it’s fired how would I send that to the destination server? Since the teleportLobby() function is in a different server I’m guessing that MessagingService would be needed?

1 Like

You’re correct in assuming that the MessagingService could be used to send information about the failed teleport to the destination server. The MessagingService allows you to send messages between different servers in a Roblox game. Here’s an example of how you could modify your code to use the MessagingService:

Destination Server Script:

local teleportFailedRE = replicatedStorage.Server.teleportFailedRE -- Create a RemoteEvent to notify about failed teleports

teleportFailedRE.OnServerEvent:Connect(function(player, errorMessage)
    print("Player " .. player.Name .. " failed to teleport. Error: " .. errorMessage)
    playersInGame.Value -= 1
    if totalPlayers ~= "error" then
        totalPlayers -= 1
    end
end)

-- Add a function to handle incoming messages from MessagingService
local function OnMessageReceived(message)
    if message.type == "TeleportFailedMessage" then
        local player = message.player
        local errorMessage = message.errorMessage

        -- Process the failed teleport
        teleportFailedRE:FireAllClients(player, errorMessage)
    end
end

game.Players.PlayerAdded:Connect(function(player)
    local joinData = player:GetJoinData()
    local lobbyData = joinData.TeleportData

    local success, result = pcall(function()
        totalPlayers = lobbyData.totalPlayersInLobby
    end)
    if not success then
        totalPlayers = "error" -- For when in studio
    end

    playersInGame.Value += 1
end)

-- Connect the function to the MessagingService message event
game.MessagingService:SubscribeAsync("TeleportFailedChannel", OnMessageReceived)

Then update the teleportLobby() function in the original server script to use the MessagingService, here’s an example you could do:

local MessagingService = game:GetService("MessagingService")

function teleportLobby()
    local ID = 14025001954
    local reservedServer = teleportService:ReserveServer(ID)
    local teleportOptions = Instance.new("TeleportOptions")
    teleportOptions.ReservedServerAccessCode = reservedServer
    teleportOptions:SetTeleportData({
        totalPlayersInLobby = #playersInLobby,
    })

    local success, result = pcall(teleportService.TeleportAsync, teleportService, ID, playersInLobby, teleportOptions)

    if not success then
        -- Handle failed teleports and remove failed players from playersInLobby table
        local errorMessage = result
        warn("Teleport Failed: " .. errorMessage)
        for i = #playersInLobby, 1, -1 do
            local player = playersInLobby[i]
            if player.Parent == nil then -- Check if player is still in the game
                table.remove(playersInLobby, i)
            end
        end
        lobbyRE:FireClient("TeleportFailed", errorMessage) -- Displays a failed teleport GUI

        -- Use MessagingService to notify the destination server about the failed teleport
        local message = {
            type = "TeleportFailedMessage",
            player = player, -- The player who failed to teleport
            errorMessage = errorMessage
        }
        MessagingService:PublishAsync("TeleportFailedChannel", message)
        return
    end

    print("Teleporting players from lobby " .. lobby.Name)
end

With these modifications, I believe when a player fails to teleport in the teleportLobby() function, a message will be sent through the MessagingService to the destination server. The destination server’s script will receive the message and handle the failed teleport accordingly. I hope I helped you @Erikmb , good luck! :stuck_out_tongue_winking_eye:

1 Like

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