Round-based game with tutorial on first join

Hi everyone.

I am trying to make a round-based game, with a turtorial arena when a player joins for the first time.
The round based game works fine- it starts in the lobby, then the arena, then the victory arena, then repeats the process.

When a new player joins for the first time, however, I check for a badge, which is awarded at the end of the tutorial (this works). When I use the code below the whole cycle stops working. It takes me to the lobby, and that is all.

Any ideas why?

inRound.Changed:Connect(function()
	if inRound.Value == true then
	
		for i, plr in pairs(game.Players:GetChildren()) do
			local char = plr.Character
			local humanRoot = char:WaitForChild("HumanoidRootPart")
			local humanoid = char:WaitForChild("Humanoid")
			humanoid.Health = 100
			humanRoot.CFrame = game.Workspace.ArenaStartPart.CFrame
		end
	else
		for i, plr in pairs(game.Players:GetChildren()) do
			local char = plr.Character
			local humanRoot = char:WaitForChild("HumanoidRootPart")
			local humanoid = char:WaitForChild("Humanoid")
			humanoid.Health = 100
			humanRoot.CFrame = game.Workspace.LobbyStartPart.CFrame
		end
	end
end)

local function round()
	while true do
		inRound.Value = false
		for i = INTERMISSION, 0, -1 do
			wait(1)	
		end
		
		inRound.Value = true
		
		for i = ROUND_LENGTH, 0, -1 do
			wait(1)
		end
		
		--Victory Screen
		for i, plr in pairs(game.Players:GetPlayers()) do
			local char = plr.Character
			local humanRoot = char:WaitForChild("HumanoidRootPart")
			local humanoid = char:WaitForChild("Humanoid")
			
			humanRoot.CFrame = game.Workspace.SkyPart.CFrame
			status.Value = ""
		end
	
		inRound.Value = false
	end
end

game.Players.PlayerAdded:Connect(function(plr)
	
	if not badgeServ:UserHasBadgeAsync(plr.UserId,firstTimeBadge) then
		print(("Doesnt own badge"))
		game.Workspace.TutorialSpawnLocation.Enabled = true
	else
		spawn(round)	
	end	
end)

I would rather use data store for this instead of badges checking. Using data store are more efficient and reliable.

I used it originally, but I still had the same problem. It seems to break the cycle and I am stuck in the lobby when I insert the code.

You’re only using spawn(round) here, when the player joins. The else branch won’t run if the player joined for the first time, which means round is never called when you activate the tutorial spawn location.

spawn(round) would be called once for each player that joins. So two players joining means two game loops are running, which would be bad.

Moving spawn(round) to the bottom of the script should fix this issue, although I can see other things that can go wrong (WIP).

  • I’m assuming enabling the tutorial spawn location means everyone will spawn there if just one person joins for the first time. It might be better to set Player.RespawnLocation instead.

  • Nitpick, it might be better to use task.wait(INTERMISSION) instead of a for loop.

  • Another nitpick, I would probably write round()'s while loop outside of the function and included at the bottom of the script. If you do this, make sure that round is not wrapped in a spawn, or your game will freeze up!

Thank you! This is a helpful answer. I changed it to

game.Players.PlayerAdded:Connect(function(plr)

	if not badgeServ:UserHasBadgeAsync(plr.UserId,firstTimeBadge) then
		plr.RespawnLocation = game.Workspace.TutorialSpawnLocation	
	else 
		plr.RespawnLocation = game.Workspace.Lobby.SpawnLocation
	end
	
end)
spawn(round)

It is better now, but the problem is that now the player spawns in the tutorial area while the round starts. How would I make it that the player in the tutorial is not part of the round at all (currently, when the intermission time runs out the player is spawned to the arena along wth the other players, even though he has not completed the tutorial yet)?