Round system not working properly

Hello, i have been recently scripting this round system with a randomly generated map & gamemode. I stumbled upon a problem where the teleporting of players don’t work as i wanted it to.

The Problem:

The problem is that when the round starts it only teleports a random player from the “inLobby” table to the map and not everyone that is in the table. I have no clue why it is doing this, i can provide the code that i think is the culprit, let me know if there is anything i can give more context on.

local function startGame()
	randomMap()
	chosenMap.Parent = workspace
	local randomGamemode = gamemodeList[math.random(1, #gamemodeList)]
	
	-- Sword Fight Gamemode
	if randomGamemode == "Sword Fight" then
		for i, plr in pairs(inLobby) do
			local player = PlayerService:GetPlayerByUserId(plr)
			
			local character = player.Character
			local HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
			if HumanoidRootPart then
				
				local spawns = chosenMap.Spawns:GetChildren()
				local randomSpawn = spawns[math.random(1,#spawns)]
				table.remove(inLobby, table.find(inLobby, plr))
				table.insert(inGame, plr)
				
				HumanoidRootPart.CFrame = randomSpawn.CFrame
				
				local sword = toolsFolder.ClassicSword:Clone()
				local backpack = player.Backpack
				sword.Parent = backpack
				
			end
		end
	end
	
	-- other gamemodes
	
end

This is the startGame() function that i think messes up the teleport, point out anything wrong.

1 Like

it might be the WaitForChild, you can try adding a timeout parameter for it or using a new thread

to debug:
add print("players in lobby: " .. #inLobby) before the for loop
add print(1) before WaitForChild and print(2) after the sword is parented to the backpack, what’s the output?

1 Like

Try doing

character.PrimaryPart.CFrame = randomSpawn.CFrame
-- or
character:SetPrimaryPartCFrame(randomSpawn.CFrame)

instead of

HumanoidRootPart.CFrame = randomSpawn.CFrame
2 Likes

How are you filling up the inLobby table? You can just do something like

inLobby = PlayersService:GetPlayers()
1 Like

It prints out the ammount of players in the lobby and is correct, prints out 1 and 2 aswell.

i tried testing with 3 players and now 2 of the 3 players gets teleported to the map and only 1 of the 2 players that got teleported gets teleported to the lobby, i have no clue whats happening here to be honest. Maybe there is a fault in my entire script?

1 Like

I tested it out, got the same problem. i am starting to think it might be some faulty code in my entire script, but i am unsure

1 Like

And it printed the 2 for each of the 3 players?

1 Like

So i start with an empty table and add the players userid with a PlayerAdded. Here is how i fill the table.

	-- if player joins game then add to Lobby table, if dies then removed from inGame table and into Lobby table
PlayerService.PlayerAdded:Connect(function(plr)
	table.insert(inLobby, plr.UserId)
	print(inLobby)
	local character = plr.Character or plr.CharacterAdded:Wait()
	local humanoid = character:WaitForChild("Humanoid")
	humanoid.Died:Connect(function()
		table.remove(inGame, table.find(inGame, plr.UserId))
		table.insert(inLobby, plr.UserId)
	end)
end)

	-- if player leaves then remove from tables
PlayerService.PlayerRemoving:Connect(function(plr)
	table.remove(inLobby, table.find(inLobby, plr.UserId))
	local MightBeInGame = table.find(inGame, plr.UserId)
	if MightBeInGame then
		table.remove(inGame, MightBeInGame)
	end
end)

this is some code that i had to do some research on so i have not written this fully myself, so might not be the best way of doing it.

1 Like

Yeah that is one thing i forgot to mention as i have tried this before but with printing the player. It only prints the number once yes, and is not printed multiple times.

1 Like

Try this:

local Players = game:GetService("Players")

local inLobby = {}
local inGame = {}

Players.PlayerAdded:Connect(function(player)
	inLobby[player] = true
end)

Players.PlayerRemoving:Connect(function(player)
	inLobby[player] = nil
	inGame[player] = nil
end)

local function startGame()
	randomMap()
	chosenMap.Parent = workspace
	local randomGamemode = gamemodeList[math.random(1, #gamemodeList)]

	-- Sword Fight Gamemode
	if randomGamemode == "Sword Fight" then
		for player, isInLobby in inLobby do
			local character = player.Character

			if not character or not isInLobby then
				continue
			end

			local spawns = chosenMap.Spawns:GetChildren()
			local randomSpawn = spawns[math.random(1, #spawns)]
			
			inLobby[player] = false
			inGame[player] = true

			character:PivotTo(randomSpawn.CFrame)

			local sword = toolsFolder.ClassicSword:Clone()
			local backpack = player.Backpack
			sword.Parent = backpack
		end
	end

	-- other gamemodes
end
1 Like

maybe try character = player.Character or player.CharacterAdded:Wait
maybe it runs before the player`s character load

1 Like

Oh yeah wow it works now and all players get teleported, got this slight error but i am sure it is an easy fix?

  20:11:10.248  ServerScriptService.RoundScript V2:149: attempt to index nil with 'Character'  -  Server - RoundScript V2:149
1 Like
for player, isInLobby in inLobby do
   local character = player and player.Character
1 Like

That could be because the script tries to teleport a player who’s dead or hasn’t loaded in yet. Try checking if they have a character first.

local Players = game:GetService("Players")

local inLobby = {}
local inGame = {}

Players.PlayerAdded:Connect(function(player)
	inLobby[player] = true
end)

Players.PlayerRemoving:Connect(function(player)
	inLobby[player] = nil
	inGame[player] = nil
end)

local function startGame()
	randomMap()
	chosenMap.Parent = workspace
	local randomGamemode = gamemodeList[math.random(1, #gamemodeList)]

	-- Sword Fight Gamemode
	if randomGamemode == "Sword Fight" then
		for player, isInLobby in inLobby do
			local character = player.Character

			if not character or not isInLobby then
				continue
            else
                              -- Put code here to start gamemode 
			end
		end
	end

	-- other gamemodes
end
1 Like

thats what my script above does

1 Like

no it wont… continue goes to the next value in the iteration

1 Like

did this but can’t seem to make it fully work now. I am not sure if i did something wrong or if this just still does not work. This is really making my brain hurt for real haha, if needed i could provide full code if there might be some mess somewhere in the script that i am unsure of but i think this is the main problem.

Just worked but i somehow broke it i think, i am unsure.

1 Like

yes, provide the full code

Here is the full code, don’t mind my messy coding i am still working on it

-- Variables

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local toolsFolder = ReplicatedStorage.Tools
local maps = ReplicatedStorage.Maps:GetChildren()
local lobby = game.Workspace.Lobby

local INTERMISSION_TIME = 5
local GAME_TIME = 5
local END_GAME_TIME = 5

local gamemodeList = {"Sword Fight"}
local inLobby = {}
local inGame = {}
local minPlayers = 1



-- Player added/removing
Players.PlayerAdded:Connect(function(player)
	inLobby[player] = true
end)

Players.PlayerRemoving:Connect(function(player)
	inLobby[player] = nil
	inGame[player] = nil
end)



-- Functions

-- Choose Random Map Func
local chosenMap
local function randomMap()
	local randomMap = maps[math.random(1, #maps)]
	randomMap.Parent = workspace
	--print(randomMap)
	chosenMap = randomMap
end

-- Check for enough players
local function CheckForPlayers()
	if #Players:GetPlayers() < minPlayers then
		warn("Not Enough Players!")
		repeat wait(1) until #Players:GetPlayers() >= minPlayers
	end
end

-- Start Game Func
local function startGame()
	randomMap()
	chosenMap.Parent = workspace
	local randomGamemode = gamemodeList[math.random(1, #gamemodeList)]

	-- Sword Fight Gamemode
	if randomGamemode == "Sword Fight" then
		for player, isInLobby in inLobby do
			local character = player and player.Character

			if not character or not isInLobby then
				continue
			end

			local spawns = chosenMap.Spawns:GetChildren()
			local randomSpawn = spawns[math.random(1, #spawns)]

			inLobby[player] = false
			inGame[player] = true

			character:PivotTo(randomSpawn.CFrame)

			local sword = toolsFolder.ClassicSword:Clone()
			local backpack = player.Backpack
			sword.Parent = backpack
		end
	end

	-- other gamemodes
end

-- End Game Func
local function EndGame()
	for i, plr in pairs(inGame) do
		local player = Players:GetPlayerByUserId(plr)
		local character = player.Character
		local HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
		if HumanoidRootPart then
			-- Removes all tools from backpack
			local backpack = player.Backpack
			backpack:ClearAllChildren()
			for i, tools in pairs(character:GetChildren()) do
				if tools:IsA("Tool") then
					tools:Destroy()
				end
			end
			
			task.wait(END_GAME_TIME)
			
			table.remove(inGame, table.find(inGame, plr))
			table.insert(inLobby, plr)
			HumanoidRootPart.CFrame = lobby.TeleportPoint.CFrame + Vector3.new(0,5,0)
			
			warn("Game Ended")
		end
	end
	
	chosenMap.Parent = ReplicatedStorage.Maps
	
end


-- GAME LOOP!

while true do
	CheckForPlayers()
	for i = INTERMISSION_TIME, 1, -1 do
		print(i)
		
		CheckForPlayers()
		task.wait(1)
	end
	
	startGame()
	
	for i = GAME_TIME, 1, -1 do
		print(i)
		
		task.wait(1)
		
		if #inGame == 1 then
			local winner = Players:GetPlayerByUserId(inGame[1])
			print(winner.Name.." has won!")
			-- leaderstats script
			task.wait(1)
			break
		end
		if #inGame == 0 then
			warn("Everyone Lost!")
			task.wait(1)
			break
		end
	end
	
	EndGame()
	
end

Try this:

-- Variables

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local toolsFolder = ReplicatedStorage.Tools
local maps = ReplicatedStorage.Maps:GetChildren()
local lobby = game.Workspace.Lobby

local INTERMISSION_TIME = 5
local GAME_TIME = 5
local END_GAME_TIME = 5

local gamemodeList = {"Sword Fight"}
local inLobby = {}
local inGame = {}
local minPlayers = 1



-- Player added/removing
Players.PlayerAdded:Connect(function(player)
	inLobby[player] = true
	table.insert(inLobby, player)
end)

Players.PlayerRemoving:Connect(function(player)
	table.remove(inGame, table.find(inGame, player))
	table.remove(inLobby, table.find(inLobby, player))
end)


-- Functions

-- Choose Random Map Func
local chosenMap
local function randomMap()
	local randomMapChoice = maps[math.random(1, #maps)]
	randomMapChoice.Parent = workspace
	--print(randomMap)
	chosenMap = randomMapChoice
end

-- Check for enough players
local function CheckForPlayers()
	if #Players:GetPlayers() < minPlayers then
		warn("Not Enough Players!")
		repeat task.wait(1) until #Players:GetPlayers() >= minPlayers
	end
end

-- Start Game Func
local function startGame()
	randomMap()
	chosenMap.Parent = workspace
	local randomGamemode = gamemodeList[math.random(1, #gamemodeList)]

	-- Sword Fight Gamemode
	if randomGamemode == "Sword Fight" then
		for _, player in inLobby do
			local character = player and player.Character

			if not character then
				continue
			end

			local spawns = chosenMap.Spawns:GetChildren()
			local randomSpawn = spawns[math.random(1, #spawns)]

			inLobby[player] = false
			inGame[player] = true

			character:PivotTo(randomSpawn.CFrame)

			local sword = toolsFolder.ClassicSword:Clone()
			local backpack = player.Backpack
			sword.Parent = backpack
		end
	end

	-- other gamemodes
end

-- End Game Func
local function EndGame()
	for _, player in inGame do
		local character = player.Character
		if character then
			-- Removes all tools from backpack
			local backpack = player.Backpack
			backpack:ClearAllChildren()
			for i, tools in pairs(character:GetChildren()) do
				if tools:IsA("Tool") then
					tools:Destroy()
				end
			end
			
			task.wait(END_GAME_TIME)
			
			table.remove(inGame, table.find(inGame, player))
			table.insert(inLobby, player)
			character:PivotTo(lobby.TeleportPoint.CFrame + Vector3.new(0,5,0))
			
			warn("Game Ended")
		end
	end
	
	chosenMap.Parent = ReplicatedStorage.Maps
	
end


-- GAME LOOP!

while true do
	CheckForPlayers()
	for i = INTERMISSION_TIME, 1, -1 do
		print(i)
		
		CheckForPlayers()
		task.wait(1)
	end
	
	startGame()
	
	for i = GAME_TIME, 1, -1 do
		print(i)
		
		task.wait(1)
		
		if #inGame == 1 then
			local winner = Players:GetPlayerByUserId(inGame[1])
			print(winner.Name.." has won!")
			-- leaderstats script
			task.wait(1)
			break
		end
		if #inGame == 0 then
			warn("Everyone Lost!")
			task.wait(1)
			break
		end
	end
	
	EndGame()
	
end