Made a lobby system from scratch and it works, althought alot of the code is pasted and it just doesnt look as good
so im wondering if theres anyway i can cut down on some of this code
-- Varibles
local Players = game:GetService("Players")
local HeldCharacters = game.ReplicatedStorage.HeldCharacters
local CreateLobbyEvent = game.ReplicatedStorage.Events.CreateLobby
local JoinLobbyEvent = game.ReplicatedStorage.Events.JoinLobby
local KickEvent = game.ReplicatedStorage.Events.LobbyKick
local ChangeCamEvent = game.ReplicatedStorage.Events.ChangeCam
local STCLobby = game.ReplicatedStorage.Events.ServerToClientLobby
local DisbandLobbyEvent = game.ReplicatedStorage.Events.DisbandLobby
local leaveLobbyEvent = game.ReplicatedStorage.Events.LeaveLobby
local GiveOwnershipEvent = game.ReplicatedStorage.Events.GiveHost
local StartGameFunction = game.ReplicatedStorage.Events.StartGame
local StarGameEvent = game.ReplicatedStorage.Events.LobbyStartGame
local LobbyMod = require(script.CreateLobby)
local Lobbys = {}
local PlayerThings = {}
-- Functions
local function CheckPlayer(Player)
repeat task.wait() until PlayerThings[Player]
local PlayerInfo = PlayerThings[Player]
while task.wait(.25) do
if not Player then break end
local Success, ErrorMessage = pcall(function()
if PlayerInfo["IsInRoom"] and PlayerInfo["RoomIn"] then
if not PlayerInfo["RoomIn"]:FindFirstChild("Players") or not PlayerInfo["RoomIn"]:FindFirstChild("Players"):FindFirstChild(Player.Name) then
PlayerInfo["IsInRoom"] = false
PlayerInfo['RoomIn'] = nil
PlayerInfo['CreatedRoom'] = nil
PlayerInfo["HasCreatedRoom"] = nil
STCLobby:FireClient(Player, "Leave")
end
end
end)
if not Success then
warn(ErrorMessage)
local S, Er = pcall(function()
PlayerInfo["IsInRoom"] = false
PlayerInfo['RoomIn'] = nil
PlayerInfo['CreatedRoom'] = nil
PlayerInfo["HasCreatedRoom"] = nil
STCLobby:FireClient(Player, "Leave")
end)
end
end
end
local function DisbandLobby(Room)
for i, v in ipairs(Room.Players:GetChildren()) do
v:Destroy()
end
Lobbys[Room] = nil
Room:Destroy()
end
local function CreateLobby(Player, RoomName, MaxPlayers, Map, IsLocked, Password)
if not PlayerThings[Player] then return end
local PlayerInfo = PlayerThings[Player]
if PlayerInfo["IsInRoom"] == true or PlayerInfo["HasCreatedRoom"] == true then return end
local LobbyTable = LobbyMod.New(Player, RoomName, MaxPlayers, Map, IsLocked, Password)
if not LobbyTable then return end
LobbyTable:StartLobby()
local Lobby = LobbyTable["Lobby"]
Lobbys[Lobby] = LobbyTable
local PlayerValue = Instance.new("StringValue")
PlayerValue.Name = Player.Name
PlayerValue.Parent = LobbyTable["PlayerFolder"]
PlayerInfo["IsInRoom"] = true; PlayerInfo["RoomIn"] = LobbyTable["Lobby"]
PlayerInfo["HasCreatedRoom"] = true; PlayerInfo["CreatedRoom"] = LobbyTable["Lobby"]
STCLobby:FireClient(Player, "Join", LobbyTable["Lobby"])
end
local function JoinLobby(Player, Room, Password)
if not PlayerThings[Player] then return end
-- Checking if player can join the room
local PlayerInfo = PlayerThings[Player]
if PlayerInfo["IsInRoom"] == true or PlayerInfo["HasCreatedRoom"] == true then return end
if not Lobbys[Room] then return end
local LobbyInfo = Lobbys[Room]
if table.find(LobbyInfo["BannedUsers"], Player) then return end
if LobbyInfo["IsLocked"] == true then if LobbyInfo["Password"] ~= Password then return end end
local MaxPlayers = LobbyInfo["MaxPlayers"]
MaxPlayers = tonumber(MaxPlayers)
if #LobbyInfo["PlayerFolder"]:GetChildren() >= MaxPlayers then return end
-- Joining the room
local PlayerValue = Instance.new("StringValue")
PlayerValue.Name = Player.Name
PlayerValue.Parent = LobbyInfo["PlayerFolder"]
PlayerInfo["IsInRoom"] = true; PlayerInfo["RoomIn"] = Room
STCLobby:FireClient(Player, "Join", Room)
end
local function ForceLeave(PlayerSent, Player, Type)
if PlayerSent == Player then return end
if not PlayerThings[PlayerSent] then return end
local _PInfo = PlayerThings[PlayerSent]
-- Checking If kick / ban is valid
if not PlayerThings[Player] then return end
local PlayerInfo = PlayerThings[Player]
if not PlayerInfo["IsInRoom"] == true or not PlayerInfo['RoomIn'] then return end
local Room = PlayerInfo["RoomIn"]
-- Big Check for player
if not _PInfo["HasCreatedRoom"] or not _PInfo["IsInRoom"] or not _PInfo["CreatedRoom"] then return end
if _PInfo['CreatedRoom'] ~= PlayerInfo["RoomIn"] then return end
-- Kicking Player
if Type == "Kick" then
Room:FindFirstChild("Players"):FindFirstChild(Player.Name):Destroy()
ChangeCamEvent:FireClient(Player, "Menu")
elseif Type == "Ban" then
Room:FindFirstChild("Players"):FindFirstChild(Player.Name):Destroy()
local LobbyInfo = Lobbys[PlayerInfo["RoomIn"]]
if not table.find(LobbyInfo["BannedUsers"], Player) then
table.insert(LobbyInfo["BannedUsers"], Player)
end
else
return
end
end
local function LeaveLobby(Player, Room)
if not PlayerThings[Player] then return end
local playerinfo = PlayerThings[Player]
if not playerinfo["IsInRoom"] and not playerinfo["RoomIn"] then return end
if not Lobbys[Room] then return end
Room.Players:FindFirstChild(Player.Name):Destroy()
if Player.Name == Room.LobbyOwner.Value and #Room.Players:GetChildren() > 0 then
local T = {}
for i, v in ipairs(Room.Players:GetChildren()) do
T[i] = v
end
if #T > 1 then
local RandomHost = T[math.random(1,#Room.Players:GetChildren())]
Room.LobbyOwner.Value = RandomHost.Name
local Playerd = Players[RandomHost.Name]
local __Pinfo = PlayerThings[Playerd]
__Pinfo["HasCreatedRoom"] = true; __Pinfo["CreatedRoom"] = Room
else
local Host = T[1]
Room.LobbyOwner.Value = Host.Name
local Playerd = Players[Host.Name]
local __Pinfo = PlayerThings[Playerd]
__Pinfo["HasCreatedRoom"] = true; __Pinfo["CreatedRoom"] = Room
end
end
if #Room.Players:GetChildren() == 0 then
DisbandLobby(Room)
end
end
local function EventDisband(Player, Room)
if not PlayerThings[Player] then return end
local _PInfo = PlayerThings[Player]
-- Reused code because im lazy
if not _PInfo["HasCreatedRoom"] or not _PInfo["IsInRoom"] or not _PInfo["CreatedRoom"] or not _PInfo["CreatedRoom"] == _PInfo["RoomIn"] then return end
if not _PInfo["CreatedRoom"] == Room and not _PInfo["RoomIn"] == Room then return end
if not Lobbys[Room] then return end
DisbandLobby(Room)
end
local function GiveHost(Player, PlayerToGiveTo, Room)
if Player == PlayerToGiveTo then return end
-- Giant Check, most of it is pasted because im not writing it out again
if not PlayerThings[Player] then return end
local _PInfo = PlayerThings[Player]
if not _PInfo["HasCreatedRoom"] or not _PInfo["IsInRoom"] or not _PInfo["CreatedRoom"] or not _PInfo["CreatedRoom"] == _PInfo["RoomIn"] then return end
if not _PInfo["CreatedRoom"] == Room and not _PInfo["RoomIn"] == Room then return end
if not Lobbys[Room] then return end
if not PlayerThings[PlayerToGiveTo] then return end
local PlayerInfo = PlayerThings[PlayerToGiveTo]
if not PlayerInfo["IsInRoom"] == true or not PlayerInfo['RoomIn'] then return end
local Room = PlayerInfo["RoomIn"]
if _PInfo['CreatedRoom'] ~= PlayerInfo["RoomIn"] then return end
Room.LobbyOwner.Value = PlayerToGiveTo.Name
PlayerInfo["HasCreatedRoom"] = true; PlayerInfo["CreatedRoom"] = Room
_PInfo["HasCreatedRoom"] = false; _PInfo["CreatedRoom"] = nil
return "Successful"
end
local function StartGame(Player, Room)
if not PlayerThings[Player] then return end
local _PInfo = PlayerThings[Player]
if not _PInfo["HasCreatedRoom"] or not _PInfo["IsInRoom"] or not _PInfo["CreatedRoom"] or not _PInfo["CreatedRoom"] == _PInfo["RoomIn"] then return end
if not _PInfo["CreatedRoom"] == Room or not _PInfo["RoomIn"] == Room then return end
if not Lobbys[Room] then return end
local DidItWork = StartGameFunction:Invoke(Room)
repeat task.wait() until DidItWork ~= nil
if not DidItWork then
local Retries = 2
local TimesTried = 0
while wait() do
TimesTried += 1
local Diditwork2 = StartGameFunction:Invoke(Room)
repeat task.wait() until DidItWork
if DidItWork then
break
end
if TimesTried >= Retries then
warn("Failed to start game")
-- Somewhere about firing client it failed
break
end
end
end
end
-- Event Functions
CreateLobbyEvent.OnServerEvent:Connect(CreateLobby)
JoinLobbyEvent.OnServerEvent:Connect(JoinLobby)
DisbandLobbyEvent.OnServerEvent:Connect(EventDisband)
leaveLobbyEvent.OnServerEvent:Connect(LeaveLobby)
KickEvent.OnServerEvent:Connect(ForceLeave)
GiveOwnershipEvent.OnServerEvent:Connect(GiveHost)
StarGameEvent.OnServerEvent:Connect(StartGame)
Players.PlayerAdded:Connect(function(Player)
PlayerThings[Player] = {
IsInRoom = false,
HasCreatedRoom = false,
}
local CheckCoroutine = coroutine.create(CheckPlayer)
coroutine.resume(CheckCoroutine, Player)
end)
Players.PlayerRemoving:Connect(function(Player)
if PlayerThings[Player] then
PlayerThings[Player] = nil
end
end)