How can I create a start page with Play button to join the main While loop?

You can write your topic however you want, but you need to answer these questions:

  1. 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.

  2. What is the issue? Include screenshots / videos if possible!
    I don’t know what is the best way to achieve this.

  3. 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.

1 Like

I don’t understand though why you want to teleport players automatically and then at the same time also want when they press a button.

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 -

local button = whatever you want

button.MouseButton1Down:Connect(function()
game.Players.LocalPlayer:LoadCharacter()
end)

Add this in server script -

game.Players.CharacterAutoLoads = false

Try it, it should work.

1 Like

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.
2 Likes

while loop would run. What you could do is check if sufficient players are there, if so, start the counter even if a player left.

1 Like

You could simply go to Players and then uncheck the CharacterAutoLoads property.

1 Like

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.

It would be helpful to see what code you have right now. What’s the part of the code that loops?

1 Like

Hmmm…Have you setted any code for the button to be shown or it’s just normally visible ?

1 Like

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.

  1. What is the code for this specific module function?
matchManager.prepareGame()
  1. Your menu UI could probably be disabled?
1 Like

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

I checked through again and confirmed the menu GUI is Enabled
and the main frame is Visible on the property.

playerManager.sendPlayersToMatch() could be the problem. Mind also sending that module here?

1 Like

What does the GUI look like, and where is it in the Explorer?

1 Like

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

1 Like

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).

I have already this game public.
CO2 Busters
So, pls check if u r interested in how it look like now.