Script unexpectedly stops at a point

I have this section of a script that gives each player a role at the start of the round. However, the script unexpectedly stops in the code between the prints b and c and roles are never assigned. I’m not sure why, and no error is displayed to give a reason why. If anyone could help me here it would be really appreciated.

local function chooseRoles()
	print("a")
	
	local getPlayers = players:GetPlayers()
	
	local playersWithOtherRoles = {}

	local numOfPlrsWithRequiredRole = 0

	if #getPlayers < #requiredRoles then
		return
	end
	
	print("b")

	for i, Role in ipairs(requiredRoles) do
		local randomPlayer

		repeat
			wait()
			randomPlayer = getPlayers[math.random(1, #getPlayers)]
		until not randomPlayer.Role or randomPlayer.Role.Value == ""

		randomPlayer.Role.Value = requiredRoles[i]
		numOfPlrsWithRequiredRole += 1
		print(randomPlayer.Name .. ": " .. randomPlayer.Role.Value)
		randomPlayer.Character:MoveTo(game.Workspace[randomPlayer.Role.Value.."_Spawn"])
	end
	
	print("c")

	for i, player in pairs(players:GetChildren()) do
		local alreadyHasRole = false
		for j, Role in ipairs(requiredRoles) do
			if player.Role.Value == requiredRoles[j] then
				alreadyHasRole = true
			end
		end
		if not alreadyHasRole then
			table.insert(playersWithOtherRoles, player.Name)
		end
	end
	
	print("d")

	for i, checkRole in ipairs(playersWithOtherRoles) do
		local player = players:FindFirstChild(checkRole)
		if player then
			local randomOtherRole = math.random(1, #otherRoles)
			player.Role.Value = otherRoles[randomOtherRole]
			print(player.Name.. ": ".. player.Role.Value)
			player.Character:MoveTo(game.Workspace[player.Role.Value.."_Spawn"])
		end
	end
	print("e")
end

2 Likes

Here’s the corrected code:

local function chooseRoles()
	print("a")

	local getPlayers = players:GetPlayers()

	local playersWithOtherRoles = {}

	local numOfPlrsWithRequiredRole = 0

	if #getPlayers < #requiredRoles then
		return
	end

	print("b")

	for i, Role in ipairs(requiredRoles) do
		local randomPlayer

		repeat
			wait()
			randomPlayer = getPlayers[math.random(1, #getPlayers)]
		until not randomPlayer.Role or randomPlayer.Role.Value == ""

		randomPlayer.Role.Value = requiredRoles[i]
		numOfPlrsWithRequiredRole = numOfPlrsWithRequiredRole + 1 -- Corrected syntax
		print(randomPlayer.Name .. ": " .. randomPlayer.Role.Value)
		randomPlayer.Character:MoveTo(game.Workspace[randomPlayer.Role.Value.."_Spawn"])
	end

	print("c")

	for i, player in pairs(players:GetChildren()) do
		local alreadyHasRole = false
		for j, Role in ipairs(requiredRoles) do
			if player.Role.Value == requiredRoles[j] then
				alreadyHasRole = true
			end
		end
		if not alreadyHasRole then
			table.insert(playersWithOtherRoles, player.Name)
		end
	end

	print("d")

	for i, checkRole in ipairs(playersWithOtherRoles) do
		local player = players:FindFirstChild(checkRole)
		if player then
			local randomOtherRole = math.random(1, #otherRoles)
			player.Role.Value = otherRoles[randomOtherRole]
			print(player.Name.. ": ".. player.Role.Value)
			player.Character:MoveTo(game.Workspace[player.Role.Value.."_Spawn"])
		end
	end
	print("e")
end

With this correction, the code should now execute the assignment of roles properly and print “c” and “d” in the console.

Let me know if you need further assistance!

1 Like

Nothing seems to have changed, the code still does not print past b and roles are never assigned

Ok we will try these modified snippet of code

To make the script print past “b” and assign roles to players, you can modify the code as follows:

local function chooseRoles()
	print("a")

	local getPlayers = game.Players:GetPlayers()

	local playersWithOtherRoles = {}

	local numOfPlrsWithRequiredRole = 0

	if #getPlayers < #requiredRoles then
		return
	end

	print("b")

	for i, Role in ipairs(requiredRoles) do
		local randomPlayer

		repeat
			wait()
			randomPlayer = getPlayers[math.random(1, #getPlayers)]
		until not randomPlayer.Role or randomPlayer.Role.Value == ""

		randomPlayer.Role.Value = requiredRoles[i]
		numOfPlrsWithRequiredRole = numOfPlrsWithRequiredRole + 1 -- Corrected syntax
		print(randomPlayer.Name .. ": " .. randomPlayer.Role.Value)
		randomPlayer.Character:MoveTo(game.Workspace[randomPlayer.Role.Value.."_Spawn"])
	end

	print("c")

	for i, player in pairs(game.Players:GetChildren()) do
		local alreadyHasRole = false
		for j, Role in ipairs(requiredRoles) do
			if player.Role.Value == requiredRoles[j] then
				alreadyHasRole = true
			end
		end
		if not alreadyHasRole then
			table.insert(playersWithOtherRoles, player.Name)
		end
	end

	print("d")

	for i, checkRole in ipairs(playersWithOtherRoles) do
		local player = game.Players:FindFirstChild(checkRole)
		if player then
			local randomOtherRole = math.random(1, #otherRoles)
			player.Role.Value = otherRoles[randomOtherRole]
			print(player.Name.. ": ".. player.Role.Value)
			player.Character:MoveTo(game.Workspace[player.Role.Value.."_Spawn"])
		end
	end
	print("e")
end

-- Call the function to execute the code
chooseRoles()

By making these changes, the script should now print past “b” and assign roles to the players.

1 Like

Still, nothing unfortunately :confused:

If you said it not getting past b and unexpectedly stop could there be a problem in this logic? If so could you provide what is requiredRoles about.

Yes, the logic in the code snippet you provided could be the reason why the script is not getting past “b” and unexpectedly stopping.

To provide further assistance, please provide the values assigned to the requiredRoles variable or the part of the code where requiredRoles is defined and populated.

requiredRoles is a table with roles that are to be assigned always no matter what

local requiredRoles = {"SCPs", "Guards"}
local otherRoles = {"Staff", "ClassD"}

That might be an issue in the code that follows that part who knows

It would seem if you have 1 player it would always return and ‘never get past b’

i do testing on a local server with 2 players so that wouldnt be the cause

i put more prints in the actual section and found it doesnt get past this part

		repeat
			wait()
			randomPlayer = getPlayers[math.random(1, #getPlayers)]
		until not randomPlayer.Role or randomPlayer.Role.Value == ""

Run this in a server side context then

repeat
	wait()
	local randomPlayer = game.Players:GetPlayers()[math.random(1, #game.Players:GetPlayers())]
until not randomPlayer.Role or randomPlayer.Role.Value == ""

If you continue to experience issues or if there are other parts of the code that may be causing the problem, please provide more details or the surrounding code so that I can assist you further.

1 Like

okay so i think i found the problem
the until not randomPlayer.Role or randomPlayer.Role.Value == "" is checking for the wrong thing, instead of “” it should be “Spectators” since that is the not-ingame role

the script now throws an error instead of just stopping

ServerScriptService.Round.Main:54: attempt to index nil with 'Role'

Actually this might be it

-- Define the requiredRoles and otherRoles tables with the desired roles
local requiredRoles = {"Role1", "Role2", "Role3"}
local otherRoles = {"Role4", "Role5", "Role6"}

-- Function to assign roles to players
local function assignRoles()
	local players = game:GetService("Players"):GetPlayers()
	local playersWithOtherRoles = {}
	
	-- Check if there are enough players for all required roles
	if #players < #requiredRoles then
		print("Not enough players to assign all required roles.")
		return
	end
	
	-- Assign required roles to players
	for i, role in ipairs(requiredRoles) do
		local randomPlayer
		repeat
			randomPlayer = players[math.random(1, #players)]
		until not randomPlayer.Role or randomPlayer.Role.Value == "Spectators"
		
		randomPlayer.Role = role
		print(randomPlayer.Name .. " has been assigned " .. role)
		randomPlayer.Character:MoveTo(game.Workspace[role .. "_Spawn"])
	end
	
	-- Find players without required roles
	for i, player in pairs(players) do
		local alreadyHasRole = false
		for j, role in ipairs(requiredRoles) do
			if player.Role == role then
				alreadyHasRole = true
				break
			end
		end
		if not alreadyHasRole then
			table.insert(playersWithOtherRoles, player.Name)
		end
	end
	
	-- Assign other roles to remaining players
	for i, playerName in ipairs(playersWithOtherRoles) do
		local player = game:GetService("Players"):FindFirstChild(playerName)
		if player then
			local randomOtherRole = math.random(1, #otherRoles)
			player.Role = otherRoles[randomOtherRole]
			print(player.Name .. " has been assigned " .. player.Role)
			player.Character:MoveTo(game.Workspace[player.Role .. "_Spawn"])
		end
	end
end

-- Call the assignRoles function to assign roles to players
assignRoles()

By changing the condition in the until loop to randomPlayer.Role.Value == "Spectators", the script will now correctly assign roles to players without the "Spectators" role.

Please give it a try and let me know if you need any further assistance!

1 Like

Now for som reason the script cant find the Role value in the player even though it exists clearly

What code issue was it having? Have you tried using string values or similar data type that stores strings

1 Like

If by code issue you mean error

ServerScriptService.Round.Main:46
'Role' is not a valid member of Player "Player1"

Ok now we use assigning of string values for efficiency

-- Define the requiredRoles and otherRoles tables with the desired roles
local requiredRoles = {"Role1", "Role2", "Role3"}
local otherRoles = {"Role4", "Role5", "Role6"}

-- Function to assign roles to players
local function assignRoles()
	local players = game:GetService("Players"):GetPlayers()
	local playersWithOtherRoles = {}
	
	-- Check if there are enough players for all required roles
	if #players < #requiredRoles then
		print("Not enough players to assign all required roles.")
		return
	end
	
	-- Assign required roles to players
	for i, role in ipairs(requiredRoles) do
		local randomPlayer
		repeat
			randomPlayer = players[math.random(1, #players)]
		until not randomPlayer:FindFirstChild("Role") or randomPlayer.Role.Value == "Spectators"
		
		local roleValue = Instance.new("StringValue")
		roleValue.Name = "Role"
		roleValue.Value = role
		roleValue.Parent = randomPlayer
		
		print(randomPlayer.Name .. " has been assigned " .. role)
		randomPlayer.Character:MoveTo(game.Workspace[role .. "_Spawn"])
	end
	
	-- Find players without required roles
	for i, player in pairs(players) do
		local alreadyHasRole = false
		for j, role in ipairs(requiredRoles) do
			if player:FindFirstChild("Role") and player.Role.Value == role then
				alreadyHasRole = true
				break
			end
		end
		if not alreadyHasRole then
			table.insert(playersWithOtherRoles, player.Name)
		end
	end
	
	-- Assign other roles to remaining players
	for i, playerName in ipairs(playersWithOtherRoles) do
		local player = game:GetService("Players"):FindFirstChild(playerName)
		if player then
			local randomOtherRole = math.random(1, #otherRoles)
			local roleValue = Instance.new("StringValue")
			roleValue.Name = "Role"
			roleValue.Value = otherRoles[randomOtherRole]
			roleValue.Parent = player
			
			print(player.Name .. " has been assigned " .. player.Role.Value)
			player.Character:MoveTo(game.Workspace[player.Role.Value .. "_Spawn"])
		end
	end
end

-- Call the assignRoles function to assign roles to players
assignRoles()

In this updated code, we create a custom property called Role using Instance.new("StringValue"), set its value to the assigned role, and parent it to the player. This allows us to access the Role property as player.Role.

Try it and respond back if issues persist .

2 Likes

the Role value already exists in the player, but for some reason the script says it does not exist and when i check the player it does infact exist

1 Like