Soft Shutdowns

Restart Servers for an update without losing players!

by Aaronp7superstar

Author Avatar

image|100x100, 160%

#| Tutorial | Soft Shutdown | Intermediate |

Separator|100x100, 160%

LEARNING TARGET: I can create a soft shutdown system so I wont loose any players when I update my game.

#What is a Soft Shutdown?

The purpose of a Soft Shutdown is to be able to Restart all the servers in your game without losing a bunch of players. When you shutdown all your servers. All the players with be teleported in to a temporary server. After they are in the temporary server, they will then be teleported back to the updated game.

Separator|100x100, 160%

#User Interface

Let's start by create a basic ScreenGui with a single TextLabel inside of it. Set the ScreenGui's DisplayOrder value to 10 and it's IgnoreGuiInset value to true. Add a TextLabel inside of the ScreenGui and set it's size to {1,0},{1,0}. Now let's rename the ScreenGui to "Message".

Separator|100x100, 160%

#Server Script

#####Variables

Create a new Script in ServerScriptService. Put the "Message" ScreenGui inside of this Script. Now we can begin to code our SoftShutdown script. First we need to create our variables. Create a variable for TeleportService so we can teleport the plays to the temporary server when we shutdown our game. Create a variable for Players next so we can get the players in the server. Next, create a variable for RunService so we can detect if the server is in Roblox Studio. Now, create a variable for the "Message" ScreenGui we put in our script.

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

local MessageToClone = script:FindFirstChild("Message")

#####Interface Function

Now we can begin creating our function for making our User Interface appear on the Player's screens when we shutdown our game's servers. Create a new function called newMessage. Then give it the parameters for our player and our message. Create a variable for our cloned UI. Set the Cloned UI's parent to the Player's PlayerGui, and set the TextLabel's text to the message.

local function newMessage(player, message)
	local tempMessage = MessageToClone:Clone()
	tempMessage.Parent = player:WaitForChild("PlayerGui")
	tempMessage:FindFirstChild("TextLabel").Text = message
end

#####SoftShutdown Function

Create a new IF statement to see if the game has a private server id and to see if the Owner of the private server is nobody. In this if statement put a wait time variable. Add a PlayerAdded function. Make it set the message to the player that joined and make it wait the wait time we selected. Divide our wait time by 2 to speed it up for new players who joined the temporary lobby late. Next teleport the player to a updated Public server. Repeat the same exact thing in a for loop to affect the players that joined before the script was loaded.

Add an elseif statement to our IF statement to check if the game is not a studio session. Bind a function to the close event for the game. Create a new reservedServerCode in a new variable. Create a for loop to display a message and Teleport all the players in game to a reserved temporary Server. Repeat the same thing in a PlayerAdded function for players who joined late during the shutdown.

After all the IF statement and our elseif Statment create a while loop to keep the script running until the amount of players in the server is equal to 0. Add a wait in this while loop.

if game.PrivateServerId ~= "" and game.PrivateServerOwnerId == 0 then
	local waitTime = 8

	Players.PlayerAdded:Connect(function(player)
		newMessage(player, "This is a temporary lobby!","You will teleport back to main server in a bit.")

		wait(waitTime)
		waitTime = waitTime / 2
		TeleportService:Teleport(game.PlaceId, player)
	end)

	for i, player in pairs(Players:GetPlayers()) do
		newMessage(player, "This is a temporary lobby!","You will teleport back to main server in a bit.")

		TeleportService:Teleport(game.PlaceId, player)
		wait(waitTime)
		waitTime = waitTime / 2
	end

elseif RunService:IsStudio() == false then
	game:BindToClose(function()
		spawn(function()
			local reservedServerCode = TeleportService:ReserveServer(game.PlaceId)
			for _, player in pairs(Players:GetPlayers()) do
				newMessage(player, "Servers are Restarting!","Please do not leave the game until servers have restarted.")

				TeleportService:TeleportToPrivateServer(game.PlaceId, reservedServerCode, {player})
			end
			Players.PlayerAdded:Connect(function(player)
				newMessage(player, "Servers are Restarting!","Please do not leave the game until servers have restarted.")

				TeleportService:TeleportToPrivateServer(game.PlaceId, reservedServerCode, {player})
			end)
		end)
		while #Players:GetPlayers() > 0 do
			wait(1)
		end
	end)    
end

Separator|100x100, 160%

image|100x100, 160%

image|100x100, 160%


image|100x100, 160%

View in-game to comment, award, and more!