How to make a lobby in Roblox Studio
Round-based games, co-op horror and tower defense all start in a lobby: a safe place where players gather before the action. This guide builds one in Roblox Studio, with a queue, a countdown, map voting, and the two ways to start the game: rounds in the same place, or a teleport to another place.
Two kinds of lobby
| Rounds in one place | Teleport to a game place | |
|---|---|---|
| How it works | Round maps are loaded into the same server; everyone in the server plays | A group is sent to its own server of a second place |
| Good for | Murder mystery, minigames, deathrun, infection | Co-op horror runs, tower defense matches, dungeons |
| Testing | Works in Studio's Play mode | Teleports only work in the published game |
1. Build the lobby
- Make it bright and safe: no traps, clear paths, the spawn in the middle.
- Put the way into the game where everyone sees it: a big pad, an elevator, a portal.
- Keep the shop, leaderboards and daily rewards here, so the game part stays clean.
- Give players something to do while they wait: a small obby, a few things to click, a leaderboard to read.
The map maker can build a lobby or hub map from a description ("a spooky carnival lobby with a stage and leaderboards"); see lobby map ideas.
2. Rounds in the same place
Keep the round maps in ServerStorage (each a model with a Spawns folder), and run the loop
from a server Script. A StringValue named Status in ReplicatedStorage lets every player's UI
show what's happening:
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local status = game.ReplicatedStorage.Status
local MIN_PLAYERS, INTERMISSION, ROUND_TIME = 2, 20, 120
local function countdown(text, seconds)
for t = seconds, 1, -1 do
status.Value = text .. " " .. t
task.wait(1)
end
end
while true do
repeat
status.Value = "Waiting for players..."
task.wait(1)
until #Players:GetPlayers() >= MIN_PLAYERS
countdown("Intermission", INTERMISSION)
local map = ServerStorage.Maps:GetChildren()[math.random(#ServerStorage.Maps:GetChildren())]:Clone()
map.Parent = workspace
local spawns = map.Spawns:GetChildren()
for i, player in Players:GetPlayers() do
local character = player.Character
if character then
character:PivotTo(spawns[(i - 1) % #spawns + 1].CFrame + Vector3.new(0, 3, 0))
end
end
countdown("Round", ROUND_TIME) -- end early when your win rule is met
for _, player in Players:GetPlayers() do
player:LoadCharacter() -- back to the lobby spawn
end
map:Destroy()
end
Add your game's rules inside the round: roles, a win check that ends the countdown early, rewards at the end.
3. Map voting
Instead of a random map, offer three. During intermission, show three buttons; each click fires a RemoteEvent with the map's name. The server keeps one vote per player (a table keyed by player, so changing your vote replaces it), counts them when intermission ends, and loads the winner, breaking ties at random. Show the vote counts live so the lobby feels busy.
4. A queue pad and a teleport to a game place
For games where each group gets its own server, add a second place to your experience (Creator Hub, under your experience's Places, or Studio's Asset Manager), then a queue pad in the lobby:
local Players = game:GetService("Players")
local TeleportService = game:GetService("TeleportService")
local GAME_PLACE_ID = 0 -- the second place's ID
local MAX_GROUP = 4
local pad = workspace.QueuePad
local queue = {}
pad.Touched:Connect(function(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player and not table.find(queue, player) and #queue < MAX_GROUP then
table.insert(queue, player)
end
end)
Players.PlayerRemoving:Connect(function(player)
local i = table.find(queue, player)
if i then
table.remove(queue, i)
end
end)
while true do
task.wait(1)
if #queue > 0 then
for t = 10, 1, -1 do
pad:SetAttribute("Countdown", t) -- a BillboardGui above the pad shows this
task.wait(1)
end
local group = queue
queue = {}
local options = Instance.new("TeleportOptions")
options.ShouldReserveServer = true -- a private server for this group
pcall(function()
TeleportService:TeleportAsync(GAME_PLACE_ID, group, options)
end)
end
end
In a real game, also let players leave the queue (stepping off the pad, or a Leave button), and check the players are still in the server before teleporting. Teleports only work in the published game, so publish and test from the Roblox app. Roblox's teleport docs cover the details, including passing data along with the group.
5. Coming back to the lobby
When a run ends in the game place, teleport the group back to the lobby's place ID the same way, and show the results there. Save rewards before teleporting: a DataStore save on the game place, read again in the lobby.
Generate a round-based game with a lobby
The BloxMaps Game Maker builds games with the lobby included: round games such as murder mystery (intermission, a map vote, the countdown and the rounds), deathrun, zombie waves, battle royale, sky wars and arena shooters, and a lobby place plus a game place for co-op horror and room-by-room horror runs. Round-based games can have their own round maps: up to 4 on the Studio plan.
A murder mystery game with a lobby and different maps each round
Try this promptQuestions
Do I need two places for a lobby?
No. Round games often keep the lobby and the maps in one place and move players between them. A separate game place is useful when the game part is big or needs its own settings.
Why don't teleports work in Studio?
TeleportService only works in a published game. Test teleports by publishing and joining from the Roblox app.
How many round maps should I have?
Three or four is a good start: enough for variety and for a vote of three.
Is BloxMaps free?
Making and previewing is free: 3 previews a day on the Free plan. You pay only to export. You only pay to export the finished Roblox Studio file (.rbxl): $14.99 once per game, or included with the Studio plan. See pricing.