Does anyone know a good tutorial on how to make a GUI lobby? Basically I wanna create a 2D player lobby list where players can make teams and join in other public teams but I can’t seem to find anything that could help me making one.
I’m currently making one myself, what you need to do is use remote events. When creating a lobby, I fire the server from the client, and fire all clients from the server to make a lobby appear to all players. Similar story with joining and leaving a party, using remote events. These are some of the scripts I made and am currently using. It’s still a little buggy and un-refined.
CLIENT SIDE SCRIPT THAT RUNS WHEN THE CREATE PARTY BUTTON IS CLICKED.
local debounce = true -- This is a debounce so you cannot create more than one lobby.
script.Parent.MouseButton1Up:Connect(function(player)
if debounce == true then
debounce = false
script.Parent.Parent.Join.Visible = true -- This is the host's client's frame that shows the players in the lobby.
local username = game.Players.LocalPlayer.Name -- This is the name of whoever created the lobby
game.ReplicatedStorage.CreateParty:FireServer(player, username) -- Transfers the name of the party creator to server side.
script.Parent.Parent.List:TweenPosition(UDim2.new(-1.234, 0, 0.499, 0),Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 0.6) -- This tween makes my lobby list go off screen so you cant join your own lobby.
end
end)
SERVER SIDE SCRIPT THAT RUNS WHEN CLIENT FIRES SERVER
game.ReplicatedStorage.CreateParty.OnServerEvent:Connect(function(players, username) -- "username" is the name of the person who created the party.
game.ReplicatedStorage.CreateParty:FireAllClients(players, username)
end)
CLIENT SIDE SCRIPT THAT RUNS WHEN ALL CLIENTS ARE FIRED FROM THE SERVER SCRIPT
game.ReplicatedStorage.CreateParty.OnClientEvent:Connect(function(username)
print(">> Success.") -- Just here to check whether the remote event was successfully fired
local hh = tostring(username) -- This is the name of the party creator we got when firing the server, and then firing all clients.
print(">>", hh, "created a party!") -- Not required.
local cloned = script.Parent.Player:Clone() -- This created a small frame inside of another frame I have, which is a list of all parties that have been created.
cloned.Name = tostring(username) -- This is important, to name the frame, due to a button that
deletes the party.
-- Remember to use "tostring" as when transferring the data, it turns the username into a 3 digit number that cannot be used.
cloned.Parent = script.Parent
cloned.TextLabel.Text = tostring(username)
cloned.Visible = true
end)
CLIENT SIDE SCRIPT TO DELETE THE PARTY
script.Parent.Parent.Delete.MouseButton1Up:Connect(function(player)
script.Parent.Parent.Join.Visible = false
debounce = true
local username = game.Players.LocalPlayer.Name -- This is the name of whoever is deleting the party.
game.ReplicatedStorage.DeleteParty:FireServer(player, username) -- Same story as creating the party, you need to transfer the username of the deleter so you can delete the party for all clients.
script.Parent.Parent.List:TweenPosition(UDim2.new(-0.234, 0, 0.499, 0), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 0.6) -- This tween brings back my party list frame. You can use the visible boolean if you want, but that doesnt looks as nice all the time.
wait(0.7)
script.Parent.Parent.Join.Visible = false -- This makes the host's lobby frame disappear, as the party no longer exists.
end)
SERVER SIDE SCRIPT TO DELETE THE PARTY
This works the same as creating the party, but it reverses the process.
game.ReplicatedStorage.DeleteParty.OnServerEvent:Connect(function(players, username)-- "username" is the name of the person who created and is now deleting the party.
game.ReplicatedStorage.DeleteParty:FireAllClients(players, username)
end)
CLIENT SIDE SCRIPT THAT RUNS WHEN ALL CLIENTS ARE FIRED FROM THE SERVER SCRIPT
game.ReplicatedStorage.DeleteParty.OnClientEvent:Connect(function(username)
print(">> Success")
print(">>", username, "deleted a party... :(")
if script.Parent:FindFirstChild(tostring(username)) then -- Checks whether a frame with the name of the party creator actually exists.
script.Parent:FindFirstChild(tostring(username)):Destroy() -- Deletes it.
end
end)
Now, in order for a player to join a party.
script.Parent.MouseButton1Up:Connect(function()
if script.Parent.Parent.count.Text == "1/2" then -- This checks if the party is full. When a player joins a party, the text will change to "2/2", which renders this button virtually useless.
local tapped = script.Parent.Parent.Name -- This is the party host's name, which we set when creating the party.
local localplr = game.Players.LocalPlayer.Name
game.ReplicatedStorage.JoinParty:FireServer(tapped, localplr) -- This will fire the server, so we can make it appear that a player has joined the party for both client and host.
script.Parent.Parent.Parent.Parent.Parent.Join.Join.Visible = false -- In the frame "Join" (Basically the local party frame), there is a button that allows you to join the game. This disables that button so that only the host can initiate the joining of the game.
script.Parent.Parent.Parent.Parent.Parent.Join.Visible = true
script.Parent.Parent.Parent.Parent.Parent.CreateParty.Visible = false -- This makes the create button invisible, so the player who is in the party cannot create a separate party. This will just make no sense. Similar thing going on with the next line.
script.Parent.Parent.Parent.Parent.Parent.Delete.Visible = false
else
print("Party is full. Try again later.")
end
end)
And the server side script:
game.ReplicatedStorage.JoinParty.OnServerEvent:Connect(function(tapped, localplr)
local s = pcall(function()
print(localplr)
game.Players[tostring(tapped)].PlayerGui.ScreenGui.Main.Join.Table.Player2.user.Text = tostring(localplr) -- This is a text box which displays the username of the local player for the party host.
game.Players[tostring(tapped)].PlayerGui.ScreenGui.Main.Join.PlayerCount.Text = "2/2" -- This is a player counter inside of the local party frame.
game.Players[tostring(localplr)].PlayerGui.ScreenGui.Main.Join.PlayerCount.Text = "2/2"-- This is a player counter inside of the local party frame.
game.Players[tostring(localplr)].PlayerGui.ScreenGui.Main.Join.Table.Player2.user.Text = tostring(tapped) -- This is a text box which displays the username of the party host for the local player.
game.Players[tostring(localplr)].PlayerGui.ScreenGui.Main.Join.Visible = true
game.ReplicatedStorage.JoinParty:FireAllClients(tapped) -- This fires a script that makes the frame that is in the party list have a textbox that displays 2/2, aka indicating that the party is full.
end)
end)
Now leaving the party.
This is the same for joining the party, but it just reverses everything.
Client side:
script.Parent.Parent.Parent.Parent.Parent.Join.Leave.MouseButton1Up:Connect(function()
local tapped = script.Parent.Parent.Name
local localplr = game.Players.LocalPlayer.Name
print(tapped, localplr)
game.ReplicatedStorage.LeaveParty:FireServer(tapped, localplr)
script.Parent.Parent.Parent.Parent.Parent.Join.Join.Visible = true
script.Parent.Parent.Parent.Parent.Parent.Join.Visible = true
script.Parent.Parent.Parent.Parent.Parent.CreateParty.Visible = true
script.Parent.Parent.Parent.Parent.Parent.Delete.Visible = true
end)
Server side:
game.ReplicatedStorage.LeaveParty.OnServerEvent:Connect(function(tapped, localplr)
local s = pcall(function()
game.Players[tostring(tapped)].PlayerGui.ScreenGui.Main.Join.Table.Player2.user.Text = "Empty"
game.Players[tostring(localplr)].PlayerGui.ScreenGui.Main.Join.Table.Player2.user.Text = "Empty"
game.Players[tostring(tapped)].PlayerGui.ScreenGui.Main.Join.PlayerCount.Text = "1/2"
game.Players[tostring(localplr)].PlayerGui.ScreenGui.Main.Join.PlayerCount.Text = "1/2"
game.Players[tostring(localplr)].PlayerGui.ScreenGui.Main.Join.Visible = false
game.ReplicatedStorage.LeaveParty:FireAllClients(tapped) -- This fires a script that makes the frame that is in the party list have a textbox that displays 1/2
end)
Whilst I’m at it, I’ll throw in the join game button for the party
This requires two scripts in one button, and a remote event.
Local script:
script.Parent.MouseButton1Down:Connect(function(player)
local player1 = script.Parent.Parent.Parent.Parent.Parent.Parent.Name
local player2 = script.Parent.Parent.Table.Player2.user.Text
print(player1)
print(player2)
script.Parent.RemoteEvent:FireServer(player1, player2)
end)
Server script:
local ts = game:GetService("TeleportService")
local placeid = _game_id_
local plr1
local plr2
script.Parent.RemoteEvent.OnServerEvent:Connect(function(player, player1, player2)
plr1 = tostring(player1)
plr2 = tostring(player2)
end)
local reservedserver
local s, e = pcall(function()
reservedserver = ts:ReserveServer(placeid)
end)
script.Parent.MouseButton1Up:Connect(function()
local users
users = {
game.Players[plr1],
game.Players[plr2]
}
ts:TeleportToPrivateServer(placeid, reservedserver, users)
end)
The remote events^^^
It’s taken me a while to write this, so I hope it actually helps a bit. I’ve only been working on this for the best part of a week, so it’s not the best. If you’d like, I can release a model.
Jesus this looks complicated but big thanks to you! Now I know what kind of scripting I need to make a lobby. Thanks again.
Just a quick request. Could you please send me your explorer tab with all the scripts, remote events in their places and names?
Ill make a model of the current menu I have but I think there is some bug. I looked it up and it might be to do with roblox testing a new dev console, but I’m not sure. I’ll DM you.
there is a lot of things that go into making a lobby system
first you will need to secure it from exploiters by doing a lot of checks.
- use remote functions a lot to be able to send back to the client a response
- check if they already have a party and if they do ignore it
- make sure they can only delete their party and not others
- have a secure way of joining public and private server (public by an id, private by an invite code only given when invited [this will make it impossible for an exploiter to spoof a remote and steal an invite code])
- make sure people cant join multiple parties (seen this a lot, where exploiters would spam join all parties)
- add a kick system so just in case someone you dont want in there is there you can kick them. make sure when kicked they cant rejoin
- handle all the parties on the server and request (requesting by remote functions) creation, deletion, joining, leaving, etc on the client
again a lot of stuff goes into this
it took me 4 days to get a functional and secure system