So i am creating a game called Number Quest Ultra which is a game about maths where you create lobbies/games to challenge people. I was testing today when i came across this weird series of problems which makes no sense

Creating a lobby, leaving it and creating another has some freaky behaviour.

The first creation of the lobby is perfectly normal, it creates the lobby, adds me to it and the UI only shows 1 player which is me

Leaving this lobby also works fine, returns to the select lobby screen and removes the lobby.

The second time round seems to have the funny behaviour, this time creating 2 of me on the players list when there should only be 1.

Leaving this does not close the lobby, but instead adds a player to it somehow.

Repeating this just leads to an increase in the player count

Server Side

local lobbies = {}
local lobbyid = 0
local mapmodule = require(game.ReplicatedStorage.MapModule)
local ds = game:GetService("DataStoreService"):GetDataStore("MapChoice")
local ts = game:GetService("TeleportService")

local lobbytemplate = {
	["GameType"] = "",
	["Owner"] = "",
	["Map"] = "",
	["LobbyID"] = 0,
	["Players"] = {}
}

local function ReturnPlayers(owner,players)
	local newplayers = players
	table.insert(newplayers,owner)
	return newplayers
end

game.ReplicatedStorage.CreateGame.OnServerEvent:Connect(function(player,gametype,map)
	if mapmodule.Maps[map]["Type"] == gametype then
		if player.Data.Maps:FindFirstChild(map) then
			lobbyid = lobbyid + 1
			local newlobby = lobbytemplate
			newlobby["Owner"] = player.Name
			newlobby["GameType"] = gametype
			newlobby["Map"] = map
			newlobby["LobbyID"] = lobbyid
			table.insert(lobbies,lobbyid,newlobby)
			game.ReplicatedStorage.UpdateGameList:FireAllClients(lobbies)
			game.ReplicatedStorage.UpdatePlayerList:FireClient(player,ReturnPlayers(newlobby["Owner"],newlobby["Players"]))
			game.ReplicatedStorage.NewLobbyID:FireClient(player,lobbyid)
		end
	end
end)

game.ReplicatedStorage.LeaveGame.OnServerEvent:Connect(function(player,lobbyid)
	for i,v in pairs(lobbies) do
		if v["LobbyID"] == lobbyid then
			if v["Owner"] == player.Name then
				for a,b in pairs(v["Players"]) do
					game.ReplicatedStorage.LobbyRemoval:FireClient(game.Players[b])
				end
				table.remove(lobbies,i)
				game.ReplicatedStorage.UpdateGameList:FireAllClients(lobbies)
			else
				for a,b in pairs(v["Players"]) do
					if b == player.Name then
						table.remove(v["Players"],a)
						for c,d in pairs(v["Players"]) do
							game.ReplicatedStorage.UpdatePlayerList:FireClient(game.Players[d],ReturnPlayers(v["Owner"],v["Players"]))
						end
						game.ReplicatedStorage.UpdateGameList:FireAllClients(lobbies)
					end
				end
			end
		end
	end
end)

game.ReplicatedStorage.JoinGame.OnServerEvent:Connect(function(player,lobbyid)
	for i,v in pairs(lobbies) do
		if v["LobbyID"] == lobbyid then
			local maxplayers = 0
			if v["GameType"] == "Normal" then
				maxplayers = 4
			else
				maxplayers = 16
			end
			if (#v["Players"]+1) < maxplayers then
				table.insert(v["Players"],player.Name)
				for c,d in pairs(v["Players"]) do
					game.ReplicatedStorage.UpdatePlayerList:FireClient(game.Players[d],ReturnPlayers(v["Owner"],v["Players"]))
				end
				game.ReplicatedStorage.UpdateGameList:FireAllClients(lobbies)
			end
		end
	end
end)

game.ReplicatedStorage.KickPlayer.OnServerEvent:Connect(function(player,lobbyid,kickplayer)
	for i,v in pairs(lobbies) do
		if v["LobbyID"] == lobbyid then
			if v["Owner"] == player.Name then
				for a,b in pairs(v["Players"]) do
					if b == kickplayer then
						table.remove(v["Players"],a)
						for c,d in pairs(v["Players"]) do
							game.ReplicatedStorage.UpdatePlayerList:FireClient(game.Players[d],ReturnPlayers(v["Owner"],v["Players"]))
						end
						game.ReplicatedStorage.UpdateGameList:FireAllClients(lobbies)
					end
				end
			end
		end
	end
end)

game.ReplicatedStorage.StartGame.OnServerEvent:Connect(function(player,lobbyid)
	for i,v in pairs(lobbies) do
		if v["LobbyID"] == lobbyid then
			if v["Owner"] == player.Name and #v["Players"] >= 1 then
				local players = {}
				table.insert(players,game.Players[v["Owner"]])
				for a,b in pairs(v["Players"]) do
					table.insert(players,game.Players[b])
					ds:SetAsync(game.Players[b].UserId,v["Map"])
				end
				local placeidtp
				if v["GameType"] == "Normal" then
					placeidtp = 5185622956
				else
					placeidtp = 5185623208
				end
				table.remove(lobbies,i)
				game.ReplicatedStorage.UpdateGameList:FireAllClients(lobbies)
				local serverid = ts:ReserveServer(placeidtp)
				ts:TeleportToPrivateServer(placeidtp,serverid,players)
			end
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	for i,v in pairs(lobbies) do
		if v["Owner"] == player.Name then
			for a,b in pairs(v["Players"]) do
				game.ReplicatedStorage.LobbyRemoval:FireClient(game.Players[b])
			end
			table.remove(lobbies,i)
			game.ReplicatedStorage.UpdateGameList:FireAllClients(lobbies)
		else
			for a,b in pairs(v["Players"]) do
				if b == player.Name then
					table.remove(v["Players"],a)
					for c,d in pairs(v["Players"]) do
						game.ReplicatedStorage.UpdatePlayerList:FireClient(game.Players[d],ReturnPlayers(v["Owner"],v["Players"]))
					end
					game.ReplicatedStorage.UpdateGameList:FireAllClients(lobbies)
				end
			end
		end
	end
end)

game.ReplicatedStorage.BuyMap.OnServerEvent:Connect(function(player,map)
	if player.Data.Coins.Value >= mapmodule.Maps[map]["Cost"] then
		if player.Data.Maps:FindFirstChild(map) == nil then
			player.Data.Coins.Value = player.Data.Coins.Value - mapmodule.Maps[map]["Cost"]
			local newmap = Instance.new("Folder",player.Data.Maps)
			newmap.Name = map
		end
	end
end)

local function RequestLobbies()
	return lobbies
end

game.ReplicatedStorage.RequestLobbies.OnServerInvoke = RequestLobbies



Client Side Lobby UI Manager

local function UpdateList(listdata)
	for i,v in pairs(script.Parent:GetChildren()) do
		if v.ClassName == "Frame" then
			local isavaiable = false
			for a,b in pairs(listdata) do
				if b["LobbyID"] == v.ID.Value then
					isavaiable = true
				end
			end
			if isavaiable == false then
				v:Destroy()
			else
				for a,b in pairs(listdata) do
					if b["LobbyID"] == v.ID.Value then
						if b["GameType"] == "Normal" then
							v.Players.Text =(#b["Players"]+1).."/4 Players"
						else
							v.Players.Text =(#b["Players"]+1).."/16 Players"
						end
					end
				end
			end
		end
	end
	for i,v in pairs(listdata) do
		local isfound = false
		for a,b in pairs(script.Parent:GetChildren()) do
			if b.ClassName == "Frame" then
				if b.ID.Value == v["LobbyID"] then
					isfound = true
				end
			end
		end
		if isfound == false then
			local clone = game.ReplicatedStorage.LobbyFrame:Clone()
			clone.ID.Value = v["LobbyID"]
			clone.Owner.Value = v["Owner"]
			clone.OwnerText.Text = v["Owner"].."'s Game"
			clone.Map.Text = v["Map"]
			clone.Mode.Text = v["GameType"]
			if v["GameType"] == "Normal" then
				clone.Players.Text = (#v["Players"]+1).."/4 Players"
			else
				clone.Players.Text = (#v["Players"]+1).."/16 Players"
			end
			clone.Parent = script.Parent
		end
	end
end

UpdateList(game.ReplicatedStorage.RequestLobbies:InvokeServer())

game.ReplicatedStorage.UpdateGameList.OnClientEvent:Connect(function(lobbies)
	UpdateList(lobbies)
end)

Client Side Player List Manager

local function UpdateList(playerlist)
	for i,v in pairs(script.Parent:GetChildren()) do
		if v.Name == "PlayerFrame" then
			v:Destroy()
		end
	end
	for i,v in pairs(playerlist) do
		local clone = game.ReplicatedStorage.PlayerFrame:Clone()
		clone.PlayerName.Text = v
		clone.Parent = script.Parent
	end
end

game.ReplicatedStorage.UpdatePlayerList.OnClientEvent:Connect(function(playerlist)
	UpdateList(playerlist)
end)

I am truly confused and just can't understand why this happens

1 comment

0

I assume one of your if statements is returning false, perhaps use some print and warn statements to detect if that is the case