Soft Shutdown teleports me twice

Anyone know what’s causing this? I need a soft shutdown system so I made my own but it either doesn’t work or I get teleported twice and idk anything about TeleportService and soft shutdown stuff

local TeleportService = game:GetService("TeleportService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")


local joinData = nil
local isHoldingRoom = false

Players.PlayerAdded:Connect(function(player)
	local data = player:GetJoinData()
	if data and data.TeleportData == "HoldingRoom" then
		isHoldingRoom = true
	end
end)

task.wait(0.5)

if (game.PrivateServerId ~= "" and game.PrivateServerOwnerId == 0) then

	local teleported = {}

	local function returnToMainGame(player)

		local data = player:GetJoinData()
		if not (data and data.TeleportData == "HoldingRoom") then return end

		if teleported[player.UserId] then return end
		teleported[player.UserId] = true

		task.wait(10)
		TeleportService:TeleportAsync(game.PlaceId, {player})
	end

	Players.PlayerAdded:Connect(returnToMainGame)
	for _, p in ipairs(Players:GetPlayers()) do task.spawn(returnToMainGame, p) end

else

	game:BindToClose(function()
		if RunService:IsStudio() or #Players:GetPlayers() == 0 then return end

		for _, player in ipairs(Players:GetPlayers()) do
			local gui = script:FindFirstChild("ShutdownGui")
			if gui then
				local clone = gui:Clone()
				clone.Parent = player:WaitForChild("PlayerGui", 5)
			end
		end

		local teleportOptions = Instance.new("TeleportOptions")
		teleportOptions.ShouldReserveServer = true

		teleportOptions:SetTeleportData("HoldingRoom") 

		local success, result = pcall(function()
			return TeleportService:TeleportAsync(game.PlaceId, Players:GetPlayers(), teleportOptions)
		end)

		if success then
			task.wait(5)
		end
	end)
end
1 Like
  • Have you tried checking the console? Does it have any errors?
  • What do you mean teleported twice? Teleporting when another one is in progress results in a TeleportInitFailed error. Your code doesn’t seem like it calls TeleportAsync twice.

Besides that your code seems fine (in terms of the issue).

My gui becomes visible and I get teleported to the new update then like 10 seconds later I get teleported again

I don’t have any errors

  • btw you should check for the parameter Enum.CloseReason to see if you shutdown all of the servers (i’m assuming you shutdown all of the servers to update the game; correct me if im wrong)
  • i’m assuming the GUI is the indicator you are moving back to the main game?

To reiterate, you get teleported to the holding place once you initiate a shutdown and move all of the players to the holding place, then you wait a couple of seconds to go back to the new update?

Yes basically

The gui pops up when I press restart the server then I go to holding server then back to normal server then I get teleported again after 5-10 seconds

Idk if I’m doing this right though because the restart servers button confuses me I don’t fully understand how it works

With that out of the way I can reasonably assume the condition on line 18 is true.

Anyways, I decided to try your code in a new experience. I could NOT reproduce your issue.

I think your issue might be caused by the server sticking around so that you join back to the holding place and you get teleported again. To prevent this from being the case, use Roblox’s ReserveServerAsync and teleport using TeleportAsync with the ReservedServerAccessCode property of TeleportOptions set to the access code ReserveServerAsync gave you to ensure Roblox doesn’t select the server you were just in for you to join.

Code (but with print statements for debugging)
local TeleportService = game:GetService("TeleportService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")


local joinData = nil
local isHoldingRoom = false

Players.PlayerAdded:Connect(function(player)
	local data = player:GetJoinData()
	if data and data.TeleportData == "HoldingRoom" then
		isHoldingRoom = true
	end
end)

task.wait(0.5)

if (game.PrivateServerId ~= "" and game.PrivateServerOwnerId == 0) then
	print("Holding place.")

	local teleported = {}

	local function returnToMainGame(player)
		print(`Teleporting player {player.Name}...`)

		local data = player:GetJoinData()
		if not (data and data.TeleportData == "HoldingRoom") then return end

		if teleported[player.UserId] then return end
		teleported[player.UserId] = true

		task.wait(10)
		TeleportService:TeleportAsync(game.PlaceId, {player})
	end

	Players.PlayerAdded:Connect(returnToMainGame)
	for _, p in ipairs(Players:GetPlayers()) do task.spawn(returnToMainGame, p) end

else

	print("Not holding game! Waiting for shutdown...")
	game:BindToClose(function()
		if RunService:IsStudio() or #Players:GetPlayers() == 0 then return end
		print("Shutting down!")

		for _, player in ipairs(Players:GetPlayers()) do
			local gui = script:FindFirstChild("ShutdownGui")
			if gui then
				local clone = gui:Clone()
				clone.Parent = player:WaitForChild("PlayerGui", 5)
			end
		end

		local teleportOptions = Instance.new("TeleportOptions")
		teleportOptions.ShouldReserveServer = true

		teleportOptions:SetTeleportData("HoldingRoom") 

		local success, result = pcall(function()
			return TeleportService:TeleportAsync(game.PlaceId, Players:GetPlayers(), teleportOptions)
		end)

		if success then
			task.wait(5)
		end
	end)
end

Thanks I’ll try it out and look into it I’ll let you know what happens