Matchmaking script does not function properly

Hello,

I have made a matchmaking script for a game, however it seems to not be functioning correctly. Testers are reporting that lobbies are appearing duplicated, and player slots are randomly disconnecting and duplicating as well. I think I solved duplication, but players are randomly disconnecting from lobbies still. Here are the functions which I suspect are causing issues:

Client:

local function Refresh()
	for i, v in ipairs(Connections) do
		v:Disconnect()
	end

	for i, v in ipairs(script.Parent.Frame:GetChildren()) do
		if v:IsA("Frame") and v.Name ~= "Template" then
			v:Destroy()
		end
	end
	local Servers = Remotes.GetCurrentServers:InvokeServer() or {}

	for i, v in ipairs(Servers) do
		local Frame = script.Parent.Frame.Template:Clone()

		Frame.Visible = true
		Frame.Parent = script.Parent.Frame

		Frame.LobbyName.Text = v["LobbyName"]
		Frame.Name = v["LobbyName"]
		Frame.PlayerCount.TextLabel.Text = `{#v["Players"]}/{v["MaxPlayers"]}`

		Connections[v["LobbyName"].."JoinBtn"] = Frame.Join.MouseButton1Click:Connect(function()
			local MF = script.Parent.Parent.InLobby
			IsInLobby = true
			Remotes.JoinLobby:InvokeServer(v["LobbyID"])
			LobbyKey = v["LobbyID"]

			script.Parent.Visible = false
			script.Parent.Parent.InLobby.Visible = true
			script.Parent.Parent.Buttons.Visible = false
			task.wait(.1)
			script.Parent.Parent.InLobby.LobbyName.Text = v["LobbyName"]
			warn("Done!")
		end)

	end
end

Remotes.NewServer.OnClientEvent:Connect(Refresh)

Remotes.NewPlayer.OnClientEvent:Connect(function(LobbyID)
	if LobbyID == LobbyKey or LobbyID == "*" then
		for i, v in ipairs(script.Parent.Parent.InLobby.Players:GetChildren()) do
			if v:IsA("Frame") and v.Name ~= "Template" then
				v:Destroy()
			end
		end

		local Players = Remotes.GetPlayers:InvokeServer(LobbyKey) or {}
		print(Players)

		for i, Player: Player in ipairs(Players) do
			local PlayerFrame = script.Parent.Parent.InLobby.Players.Template:Clone()

			PlayerFrame.Name = Player.Name
			PlayerFrame.Visible = true
			PlayerFrame.Parent = script.Parent.Parent.InLobby.Players
			PlayerFrame.PlayerName.Text = Player.Name
			PlayerFrame.PFP.Image = game.Players:GetUserThumbnailAsync(Player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size180x180)

			--Connections[Player.Name.."_Kick"] = PlayerFrame.Kick.MouseButton1Click:Connect(function()
			--	Remotes.Kick:InvokeServer(LobbyKey, Player.Name)
			--end)

			PlayerFrame.Visible = true
			IsInLobby = true
		end
	end
end)

Refresh()

Server:

local Lobbies = {}

local function MakeNewLobby(OwnerPlayer, LobbyName, MaxPlayers)
	local LobbyID = game:GetService("HttpService"):GenerateGUID(true)
	table.insert(Lobbies, {
		["LobbyName"] = LobbyName or OwnerPlayer.Name.."'s Lobby",
		["LobbyOwner"] = OwnerPlayer,
		["MaxPlayers"] = MaxPlayers,
		["LobbyID"] = LobbyID,
		["Players"] = {}
	})
	
	game.ReplicatedStorage.MatchmakingRemotes.NewServer:FireAllClients()

	return {true, LobbyID}
end

local function RemoveDuplicates(Table)
	local seen = {}
	local result = {}

	for _, value in ipairs(Table) do
		if not seen[value] then
			table.insert(result, value)
			seen[value] = true
		end
	end

	return result
end


...

game.ReplicatedStorage.MatchmakingRemotes.JoinLobby.OnServerInvoke = function(Player, LobbyID)
	for i, v in ipairs(Lobbies) do
		if v["LobbyID"] == LobbyID then
			table.insert(v["Players"], Player)
			
			v["Players"] = RemoveDuplicates(v["Players"])
			
			game.ReplicatedStorage.MatchmakingRemotes.NewPlayer:FireAllClients(LobbyID)
			return {true, `Successfully joined {v["LobbyName"]}`}
		end
	end
end

...

game.ReplicatedStorage.MatchmakingRemotes.LeaveLobby.OnServerInvoke = function(RequestPlayer, LobbyID)
	for i, v in ipairs(Lobbies) do
		if v["LobbyID"] == LobbyID then
			for k, Player in ipairs(v["Players"]) do
				if Player.Name == RequestPlayer.Name then
					table.remove(v["Players"], i)
					game.ReplicatedStorage.MatchmakingRemotes.NewPlayer:FireAllClients(LobbyID)
				end
			end
			print(#v["Players"])
			if #v["Players"] == 0 then
				DeleteLobby(v["LobbyOwner"] or "force", LobbyID)
			end
		end
	end
end
3 Likes