Not sure if this helps but I recoded SafeTeleport for multiple amount of people teleporting to the same lobby while making a story game, in case you needs to sample my code for reserve teleport.
Module:
local TeleportService = game:GetService("TeleportService")
local ATTEMPT_LIMIT = 5
local RETRY_DELAY = 1
local FLOOD_DELAY = 15
local function SafeTeleport(placeId : number, players : {Player}, options : TeleportOptions)
if not game:GetService("RunService"):IsStudio() then
local attemptIndex = 0
local success, result -- define pcall results outside of loop so results can be reported later on
repeat
success, result = pcall(function()
return TeleportService:TeleportAsync(placeId, players, options) -- teleport the player in a protected call to prevent erroring
end)
attemptIndex += 1
if not success then
task.wait(RETRY_DELAY)
elseif success then
--What to do on success.
--[[for _, player in pairs(players) do
for _, tplayer in pairs(game.Players:GetPlayers()) do
if player:IsFriendsWith(tplayer.UserId) then
game.ReplicatedStorage.PrintEvent:FireClient(tplayer, nil, ("Your friend %s(@%s) is being teleported to %s."):format(player.DisplayName,player.Name,game:GetService("MarketplaceService"):GetProductInfo(placeId).Name))
end
end
end]]
end
until success or attemptIndex == ATTEMPT_LIMIT -- stop trying to teleport if call was successful, or if retry limit has been reached
if not success then
warn(result) -- print the failure reason to output
end
return success, result
end
warn("Is currently in studio cannot teleport.")
return false, "Is currently in studio cannot teleport."
end
local function handleFailedTeleport(player, teleportResult, errorMessage, targetPlaceId, teleportOptions)
if teleportResult == Enum.TeleportResult.Flooded or teleportResult == Enum.TeleportResult.Failure then
-- pause and retry if it's a one-time hiccup
task.wait(teleportResult == Enum.TeleportResult.Flooded and FLOOD_DELAY or teleportResult == Enum.TeleportResult.Failure and RETRY_DELAY or 2)
-- teleportOptions automatically have the reservedServerCode filled up
TeleportService:TeleportAsync(targetPlaceId, {player}, teleportOptions)
else
-- throw an error if something else is wrong
error(("Invalid teleport [%s]: %s"):format(teleportResult.Name, errorMessage))
end
end
TeleportService.TeleportInitFailed:Connect(handleFailedTeleport)
return SafeTeleport
Script:
local TeleportOption
local ReservedServerId = game:GetService("TeleportService"):ReserveServer(GameIds["Multiplayer"])
TeleportOption = Instance.new("TeleportOptions")
TeleportOption.ReservedServerAccessCode = ReservedServerId
TeleportOption:SetTeleportData({
VipReservedId = ReservedServerId,
VipOwner = player.UserId
})
SafeTeleport(GameIds["Multiplayer"], {player}, TeleportOption)
Edit: SafeTeleport(GameIds["Multiplayer"], {player}, TeleportOption)
How I manage TeleportData in a different startup script(Might not needs this):
local Player = Players:GetPlayers()[1] or Players.PlayerAdded:Wait()
local TeleportData = Player:GetJoinData().TeleportData or {}
if TeleportData["VipReservedId"] then
game:GetService("ServerStorage").VipServerData.ReservedId.Value = TeleportData["VipReservedId"]
game:GetService("ServerStorage").VipServerData.Owner.Value = TeleportData["VipOwner"]
if EnableFlags.AchievementConfig.AchievementDisableOnVipServer then
game.ServerScriptService.Services.EnableFlagBind.Change:Invoke("Achievement", false)
end
end