Better method of shutting down extra servers

I’m trying to make it so there are only a set amount of servers open for my game at a time, let’s say the maximum is 3. This means if there are already 3 servers running and a 4th one gets opened then the 4th one will get shut down automatically and force new players to join the existing 3 servers. I’ve done some experimenting and my code pretty much works, only problem is if a new player joins said 4th server and gets kicked and they don’t close the Roblox client immediately it will also shut down ALL the other running servers.

Here’s the full script in ServerScriptService:

local DataStoreService = game:GetService("DataStoreService");
local DataStore = DataStoreService:GetDataStore("ActiveServers");
local serverLimit = 3;
local activeServers = 0;
local accountedForSelf = false;
local kickMesssage;

local function loadData()
	local data;
	local success, err = pcall(function()
		data = DataStore:GetAsync("Servers");
	end)

	if success then
		if not accountedForSelf then
			accountedForSelf = true;
			activeServers = data + 1; --Include this server in the total count
		else
			activeServers = data;
		end
	else
		activeServers = 1;
	end
end

local function saveData()
	local success, err = pcall(function()
		DataStore:SetAsync("Servers", activeServers);
	end)
	
	if not success then
		wait(5);
		saveData();
	end
end

local function shutdownServer()
	activeServers = activeServers - 1;
	saveData();
	
	game.Players.PlayerAdded:Connect(function(newPlayer)
		newPlayer:Kick(kickMessage);
	end)
	for each, player in pairs(game.Players:GetPlayers()) do
		player:Kick(kickMessage);
	end
end

local checkServerIntegrity = coroutine.wrap(function()
	while wait(30) do
		loadData();
		saveData();
		
		if activeServers > serverLimit then
			shutdownServer();
		end
	end	
end)

local function initialize()
	if serverLimit == 1 then
		kickMessage = "There can only be 1 public server active at a time! Please join a current server.";
	else
		kickMessage = "There can only be "..serverLimit.." public servers active at a time! Please join a current server.";
	end
	
	if game.PrivateServerOwnerId == 0 then --We don't care about extra private servers
		checkServerIntegrity();
	end
end
initialize();

Any help is appreciated. I’m aware that limiting servers is unorthodox but it is necessary for my game.

A couple things to start off, this would be a LOT easier if you used MessagingService to communicate between servers. A datastore is impractical and unnecessary here. Im sure you have heard this before, but you don’t need ; at the end of each line in lua. Your data declaration using pcall can be simplified into one line like so:
local success,results = pcall(DataStore.GetAsync,DataStore,“Servers”)
This works becuase pcall accpets one function first, and then the rest of the parameters will be passed to the function. Since we are calling a : function with a . here, we need to manually pass the “DataStore” object so that it will be defined as “self” as per OOP rules. Insted of having all of these global variables such as kickMessage, activeServers,serverLimit, just pass them through the functions as needed. Another problem, could lie within servers opening very quickly. Basically, the load data function will be running asynchronously in numerous servers resulting in the activeServers number becoming inaccurate.

In terms of your actual issue, youre checking server integrity on all servers, and once the active is greater then the server limit, you shutdown the server (this code runs in all servers, so now that it has read the number has gone over once, every server will shut down). To fix this, after shutting the server down, subtract that server from your datastore server count preventing other servers to continue to shut down.

Never heard of MessagingService, will read the documentation on it.