Players make empty ingame lobby full

As you can see in the video below, if the player simply moves into the lobby area everything is fine. But if they start moving quickly inside and out of the lobby zone then I’m assuming because this is a server script, the server can’t update fast enough and keep up with the client. What can I do about this?


I am using ZonePlus for where the player enters the lobby.

local players = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage")
local teleportService = game:GetService("TeleportService")
local serverScriptService = game:GetService("ServerScriptService")

local safeTeleport = require(serverScriptService.safeTeleport)

local lobbyRE = replicatedStorage.Client.lobbyRE

local lobby = script.Parent
local beams = lobby.Lights:GetChildren()
local backboard = lobby.QueueBoard.Backboard
local usernameDisplay = backboard.Players.Frame.Frame
local backboardTime = backboard.Players.Frame.BackboardTime
local backboardPlayers = backboardTime.BackboardPlayers

local zonePlus = require(game:GetService("ReplicatedStorage").Zone)
local container = lobby.QueueHitbox
local zone = zonePlus.new(container)

local userTemplate = nil
local playersInLobby = {}

local overheadStats = lobby.OverheadStats.Data.Main
local time = overheadStats.Time
local currentPlayerAmount = overheadStats.Players
local maxPlayerAmount = script.maxPlayerAmount
local timerOn = false
local playerCanJoin = true
local isLobbyFull = script.isLobbyFull

function reset()
	playersInLobby = {}
	playerCanJoin = true
	isLobbyFull.Value = false
	time.Text = "Waiting For Players"
	backboardTime.Text = "Waiting For Players"
	currentPlayerAmount.Text = #playersInLobby.. "/".. maxPlayerAmount.Value
	backboardPlayers.Text = #playersInLobby.. "/".. maxPlayerAmount.Value
end
reset()

function timer(player)
	timerOn = true

	for i = 3, 1, -1 do
		time.Text = "0:".. i
		backboardTime.Text = "0:".. i
		task.wait(1)

		if #playersInLobby < 1 then
			timerOn = false
			reset()
			return
		end
	end
	time.Text = "TELEPORTING"
	backboardTime.Text = "TELEPORTING"

	lobbyRE:FireClient(player, "teleport", #playersInLobby)
	playerCanJoin = false
	--teleport players here
	task.wait(10)

	for _, v in pairs(usernameDisplay:GetChildren()) do
		if v:IsA("ScrollingFrame") then
			if v.Name == player.Name then
				v:Destroy()
			end
		end
	end

	playerCanJoin = true
	timerOn = false
	reset()
end

zone.playerEntered:Connect(function(player)
	local isPlayerInLobby = table.find(playersInLobby, player)

	if player and not isPlayerInLobby and #playersInLobby < maxPlayerAmount.Value and playerCanJoin then
		table.insert(playersInLobby, player)

		userTemplate = replicatedStorage.Client.UserTemplate:Clone()
		userTemplate.Frame["User/Display"].Text = player.DisplayName.. "(@".. player.Name.. ")"
		userTemplate.Frame.PlayerIcon.Image = players:GetUserThumbnailAsync(player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
		if player:GetRankInGroup(32661332) >= 253 then
			userTemplate.Frame.Badges.Staff.Visible = true
		else
			userTemplate.Frame.Badges.Staff.Visible = false
		end
		userTemplate.Name = player.Name
		userTemplate.Parent = usernameDisplay

		if #playersInLobby >= 17 then
			backboard.Players.Frame.Frame.ScrollingEnabled = true
		elseif #playersInLobby == maxPlayerAmount.Value then
			isLobbyFull.Value = true
		end

		currentPlayerAmount.Text = #playersInLobby.. "/".. maxPlayerAmount.Value
		backboardPlayers.Text = #playersInLobby.. "/".. maxPlayerAmount.Value

		if not timerOn then
			timer(player)
		end
	end

	if isLobbyFull.Value == true then
		lobbyRE:FireClient(player, "lobbyFull")
	end
end)

zone.playerExited:Connect(function(player)
	local isPlayerInLobby = table.find(playersInLobby, player)

	if isPlayerInLobby then
		table.remove(playersInLobby, isPlayerInLobby)

		for _, v in pairs(usernameDisplay:GetChildren()) do
			if v:IsA("ScrollingFrame") then
				if v.Name == player.Name then
					v:Destroy()
				end
			end
		end

		if #playersInLobby < 17 then
			backboard.Players.Frame.Frame.ScrollingEnabled = false
		elseif #playersInLobby < maxPlayerAmount.Value then
			isLobbyFull.Value = false
		end

		currentPlayerAmount.Text = #playersInLobby.. "/".. maxPlayerAmount.Value
		backboardPlayers.Text = #playersInLobby.. "/".. maxPlayerAmount.Value
		if #playersInLobby < 1 then
			reset()
		end
	end
end)
2 Likes

You might want to add a delay so that people can’t spam in and out like that.

For example, if people go out and in in a short enough period, you could issue a message like “Slow Down!”.

I’m sure this wasn’t exactly what you wanted to here, but this is one of the ways I see it working. I’ll keep looking for other ways to do it without needing to add a cooldown, but it’s possible this might be the only method I find.

3 Likes

I guess you could also check to see if the player is still in the array, which means you wouldn’t have to add a delay. In case the server hasn’t caught up, it will still see the player was already in there.

One of the issues you could be facing is not enough time for the playerExited event to fully occur.

1 Like