Math.random not random after second run

I’m going to try my hardest to explain this good.So my script is a script that runs rounds of games and it chooses random teams for players. For example it chooses if the player is a hunter or a runner.

The issue is it only randomizes once then after that you get the same team role as before`.

The Question is how do I make it always shuffle roles so people have a chance to become a hunter as well?

The variable that handles random teams:

local randTeam = math.Random(1,2)

The Entireity of the Script


local rep = game:GetService("ReplicatedStorage")
local plrs = game:GetService("Players")
local votingSystem = game.Workspace.Voting
local status = rep.Status

local redTeam = game.Teams["Killer"]
local blueTeam = game.Teams["Runner"]
local blueTeamColor = BrickColor.new ("Lime green")
local redTeamColor = BrickColor.new ("Really red")

local lobbyTeam = game.Teams.Lobby

local choices = votingSystem:GetChildren()
local maps = rep.Maps:GetChildren()

local intermission = 10

local isAnOption
local randomMap

local chosenMap
local mapClone

local BlueTeamCount
local RedTeamCount


-- picking a random map function
local function PickRandomMap ()

	local randomNumber = math.random(1, #maps)

	randomMap = maps[randomNumber]

	return randomMap.CanBeVoted
end


for i, 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 
			wait()
			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	


rep.InRound.Changed:Connect(function()

	if rep.InRound.Value == false then

		mapClone:Destroy()

		for i, map in pairs(maps) do
			map.CanBeVoted.Value = false
		end

		for i, 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

		-- after the intermission has ended, the round will soon begin
		--- when the map with most votes will be spawned

		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

		-- shows which map has won

		status.Value = "The Chosen map is: ".. chosenMap

		--- getting the map from the replicated storgae to the workspace

		for i, map in pairs(maps) do
			if chosenMap == map.Name then
				mapClone = map:Clone()
				mapClone.Parent = game.Workspace
			end
		end	

		--[[ another short delay right before the players get teleported you would also need to add 
		the same delay on the round system script]]
		wait(3)

		-- clears all the votes for next round

		for i, choice in pairs(choices) do
			choice.label.SurfaceGui.TextLabel.Text = " "
			choice.Image.SurfaceGui.ImageLabel.Image = " "
			choice.button.Votes:ClearAllChildren()
			rep.VoteReset:FireAllClients(choice.button)
		end

		-- this is if there are no teams wit dedicated spawns (free for all):

		--local spawns = mapClone.Spawns:GetChildren()

		local BlueTeamCount = {}
		local RedTeamCount = {}

		for i, plr in pairs(plrs:GetChildren()) do

			local char = plr.Character
			local humanRoot = char:WaitForChild("HumanoidRootPart")
			local nameGui = char.Head:FindFirstChild("NameGUI")

			local RedSpawns = mapClone.RedSpawns:GetChildren()
			local BlueSpawns = mapClone.BlueSpawns:GetChildren()

			-- picks a random spawn from each team
			local randomRedSpawn = RedSpawns[math.random(1,#RedSpawns)]
			local randomBlueSpawn = BlueSpawns[math.random(1,#BlueSpawns)]

			-- will put the current player into a team with the less amount of players

			if #RedTeamCount == 1 then

				plr.Team = blueTeam
				-- this is so we can make the spawn location for each player more randomized
				plr.CameraMode = "Classic"
				plr.CameraMaxZoomDistance = 9
				humanRoot.CFrame = randomBlueSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))

				table.insert(BlueTeamCount, plr.Name)
				if nameGui then
					nameGui.name.TextColor3 = blueTeamColor
				end
				print(plr.Name .. " put in ".. plr.Team.Name)

			elseif #RedTeamCount == 0 then

				plr.Team = redTeam
				plr.CameraMode = "LockFirstPerson"
				plr.CameraMaxZoomDistance = 0.5
				humanRoot.CFrame = randomRedSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))

				table.insert(RedTeamCount, plr.Name)

				if nameGui then
					nameGui.name.TextColor3 = redTeamColor
				end

				print(plr.Name .. " put in ".. plr.Team.Name)

				-- if both teams have the same amount of players, it choses a random team using math.random

			else

				local randTeam = Random.new(1,2)

				if randTeam == 1 then

					plr.Team = blueTeam
					plr.CameraMode = "Classic"
					plr.CameraMaxZoomDistance = 9
					humanRoot.CFrame = randomBlueSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))

					table.insert(BlueTeamCount, plr.Name)

					if nameGui then
						nameGui.name.TextColor3 = blueTeamColor
					end

					print(plr.Name .. " put in ".. plr.Team.Name)

				else

					plr.Team = blueTeam
					plr.CameraMode = "Classic"
					plr.CameraMaxZoomDistance = 9
					humanRoot.CFrame = randomBlueSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))

					table.insert(RedTeamCount, plr.Name)
					if nameGui then
						nameGui.name.TextColor3 = redTeamColor
					end
					print(plr.Name .. " put in ".. plr.Team.Name)

				end
			end



			--------- if the player dies, it puts them back in the lobby and removes them from the team

			-- when a player has died
			char:WaitForChild("Humanoid").Died:Connect(function()

				plr.Team = lobbyTeam


			end)

		end	

	end	
end)

1 Like

Why don’t you just do a separate for loop that loops through all the players online or whatever it may be, and then assign them a random team that way, like for example:

local Teams = game:GetService("Teams"):GetChildren()
local Players = game:GetService("Players"):GetPlayers()

for i, player in pairs(Players) do
	local RandomTeam = Teams[math.random(1, #Teams)]
	player.Team = RandomTeam
	print(player.Name .."is now on "..RandomTeam.Name)
end

Like shown above here, is a better usage of math.random.

It only chooses random teams for a round based game. For example, when the intermission ends, it chooses random teams. How would I implement your idea to start when the intermission ends?

Random teams for each player, right?

1 Like

Yeah, thats how it works. I can show you the game if you want to see

Perhaps you could do that, I mean I would think it wouldn’t be difficult to implement my usage,

I forgot to mention how my script works. If math.random gets 1, it checks and puts you into the blue team, if it gets 2 it puts you into the red team.

Would that change anything if my system works like that?

Yeah but this gets a completely random team without checking what number is chose like you did.
local RandomTeam = Teams[math.random(1, #Teams)]

The thing is, there are only 2 teams and there is one team for the lobby. if your getting all the teams and making people go in there randomly its going to put them inside the lobby team as well, thats why I did (1,2) instead of (1,#Teams)

So then you could just do something like…

local ChosenTeam = nil
repeat
    task.wait()
    ChosenTeam = Teams[math.random(1, #Teams)]
until ChosenTeam ~= game.Teams.Lobby

it works but it keeps printing the same value? do you want to check it for your self?

Printing the same value of what?

I can show you the problem in game. JukeBox - Roblox

Are you able to join so you can see for your self?

You should try the Random library since it gives you more granular functionality such as :NextInteger and the pseudo-random seed is purely localized, so the randomness is more “fair” as apart from math.random giving you the next random integer from the global seed