How do I make math.random more random

Hey! So I was testing with my friend and everytime I was chosen a killer, I become a killer for 10+ rounds. How do I make it more uniquely random?

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")

local Cooldown = wait(3)
local Status = ReplicatedStorage.Status
local VotingSystem = game.Workspace.Voting
local Choices = VotingSystem:GetChildren()
local Maps = ReplicatedStorage.Maps:GetChildren()
local Intermission = 15

local LobbyTeam = Teams["Lobby"]
local RedTeam = Teams["Killer"]
local BlueTeam = Teams["Runner"]
local RedTeamColor = RedTeam.TeamColor
local BlueTeamColor = BlueTeam.TeamColor
local RedTeamCount
local BlueTeamCount

local IsAnOption
local RandomMap
local ChosenMap
local MapClone

local function PickRandomMap()
    local RandomNumber = math.random(1,#Maps)
    RandomMap = Maps[RandomNumber]
    return RandomMap.CanBeVoted
end 

for Index, Choice in pairs(Choices) do
    local Name = Choice.label.SurfaceGui.TextLabel
	local Picture = Choice.Image.SurfaceGui.ImageLabel

	IsAnOption = PickRandomMap()

	if IsAnOption.Value == true then
		repeat 
			IsAnOption = PickRandomMap()
		until
		IsAnOption.Value == false
		Name.Text = RandomMap.Name
		Picture.Image = RandomMap.Image.Value
		RandomMap.CanBeVoted.Value = true
	else
		Name.Text = RandomMap.Name
		Picture.Image = RandomMap.Image.Value
		RandomMap.CanBeVoted.Value = true
	end					
end

ReplicatedStorage.InRound.Changed:Connect(function()
   	if ReplicatedStorage.InRound.Value == false then
		MapClone:Destroy()
            
		for Index, Map in pairs(Maps) do
			Map.CanBeVoted.Value = false
		end
            
		for Index, Choice in pairs(Choices) do
			local Name = Choice.label.SurfaceGui.TextLabel
			local Picture = Choice.Image.SurfaceGui.ImageLabel

			IsAnOption = PickRandomMap()

			if IsAnOption.Value == true then
				repeat 
					IsAnOption = PickRandomMap()
				until
				IsAnOption.Value == false
				Name.Text = RandomMap.Name
				Picture.Image = RandomMap.Image.Value
				RandomMap.CanBeVoted.Value = true

			else
				Name.Text = RandomMap.Name
				Picture.Image = RandomMap.Image.Value
				RandomMap.CanBeVoted.Value = true		
			end					
		end	
	else
		local Choice1Votes = #VotingSystem.Choice1.button.Votes:GetChildren()
		local Choice2Votes = #VotingSystem.Choice2.button.Votes:GetChildren()
		local Choice3Votes = #VotingSystem.Choice3.button.Votes:GetChildren()

		if Choice1Votes >= Choice2Votes and Choice1Votes >= Choice3Votes then

			ChosenMap = VotingSystem.Choice1.label.SurfaceGui.TextLabel.Text

		elseif Choice2Votes >= Choice1Votes and Choice2Votes >= Choice3Votes then

			ChosenMap = VotingSystem.Choice2.label.SurfaceGui.TextLabel.Text

		else

			ChosenMap = VotingSystem.Choice3.label.SurfaceGui.TextLabel.Text

		end
    Status.Value = "The Chosen map is: ".. ChosenMap”
		for Index, Map in pairs(Maps) do
			if ChosenMap == Map.Name then
				MapClone = Map:Clone()
				MapClone.Parent = game.Workspace
			end
		end	
        Cooldown
        
		for Index, Choice in pairs(Choices) do
			Choice.label.SurfaceGui.TextLabel.Text = " "
			Choice.Image.SurfaceGui.ImageLabel.Image = " "
			Choice.button.Votes:ClearAllChildren()
			ReplicatedStorage.VoteReset:FireAllClients(Choice.button)
		end

		local BlueTeamCount = {}
		local RedTeamCount = {}
    local Contestants = {}
      
		for Index, Player in pairs(Players:GetChildren()) do
			local Character = Player.Character
			local RootPart = Character:WaitForChild("HumanoidRootPart")
			local NameGUI = Character.Head:FindFirstChild("NameGUI")
-- Spawns
			local RedSpawns = MapClone.RedSpawns:GetChildren()
			local BlueSpawns = MapClone.BlueSpawns:GetChildren()

			local RandomRedSpawn = RedSpawns[math.random(1,#RedSpawns)]
			local RandomBlueSpawn = BlueSpawns[math.random(1,#BlueSpawns)]  
     		if #RedTeamCount == 1 then

				Player.Team = BlueTeam
				RootPart.CFrame = RandomBlueSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))
				Player.CameraMode = "Classic"
				Player.CameraMaxZoomDistance = 9
				table.insert(BlueTeamCount, Player.Name)
				if NameGUI then
					NameGUI.Name.TextColor3 = BlueTeamColor
				end
				print(Player.Name .. " Inside: ".. Player.Team.Name)
			elseif #RedTeamCount == 0 then

				Player.Team = redTeam
				Player.CameraMode = "LockFirstPerson"
				Player.CameraMaxZoomDistance = 0.5
				RootPart.CFrame = RandomRedSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))

				table.insert(RedTeamCount, Player.Name)

				if NameGUI then
					NameGUI.Name.TextColor3 = RedTeamColor
				end

				print(Player.Name .. " Inside: ".. Player.Team.Name)
			else   
                while true do
                      wait(2)
                      for Index, Player in pairs(Players:GetChildren()) do                 
                             if Player and Player.Character then
                             local Human = Player.Character:WaitForChild("Humanoid")
                             if Human and Human.Health > 0 then                          
                                    table.insert(Contestants,Player)
                             end
                         end
                     end
                     if #Contestants >= 2 then
                        break
                     else
                        print("Waiting For Players")
                     end
                 end 
                    
           --    local Killer = Players:GetPlayers()[math.random(1,#Players:GetPlayers())]
           --    local KillerTwo = Players:GetPlayers()[math.random(1,#Players:GetPlayers())]
                 local Killer = Contestants[math.random(1,#Contestants)]
                 local KillerTwo = Contestants[math.random(1,#Contestants)]
                 
                 for Index, Player in pairs(Players:GetChildren()) do                  
                     if Player == Killer then
                        Player.Team = RedTeam
                        RootPart.CFrame = RandomRedSpawn.CFrame + Vector3.new(math.random(1,3), math.random(1,3), math.random(1,3))
                        Player.CameraMode = "LockFirstPerson"                    
                        Player.CameraMaxZoomDistance = 9
                        table.insert(RedTeamCount, Player.Name)
                        if NameGUI then
                           NameGUI.Name.TextColor3 = RedTeamColor
                        end
                        print(Player.Name.." Inside: "..Player.Team.Name)
                     elseif Player ~= Killer and Player ~= Killer2 then
                        Player.Team = BlueTeam
                        Player.CameraMode = "Classic"
                        Player.CameraMaxZoomDistance = 9
                        RootPart.CFrame = RandomBlueSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))
                        table.insert(BlueTeamCount, Player.Name)
                        if NameGUI then
                           NameGUI.Name.TextColor3 = BlueTeam
                        end
                        print(Player.Name.." Inside: "..Player.Team.Name)
                        end
                    end
                    if #Contestants >= 6 then
                       if Player == Killer2 then
                          Player.Team = RedTeam
                        RootPart.CFrame = RandomRedSpawn.CFrame + Vector3.new(math.random(1,3), math.random(1,3), math.random(1,3))
                        Player.CameraMode = "LockFirstPerson"                    
                        Player.CameraMaxZoomDistance = 9
                        table.insert(RedTeamCount, Player.Name)
                        if NameGUI then
                           NameGUI.Name.TextColor3 = RedTeamColor
                        end
                        print(Player.Name.." Inside: "..Player.Team.Name)
                        end
                    end
                end
                Character:WaitForChild("Humanoid").Died:Connect(function()
                Player.Team = LobbyTeam
                Player.CameraMode = "Classic"
                Player.CameraMaxZoomDistance = 9
            end)
        end
    end
end)

1 Like

You can keep track of the last killer and if the new random killer is the same then do math.random again until you get a different killer. Or you could do a more efficient method: Remove the previous killer from the list of players that can be a killer and then after the next round add them back in again.

5 Likes

How would I keep track of the previous killer?

1 Like

Make a local variable at the top of the script and call it something like “PreviousKiller”, then set PreviousKiller to the Killer that you get from math.random

2 Likes

So something like this?


for Index, Player in pairs(Players:GetChildren()) do                  
                     if Player == Killer then
                        PreviousKiller = Player
                            if PreviousKiller == Killer then
                                repeat Killer until PreviousKiller ~= Killer
                                end
                            end
                        Player.Team = RedTeam
                        RootPart.CFrame = RandomRedSpawn.CFrame + Vector3.new(math.random(1,3), math.random(1,3), math.random(1,3))
                        Player.CameraMode = "LockFirstPerson"                    
                        Player.CameraMaxZoomDistance = 9
                        table.insert(RedTeamCount, Player.Name)
                        if NameGUI then
                           NameGUI.Name.TextColor3 = RedTeamColor
                        end
                        print(Player.Name.." Inside: "..Player.Team.Name)

the repeat part won’t work for a few reasons. First of all when you make a repeat loop you have to add a wait() (task.wait() is even better), also if you’re using PreviousKIller and you are trying to get a random killer then don’t use a repeat loop and instead make a table with all the possibly players that can be the Killer but don’t put the PreviousKiller inside that table. Then get a random index in that table by doing math.random(1, #TheLengthOfTheTable) and you’ll get a random player that will never select the PreviousKiller.

1 Like

here’s some quick code that i wrote that should do the job:


local PreviousKiller : Player? = nil
local PlayerList = {}

local function PickKiller()
   for _, player : Player in game:GetService("Players"):GetPlayers() do
   	if player ~= PreviousKiller then
   		table.insert(PlayerList, player)
   	end
   end
   
   local RandomIndex = math.random(1, #PlayerList)
   local SelectedKiller = PlayerList[RandomIndex]
   PreviousKiller = SelectedKiller
   table.clear(PlayerList)

   return SelectedKiller
end
1 Like

I got you. So what I can do is remove the player who got killer from a table with contestants and if it runs again, it will choose someone else. But how do i add them back again after 2 rounds have passed?

Ok i made a slight mistake in the code, i forgot to clear out the table at the end of the function.

I made a table called Contestants, can I replace your table to contestants?

Yeah should be fine if it doesn’t hold anything inside it.

1 Like

The “PreviousKiller” variable will be overwritten by a new killer so the killer from the previous round will be added to the PlayerList again.

1 Like

Thank you I was about ask that (:

1 Like

One more question. This is how I use it right?


                 local function PickKiller()
                       for _, player : Player in game:GetService("Players"):GetPlayers() do
                        	if player ~= PreviousKiller then
   		                      table.insert(PlayerList, player)
   	                       end
                       end
                       local RandomIndex = math.random(1, #PlayerList)
                       local SelectedKiller = PlayerList[RandomIndex]
                       PreviousKiller = SelectedKiller
                       table.clear(PlayerList)

                       return SelectedKiller
                 end
                    
           --    local Killer = Players:GetPlayers()[math.random(1,#Players:GetPlayers())]
           --    local KillerTwo = Players:GetPlayers()[math.random(1,#Players:GetPlayers())]
                 local Killer = Contestants[math.random(1,#Contestants)]
                 local KillerTwo = Contestants[math.random(1,#Contestants)]
                 
                 for Index, Player in pairs(Players:GetChildren()) do                  
                     if Player == Killer then
                        PickKiller()
                        Player.Team = RedTeam
                        RootPart.CFrame = RandomRedSpawn.CFrame + Vector3.new(math.random(1,3), math.random(1,3), math.random(1,3))
                        Player.CameraMode = "LockFirstPerson"                    
                        Player.CameraMaxZoomDistance = 9
                        table.insert(RedTeamCount, Player.Name)
                        if NameGUI then
                           NameGUI.Name.TextColor3 = RedTeamColor
                        end
                        print(Player.Name.." Inside: "..Player.Team.Name)
                     elseif Player ~= Killer and Player ~= Killer2 then
                        Player.Team = BlueTeam
                        Player.CameraMode = "Classic"
                        Player.CameraMaxZoomDistance = 9
                        RootPart.CFrame = RandomBlueSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))
                        table.insert(BlueTeamCount, Player.Name)
                        if NameGUI then
                           NameGUI.Name.TextColor3 = BlueTeam
                        end
                        print(Player.Name.." Inside: "..Player.Team.Name)
                        end
                    end
                    if #Contestants >= 6 then
                       if Player == Killer2 then
                          Player.Team = RedTeam
                          PickKiller()
                        RootPart.CFrame = RandomRedSpawn.CFrame + Vector3.new(math.random(1,3), math.random(1,3), math.random(1,3))
                        Player.CameraMode = "LockFirstPerson"                    
                        Player.CameraMaxZoomDistance = 9
                        table.insert(RedTeamCount, Player.Name)
                        if NameGUI then
                           NameGUI.Name.TextColor3 = RedTeamColor
                        end
                        print(Player.Name.." Inside: "..Player.Team.Name)
                        end
                    end
                end

Since you do not set the random seed, it will just generate the number the same over and over again. Add math.randomseed(os.time()) somewhere.

Or, alternatively, you should use something like Random.new instead of math.random because setting the seed could mess up other scripts.

2 Likes

In this case Killer two can can possibly be the same as Killer one

1 Like

PickKiller() returns the selected killer, so if you want to get a killer then do: local Killer = PickKiller()

1 Like

For that, I thought of doing this but I got stuck st the if statement

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")

local Cooldown = wait(3)
local Status = ReplicatedStorage.Status
local VotingSystem = game.Workspace.Voting
local Choices = VotingSystem:GetChildren()
local Maps = ReplicatedStorage.Maps:GetChildren()
local Intermission = 15

local LobbyTeam = Teams["Lobby"]
local RedTeam = Teams["Killer"]
local BlueTeam = Teams["Runner"]
local RedTeamColor = RedTeam.TeamColor
local BlueTeamColor = BlueTeam.TeamColor
local RedTeamCount
local BlueTeamCount

local IsAnOption
local RandomMap
local ChosenMap
local MapClone
math.randomseed(tick())

local function PickRandomMap()
	local RandomNumber = math.random(1,#Maps)
	RandomMap = Maps[RandomNumber]
	return RandomMap.CanBeVoted
end 

for Index, Choice in pairs(Choices) do
	local Name = Choice.label.SurfaceGui.TextLabel
	local Picture = Choice.Image.SurfaceGui.ImageLabel

	IsAnOption = PickRandomMap()

	if IsAnOption.Value == true then
		repeat 
			IsAnOption = PickRandomMap()
		until
		IsAnOption.Value == false
		Name.Text = RandomMap.Name
		Picture.Image = RandomMap.Image.Value
		RandomMap.CanBeVoted.Value = true
	else
		Name.Text = RandomMap.Name
		Picture.Image = RandomMap.Image.Value
		RandomMap.CanBeVoted.Value = true
	end					
end

ReplicatedStorage.InRound.Changed:Connect(function()
	-- Choosing Map
	if ReplicatedStorage.InRound.Value == false then
		MapClone:Destroy()

		for Index, Map in pairs(Maps) do
			Map.CanBeVoted.Value = false
		end

		for Index, Choice in pairs(Choices) do
			local Name = Choice.label.SurfaceGui.TextLabel
			local Picture = Choice.Image.SurfaceGui.ImageLabel

			IsAnOption = PickRandomMap()

			if IsAnOption.Value == true then
				repeat 
					IsAnOption = PickRandomMap()
				until
				IsAnOption.Value == false
				Name.Text = RandomMap.Name
				Picture.Image = RandomMap.Image.Value
				RandomMap.CanBeVoted.Value = true

			else
				Name.Text = RandomMap.Name
				Picture.Image = RandomMap.Image.Value
				RandomMap.CanBeVoted.Value = true		
			end					
		end	
	else
		local Choice1Votes = #VotingSystem.Choice1.button.Votes:GetChildren()
		local Choice2Votes = #VotingSystem.Choice2.button.Votes:GetChildren()
		local Choice3Votes = #VotingSystem.Choice3.button.Votes:GetChildren()

		if Choice1Votes >= Choice2Votes and Choice1Votes >= Choice3Votes then

			ChosenMap = VotingSystem.Choice1.label.SurfaceGui.TextLabel.Text

		elseif Choice2Votes >= Choice1Votes and Choice2Votes >= Choice3Votes then

			ChosenMap = VotingSystem.Choice2.label.SurfaceGui.TextLabel.Text

		else

			ChosenMap = VotingSystem.Choice3.label.SurfaceGui.TextLabel.Text

		end
		Status.Value = "The Chosen map is: ".. ChosenMap
		for Index, Map in pairs(Maps) do
			if ChosenMap == Map.Name then
				MapClone = Map:Clone()
				MapClone.Parent = game.Workspace
			end
		end	
		wait(2)

		for Index, Choice in pairs(Choices) do
			Choice.label.SurfaceGui.TextLabel.Text = " "
			Choice.Image.SurfaceGui.ImageLabel.Image = " "
			Choice.button.Votes:ClearAllChildren()
			ReplicatedStorage.VoteReset:FireAllClients(Choice.button)
		end
		-- Teams
		local BlueTeamCount = {}
		local RedTeamCount = {}
		local PlayerList = {}

		local PreviousKiller : Player? = nil

		local function PickKiller()
			for _, player : Player in game:GetService("Players"):GetPlayers() do
				if player ~= PreviousKiller then
					table.insert(PlayerList, player)
				end
			end
			local RandomIndex = math.random(1, #PlayerList)
			local SelectedKiller = PlayerList[RandomIndex]
			PreviousKiller = SelectedKiller
			table.clear(PlayerList)

			return SelectedKiller
		end

		local Killer = PickKiller()

		for _, Player in pairs(Players:GetChildren()) do
			local char = Player.Character
			local root = char:WaitForChild("HumanoidRootPart")
			local RedSpawns = MapClone.RedSpawns:GetChildren()
			local BlueSpawns = MapClone.BlueSpawns:GetChildren()
			local RandomBlueSpawn = BlueSpawns[math.random(1,#BlueSpawns)]   
			local RandomRedSpawn = RedSpawns[math.random(1,#RedSpawns)]
			local gui = char.Head:FindFirstChild("NameGUI")
			-- Check if the player is a killer
			if Player == Killer then
				Player.Team = RedTeam
				root.CFrame = RandomRedSpawn.CFrame + Vector3.new(math.random(1,3), math.random(1,3), math.random(1,3))
				Player.CameraMode = "LockFirstPerson"                    
				Player.CameraMaxZoomDistance = 9
				table.insert(RedTeamCount, Player.Name)
				if gui then
					gui.Name.TextColor3 = RedTeamColor
				end
				print(Player.Name.." Inside: "..Player.Team.Name)
			elseif Player ~= Killer then
				Player.Team = BlueTeam
				Player.CameraMode = "Classic"
				Player.CameraMaxZoomDistance = 9
				root.CFrame = RandomBlueSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))
				table.insert(BlueTeamCount, Player.Name)
				if gui then
					gui.Name.TextColor3 = BlueTeam
				end

				for Index, Player in pairs(Players:GetChildren()) do
					local Character = Player.Character
					local RootPart = Character:WaitForChild("HumanoidRootPart")
					local NameGUI = Character.Head:FindFirstChild("NameGUI")
					-- Spawns
					local RedSpawns = MapClone.RedSpawns:GetChildren()
					local BlueSpawns = MapClone.BlueSpawns:GetChildren()

					local RandomRedSpawn = RedSpawns[math.random(1,#RedSpawns)]
					local RandomBlueSpawn = BlueSpawns[math.random(1,#BlueSpawns)]  
					if #RedTeamCount == 1 then

						Player.Team = BlueTeam
						RootPart.CFrame = RandomBlueSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))
						Player.CameraMode = "Classic"
						Player.CameraMaxZoomDistance = 9
						table.insert(BlueTeamCount, Player.Name)
						if NameGUI then
							NameGUI.Name.TextColor3 = BlueTeamColor
						end
						print(Player.Name .. " Inside: ".. Player.Team.Name)
					elseif #RedTeamCount == 0 then

						Player.Team = RedTeam
						Player.CameraMode = "LockFirstPerson"
						Player.CameraMaxZoomDistance = 0.5
						RootPart.CFrame = RandomRedSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))

						table.insert(RedTeamCount, Player.Name)

						if NameGUI then
							NameGUI.Name.TextColor3 = RedTeamColor
						end

						print(Player.Name .. " Inside: ".. Player.Team.Name)
					else  
						Character:WaitForChild("Humanoid").Died:Connect(function()
							Player.Team = LobbyTeam
							Player.CameraMode = "Classic"
							Player.CameraMaxZoomDistance = 9
						end)
					end
				end
			end
		end
	end
end)

simply move the code under the if statement into the PickKiller function but the Player variable will be replaced with SelectedKiller, you also don’t need 2 PickKiller functions, you can just fire the same function twice

1 Like

Hey allan I was testing in game and I kept getting killer still. Do you want to see the game?