You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
I want to create a start page with Play button to join the main While loop for buttle royale, etc.
I have created a simple battle royale template with an infinite while loop in which
players stay in the lobby for certain time then teleport to the main field automatically until the match end.
I don’t want to teleport the players unless they press Play button in the lobby,
which would be a typical system among professional games.
What is the issue? Include screenshots / videos if possible!
I don’t know what is the best way to achieve this.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I checked many YouTube videos but most of them just make the frame invisible on the main field and they don’t use the lobby system.
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
-- This is an example Lua code block
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.
I would suggest teleport them if their button is not visible, if the button is visible, that means they didn’t pressed the Play button. Or do in local script -
Hello, I tried your scripts, but the main while loop still start although I don’t press Play button.
I put the following code(game.Players.CharacterAutoLoads = false) outside and inside of the main while loop in Game Manager server script.
where should I put this line in the server script?
Or do I need to make a new server script for that?
By the way, my scripts for battle royale are basically just from Roblox website.
That is, there is Game Manger script in Server Script Service, while module scripts are in Server Storage.
Now I am customizing them.
Thank you for the info.
I am setting number of the minimum player for the main loop is 1.
And I changed the CharacteAutoLoads property for Players to false,
but the Starting screen is not shown even though BGM can be listened.
Thank u for ur cooperation.
Here is the script of Game Manager.
Now I moved the menu GUI and the local script to ReplicatedFirst.
-- Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local StarterGui = game:GetService("StarterGui")
local menuGui = game:GetService("ReplicatedFirst").MenuGui
--menuGui.Enalbed = true
--menuGui.MainFrame.Visible = true
-- Variables
-- Module Scripts
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
local EnemyManager = require(moduleScripts:WaitForChild("EnemyManager"))
-- Events
local events = ServerStorage:WaitForChild(("Events"))
local matchEnd = events:WaitForChild("MatchEnd")
local matchStart = events:WaitForChild("MatchStart")
--game.Players.CharacterAutoLoads = false
-- Main game loop
while menuGui.Enabled == false do
--displayManager.updateStatus("Waiting for Players")
repeat
--print("Starting intermission")
wait(gameSettings.intermissionDuration)
until Players.NumPlayers >= gameSettings.minimumPlayers
displayManager.updateStatus("Get ready!")
wait(gameSettings.transitionTime)
matchManager.prepareGame()
-- Placeholder wait for the length of the game.
wait(5)
print("MatchDuration")
EnemyManager.enemySpawn()
local endState = matchEnd.Event:Wait()
local endStatus = matchManager.getEndStatus(endState)
displayManager.updateStatus(endStatus)
matchManager.cleanupMatch()
wait(gameSettings.transitionTime)
matchManager.resetMatch()
end
And this is the local script for the menu GUI.
I can listen the music, but I cannot see the GUI.
local menuGui = script.Parent
local mainFrame = menuGui.MainFrame
local playButton = mainFrame.PlayButton
local SoundService = game:GetService("SoundService")
local natureWorld7 = SoundService:WaitForChild("NatureWorld7")
local clickSound = SoundService:WaitForChild("ClickSound")
if menuGui.Enabled == true then
natureWorld7:Play()
end
playButton.MouseButton1Click:Connect(function()
natureWorld7:Stop()
clickSound:Play()
game.Players.LocalPlayer:LoadCharacter()
menuGui.Enabled = false
end)
Now in my scripts, I don’t set the frame and the button to be shown by scripting
but I just set Visible for them on the properties.
Also, I set the menu GUI “Enabled” on the property.
This is MatchManager module script introduced on Roblox Education pages.
prepareGame() function is one of the functions defined here.
local MatchManager = {}
-- Services
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Module Scripts
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
--Events
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
--Values
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
--Create a new timer object to be used to keep track of match time.
local myTimer = timer.new()
local function stopTimer()
myTimer:stop()
end
--Local Functions
local function timeUp()
matchEnd:Fire(gameSettings.endStates.TimerUp)
end
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
while myTimer:isRunning() do
-- Adding +1 makes sure the timer ends at 1 instead of 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- By not setting the time for wait, it offers more accurate looping
wait()
end
end
-- Module Scripts
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
function MatchManager.getEndStatus(endState)
local statusToReturn
if endState == gameSettings.endStates.FoundWinner then
local winnerName = playerManager.getWinnerName()
statusToReturn = "Winner is: "..winnerName
elseif endState == gameSettings.endStates.TimerUp then
statusToReturn = "Time ran out!"
else
statusToReturn = "Error found"
end
return statusToReturn
end
function MatchManager.cleanupMatch()
playerManager.removeAllWeapons()
end
function MatchManager.resetMatch()
playerManager.resetPlayers()
end
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager
Sorry, forget about the last one.
This is PlayerManager module.
local PlayerManager = {}
-- Services
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modules
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Events
events = ServerStorage:WaitForChild("Events")
matchEnd = events:WaitForChild("MatchEnd")
-- Map Variables
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace:WaitForChild("Arena")
local spawnLocations = arenaMap.SpawnLocations
-- Values
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Player Variables
local activePlayers ={}
local playerWeapon = ServerStorage.Weapon
-- Local Functions
local function checkPlayerCount()
if #activePlayers == 1 then
matchEnd:Fire(gameSettings.endStates.FoundWinner)
end
end
local function removeActivePlayer(player)
for playerKey, whichPlayer in pairs(activePlayers) do
if whichPlayer == player then
table.remove(activePlayers, playerKey)
playersLeft.Value = #activePlayers
checkPlayerCount()
end
end
end
local function respawnPlayerInLobby(player)
player.RespawnLocation = lobbySpawn
player:LoadCharacter()
end
local function onPlayerJoin(player)
player.RespawnLocation = lobbySpawn
end
local function preparePlayer(player, whichSpawn)
player.RespawnLocation = whichSpawn
player:LoadCharacter()
local character = player.Character or player.Character:Wait()
local sword = playerWeapon:Clone()
sword.Parent = character
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
respawnPlayerInLobby(player)
removeActivePlayer(player)
end)
end
local function removePlayerWeapon(whichPlayer)
-- Check to see if a player exist in case the disconnected or left.
if whichPlayer then
local character = whichPlayer.Character
-- If the player has it currently on their character
if character:FindFirstChild("Weapon") then
character.Weapon:Destroy()
end
-- If the player has the weapon in their backpack
if whichPlayer.Backpack:FindFirstChild("Weapon") then
whichPlayer.Backpack.Weapon:Desttroy()
end
else
print("No player to remove weapon")
end
end
-- Module Functions
function PlayerManager.sendPlayersToMatch()
local arenaSpawns = spawnLocations:GetChildren()
for playerKey, whichPlayer in pairs(Players:GetPlayers()) do
table.insert(activePlayers, whichPlayer)
local spawnLocation = arenaSpawns[1]
preparePlayer(whichPlayer, spawnLocation)
table.remove(arenaSpawns, 1)
end
playersLeft.Value = #activePlayers
end
function PlayerManager.getWinnerName()
if activePlayers[1] then
local winningPlayer = activePlayers[1]
return winningPlayer.Name
else
return "Error: No winning player found"
end
end
function PlayerManager.removeAllWeapons()
for playerKey, whichPlayer in pairs(activePlayers) do
removePlayerWeapon(whichPlayer)
end
end
function PlayerManager.resetPlayers()
for PlayerKey, whichPlayer in pairs(activePlayers) do
respawnPlayerInLobby(whichPlayer)
end
activePlayers ={}
end
-- Events
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager
This is the start screen I want to display at the beginning of the game
and the right side is the folder structure.
(I temporally move the menuGUI to StarterGui from ReplicatedFirst).