Neither.
Change your code to this:
local PlayersGroup = Players:GetPlayers()
local assigned_players = {}
local role_texts = {"Medic", "Killer", "Detective"} --//Used to define keys in the table
for i = 1, 3 do --//3 roles, so iterate 3 times.
local selected_index = math.random(1, #PlayersGroup)
local chosen_player = PlayersGroup[selected_index] --//Choose random player
local key = role_texts[i] --//Key to use for this iteration
assigned_players[key] = chosen_player --//Store chosen player in a dictionary versus storing 3 different variables
table.remove(PlayersGroup, selected_index) --//Remove the index of the selected player from the PlayersGroup table so it cannot be chosen again
end
Did that when @C_Sharper posted it
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StarterGui = game:GetService("StarterGui")
local Event = ReplicatedStorage:WaitForChild("DisplayRole")
local TraitorHUD = StarterGui:WaitForChild("TraitorHUD")
local Killer = nil
local Medic = nil
local Detective = nil
local Survivors = {}
function pickPlayers()
Killer = nil
Medic = nil
Detective = nil
Survivors = {}
local PlayersGroup = Players:GetPlayers()
if tonumber(PlayersGroup) > 0 then
local assigned_players = {}
local role_texts = {"Medic", "Killer", "Detective", "Civilian"}
for i = 1, 4 do
local selected_index = math.random(#PlayersGroup)
local chosen_player = PlayersGroup[selected_index] --//Choose random player
local key = role_texts[i]
assigned_players[key] = chosen_player
table.remove(PlayersGroup, selected_index)
end
else
return
end
Event:FireClient(Players[Medic], "You are Medic") -- Sends a text onto a players screen
Event:FireClient(Players[Detective], "You are Detective")
for i, v in pairs(Survivors) do
Event:FireClient(Players[v], "You are Civilian")
end
Event:FireClient(Players[Killer], "You are Traitor")
Players[Killer].PlayerGui.TraitorHUD.Enabled = true
print("Medic: ".. Medic) -- Prints the role and name of a player
for i, v in pairs(Survivors) do
print("Civilian: ".. v)
end
if Players[Killer] then
print("Traitor: ".. Killer)
end
if Players[Detective] then
print("Detective: ".. Detective)
end
end
while wait(10) do
pickPlayers()
end
Change your code to this:
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StarterGui = game:GetService("StarterGui")
local Event = ReplicatedStorage:WaitForChild("DisplayRole")
local TraitorHUD = StarterGui:WaitForChild("TraitorHUD")
local Killer = nil
local Medic = nil
local Detective = nil
local Survivors = {}
function pickPlayers()
Killer = nil
Medic = nil
Detective = nil
Survivors = {}
local PlayersGroup = Players:GetPlayers()
if tonumber(PlayersGroup) > 0 then
local assigned_players = {}
local role_texts = {"Medic", "Killer", "Detective", "Civilian"}
for i = 1, 4 do
local selected_index = math.random(1, #PlayersGroup)
local chosen_player = PlayersGroup[selected_index] --//Choose random player
local key = role_texts[i]
assigned_players[key] = chosen_player
table.remove(PlayersGroup, selected_index)
end
else
return
end
Event:FireClient(Players[Medic], "You are Medic") -- Sends a text onto a players screen
Event:FireClient(Players[Detective], "You are Detective")
for i, v in pairs(Survivors) do
Event:FireClient(Players[v], "You are Civilian")
end
Event:FireClient(Players[Killer], "You are Traitor")
Players[Killer].PlayerGui.TraitorHUD.Enabled = true
print("Medic: ".. Medic) -- Prints the role and name of a player
for i, v in pairs(Survivors) do
print("Civilian: ".. v)
end
if Players[Killer] then
print("Traitor: ".. Killer)
end
if Players[Detective] then
print("Detective: ".. Detective)
end
end
while wait(10) do
pickPlayers()
end
[02:13:01.665 - ServerScriptService.EventRolePicker:29: invalid argument #2 to ‘random’ (interval is empty)
Still the same error. It shouldn’t be empty. I tested it in a LocalServer with 4 players. Team Test, and even joining the game on two accounts.
That’s literally the exact same code I just sent. You just left out
local Players = game:GetService(“Players”)
I did not leave out this variable, when I copied it so I can check on studio (to find line 29) might have not been marked.
Just retype the variable there.
I did and it’s the exact same code I had sent earlier. Nothing’s changed lol.
Look I appreciate the help, but if you don’t know what you’re doing and just resending code others have sent, then save yourself the time.
I might as well look back on the Wiki and stare at this for another few hours.
I changed :GetPlayers()
to :GetChildren()
in line 21. And I know what I am doing, if I wouldn’t know what I am doing I wasn’t here to help you. You are reacting too fast before checking the code.
You never check if the player gets chosen multiple times here
You would need to remove the player from the table before you continue.
local KillerID = math.random(1, #PlayersGroup) -- Picks ONE player from the entire server
table.remove(PlayersGroup, KillerID)
local MedicID = math.random(1, #PlayersGroup)
table.remove(PlayersGroup, MedicID)
local DetectiveID = math.random(1, #PlayersGroup)
table.remove(PlayersGroup, DetectiveID)
Here is the fixed code:
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StarterGui = game:GetService("StarterGui")
local Event = ReplicatedStorage:WaitForChild("DisplayRole")
local TraitorHUD = StarterGui:WaitForChild("TraitorHUD")
local Killer = nil
local Medic = nil
local Detective = nil
local Survivors = {}
function pickPlayers()
Killer = nil
Medic = nil
Detective = nil
Survivors = {}
local PlayersGroup = Players:GetChildren()
if tonumber(PlayersGroup) > 0 then
local assigned_players = {}
local role_texts = {"Medic", "Killer", "Detective", "Civilian"}
for i = 1, 4 do
local selected_index = math.random(1, #PlayersGroup)
local chosen_player = PlayersGroup[selected_index] --//Choose random player
local key = role_texts[i]
assigned_players[key] = chosen_player
table.remove(PlayersGroup, selected_index)
end
else
return
end
Event:FireClient(Players[Medic], "You are Medic") -- Sends a text onto a players screen
Event:FireClient(Players[Detective], "You are Detective")
for i, v in pairs(Survivors) do
Event:FireClient(Players[v], "You are Civilian")
end
Event:FireClient(Players[Killer], "You are Traitor")
Players[Killer].PlayerGui.TraitorHUD.Enabled = true
print("Medic: ".. Medic) -- Prints the role and name of a player
for i, v in pairs(Survivors) do
print("Civilian: ".. v)
end
if Players[Killer] then
print("Traitor: ".. Killer)
end
if Players[Detective] then
print("Detective: ".. Detective)
end
end
while wait(10) do
pickPlayers()
end
[02:50:54.078 - ServerScriptService.EventRolePicker:23: attempt to compare number and nil
I then changed
if tonumber(PlayersGroup) > 0 then
--// Changed to
if tonumber(#PlayersGroup) > 0 then
--// However this only led to another error saying #PlayerGroup is empty
remove the humanoid that has been chosen from the table, that should fix your issue
Remove tonumber
, maybe it contain string and it returned nil.
What humanoid? Unless you are referring to removing “Killer” or “Medic” or “Detective” from the table. I have that here.
table.remove(PlayersGroup, selected_index)
oh god, i just saw the amount of responses, disregard my posts, lol
Solve one problem and another one pop ups.
[02:56:40.047 - ServerScriptService.EventRolePicker:29: invalid argument #2 to ‘random’ (interval is empty)
Still so confused on how it’s empty. Definitely not empty and there’s a whole line checking if there is a player in the game.
I just realized this would cause issues if there is < 3 players in the server.
In that case, you’d want to run a condition statement seeing if the current length of the PlayersGroup table is > 0 in the iterator, and if it isn’t break out of the loop and run the core game function again when the number of players in the server is sufficient.
In a nutshell
Each iteration, it removes the previously selected index from the table, guaranteeing that a new index is selected. However. If only one player is present in the server, the iterator will run another 2 times, and at that point the first (and only) selected index of the table has been removed.
Wasn’t thinking about that when I wrote the code.
trying to find the length of an array already returns a number. no need to use tonumber
Please dont do that. It’s bad practice.