A Bug in my Lobby System that I need help with

This is my studio if you want to get a better understanding:
MyMostRecentBigBrainProject.rbxl (47.5 KB)

  1. I am making a lobby system like the roblox game “flicker”. To summarize, there are two rooms. “roomOne” is the room players start at when they join the game. “roomTwo” is the room players go to, to launch into the game. In other words, “roomTwo” is the intermission room. These two tables have a metastable with a __newindex metamethod in it. It’s functionality is to change the player’s CFrame to the corresponding room they want to go to. It also checks if there is enough player in “roomTwo”, and if there is, then change a boolValue to true to let us know that there is enough player in it to start the intermission countdown.

  2. If a player switch between “roomOne” and “roomTwo” super fast, the countdown goes crazy and messes up. This happens because the “module.countDown” function fires multiple times when players leave and then join superfast, which messes up the count.

  3. I have tried thinking really hard to come up with a solution to fix this runtime error and I don’t really know a good way to do it.

ServerScript:

local replicatedStorage = game:GetService("ReplicatedStorage")
local goRemoteEvent = replicatedStorage.GoRemoteEvent
local leaveRemoteEvent = replicatedStorage.LeaveRemoteEvent
local roomOne = {["name"] = "roomOne",}
local roomTwo = {["name"] = "roomTwo",}
local state = replicatedStorage.BoolValue
local moduleScript = require(game.ServerStorage.ModuleScript)

local metatable = {__newindex = function (t, i, v)
	rawset(t,#t + 1, v)
	v.Character:SetPrimaryPartCFrame(workspace[t["name"] .. "TeleportionPort"].CFrame)
	if moduleScript.checkNumber(roomTwo) then
		state.Value = true
	else
		state.Value = false
	end
end}

setmetatable(roomOne, metatable)
setmetatable(roomTwo, metatable)

state:GetPropertyChangedSignal("Value"):Connect(function()
	if moduleScript.checkNumber(roomTwo) then
		print("hi0")
		moduleScript.countDown(7, roomTwo)
	end
end)

goRemoteEvent.OnServerEvent:Connect(function(player)
	for i, v in pairs(roomTwo) do
		if v == player then
			print("your already in roomTwo")
			return
		end
	end
	for i,v in pairs(roomOne) do
		if v == player then
			roomOne[i] = nil
			roomTwo[#roomTwo + 1] = player
		end
	end
end)

leaveRemoteEvent.OnServerEvent:Connect(function(player)
	for i, v in pairs(roomOne) do
		if v == player then
			print("your already in roomOne")
			return
		end
	end
	for i,v in pairs(roomTwo) do
		if v == player then
			roomTwo[i] = nil
			roomOne[#roomOne + 1] = player
		end
	end
end)

local function onCharacterAdded(character)
	local limb = character:WaitForChild("HumanoidRootPart")
	local player = game.Players:GetPlayerFromCharacter(character)
	limb:GetPropertyChangedSignal("CFrame"):Wait()

	roomOne[#roomOne + 1] = player
end

local function onPlayerAdded(player)
	player.CharacterAdded:Connect(onCharacterAdded)
end

game.Players.PlayerAdded:Connect(onPlayerAdded)

ModuleScript:

local module = {}

local stringValue = game.ReplicatedStorage.StringValue

function module.checkNumber(t)
	return #t >= 1 
end
	
function module.countDown(n, t)
	print("changed")
	if module.checkNumber(t) then
		if n == 0 then
			stringValue.Value = "Success" 
		else
			stringValue.Value = "Intermission in " .. n - 1
			wait(1)
			module.countDown(n - 1, t)
		end
	else
		stringValue.Value = "Not enough players"
		return
	end
end
2 Likes

I don’t see the point in using a recursive function for the countdown (???). Not sure why you couldn’t just use a generic “for loop”, because that would probably be much easier.

1 Like