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