Why does my group teleport sometimes freeze up?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? I want my group teleporter (from the lobby into the gameplay) to not freeze up occasionally.

  2. What is the issue? I have a group teleporter that generally works fine, BUT every few hours I see the teleporter is broken in one of the servers. It is frozen on the TELEPORTING setting. Everybody in the chat is complaining about the long wait. The only way for me to fix is to manually reset the particular server.

  3. What solutions have you tried so far?
    I tried to write some safety checks to help if the teleport fails. It still fails occasionally.
    Here is some of my safety check code:
    if #playersToTeleport > 0 or not success then – if it fails again

Here is the whole script.

--<<SERVICES>>
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local TweenService = game:GetService ("TweenService")


--<<REMOTES>>
local OpenBedDoorBE = ReplicatedStorage.Remotes.OpenBedDoorBE
local CloseBedDoorBE = ReplicatedStorage.Remotes.CloseBedDoorBE


local leaveGuiEvent = ReplicatedStorage.Remotes.LeaveGuiEvent
local TransitionEvent = ReplicatedStorage.Remotes.TransitionEvent

local InTeleEvent = ReplicatedStorage.Remotes.InTeleEvent
local OutTeleEvent = ReplicatedStorage.Remotes.OutTeleEvent


local SpeedTime = 0


--------------------------------------------------------------------------------

local MaxPlayers = 12
local telecount = 1

local placeId = game.ReplicatedStorage.Values.StoryValue.Value

local timer
local TS = game:GetService("TeleportService")


local list = {}
local gui = script.Parent.GuiPart.SurfaceGui
local billboard = script.Parent.GuiPart.SurfaceGuiBack
local teleporting = false
local standby = true
local spawnTeleport = game.Workspace.LobbyBasics.enterRoomA
local countdownAEvent = game.ReplicatedStorage.Remotes.countdownAEvent

--<<SET UP>>
script.Parent.GuiPart.SurfaceGui.Frame.Status.Text = "WAIT"
script.Parent.GuiPart.SurfaceGui.Frame.Status.TextColor3 = Color3.fromRGB(255,172,51)



--<<FUNCTIONS>>
local function updateGui()
	gui.Frame.players.Text = #list
	billboard.Frame.players.Text = #list
end


local function removeFromList(character)
	for i=1,#list do
		if list[i] == character.Name then
			table.remove(list,i)
			updateGui()
		end
	end
end




local function LeavePlayer(player)
	if player.Character then

		player.Character.HumanoidRootPart.Anchored = false
		player.Character.Humanoid.Jump = true

		repeat wait() until player.Character.Humanoid.Sit == false


		player.Character:MoveTo((game.Workspace.LobbyBasics.leaveRoomA.Position))
		
		OutTeleEvent:FireClient(player) -- Remote that indicates you are Out!	

		removeFromList(player.Character)
	end
end


local function teleportPlayers()
	
	
	CloseBedDoorBE:Fire()

	if #list > 0 then
		script.Parent.GuiPart.SurfaceGui.Frame.Status.Text = "TELEPORTING"
		script.Parent.GuiPart.SurfaceGui.Frame.Status.TextColor3 = Color3.fromRGB(255,172,51)


		local playersToTeleport = {} -- stores players
		for i=1,#list do
			if game.Players:findFirstChild(list[i]) then
				table.insert(playersToTeleport,game.Players:findFirstChild(list[i]))
				TransitionEvent:FireClient(game.Players:findFirstChild(list[i]))
			else
				table.remove(list,i)	
			end
		end 
		
		local code;
		local success, err = pcall(function()
			code = TS:ReserveServer(placeId)
		end)
			
		teleporting = true
		local success, err = pcall(function()
			if not code then return end
			
			TS:TeleportToPrivateServer(placeId,code,playersToTeleport) 
		end)
		
		for i = 1, 15 do
			
			wait(1)
			
			if #playersToTeleport == 0 then
				break
			end
			
		end
		

		if #playersToTeleport > 0 or not success then -- if teleport fails
			--wait(5)
			local success, err = pcall(function()
				if not code then return end
				
				TS:TeleportToPrivateServer(placeId,code,playersToTeleport) -- try again
			end)
			wait(5)
			if #playersToTeleport > 0 or not success then -- if it fails again
				for i,Player in pairs(playersToTeleport) do
					if Player then
						LeavePlayer(Player) -- move the player out of the waiting zone
					end
				end
			end
		end	
	end

	teleporting = false
	standby = true
	

	script.Parent.GuiPart.SurfaceGui.Frame.Status.Text = "WAIT"
	script.Parent.GuiPart.SurfaceGui.Frame.Status.TextColor3 = Color3.fromRGB(155, 13, 10)
	
	wait(2)
	
end


script.Parent.Gate.Touched:Connect(function(hit)
	if hit.Parent:findFirstChild("Humanoid") then
		if teleporting == false and standby == false then
			local char = hit.Parent
			local player = game.Players:FindFirstChild(char.Name)
			local alreadyExists = false

			for i=1,#list do
				if list[i] == char.Name then
					alreadyExists = true
				end
			end

			if alreadyExists == false then
				if #list <= MaxPlayers then
					table.insert(list,char.Name)

					char.Humanoid.Jump = true

					wait()
					char.PrimaryPart.CFrame = spawnTeleport.CFrame -- old code to teleport in


					InTeleEvent:FireClient(player) -- Remote that indicates you are IN!

					updateGui()
					leaveGuiEvent:FireClient(player)
				end

				player.CharacterRemoving:connect(function(character)
					removeFromList(character)
				end)
			end

		end
	end
end)


leaveGuiEvent.OnServerEvent:Connect(LeavePlayer)

----------------------------------------

function countdown()
	wait(1)
	OpenBedDoorBE:Fire()
	
	teleporting = false
	
	gui.Frame.time.Text = "-" --start with no time
	billboard.Frame.time.Text = "-" --start with no time
	--start with no players?  what to put?
	
	script.Parent.GuiPart.SurfaceGui.Frame.Status.Text = "ENTER"
	script.Parent.GuiPart.SurfaceGui.Frame.Status.TextColor3 = Color3.fromRGB(37, 101, 40)

	standby = false
	
	repeat --wait until there is a player before starting countdown
		wait()
	until #list > 0	
	
	local function ResetTimer()
		if SpeedTime == true then -- was speedtime set before?
			timer = 16
		else timer = 31
		end
		
	end
	ResetTimer()
	SpeedTime = false --reset speedtime
	
	for i=1,timer do
		timer = timer - 1
		gui.Frame.time.Text = timer
		billboard.Frame.time.Text = timer
		wait(1)
		
		if #list >= MaxPlayers then -- if full, then start teleport
			SpeedTime = true -- give speedtime for next time
			break
		elseif #list == 0 then
			ResetTimer()
			gui.Frame.time.Text = "-" --no time
			billboard.Frame.time.Text = "-" --no time
			break
		end
		
	end
	
	
	CloseBedDoorBE:Fire()
	
	teleporting = true	
	
	script.Parent.GuiPart.SurfaceGui.Frame.Status.Text = "TELEPORTING"
	script.Parent.GuiPart.SurfaceGui.Frame.Status.TextColor3 = Color3.fromRGB(177, 159, 13)
	
	
	if #list > 0 then --make sure there is still at least 1 player to teleport
				
		teleportPlayers()
			
	end	
		
end

---------------------------------------------------------------------------------------------------

wait(5)

while wait() do
	countdown()
end

Run a thread that waits 20 seconds that stops when the teleport is finished, then restart the script if it does finish.

script:Clone().Parent = script.Parent
script:Destory()