Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

this math.random script only runs once, even with a loop. why does it do this?

im trying to make a plates of fate type game with random events, but the math.random only does it once. if i run the script it only does one event then it just repeats that same event ive tried using a while true do loop but it didnt work i reverted the script so that i didnt change anything Can you maybe rewrite whats wrong? thanks. heres my code

local textLabel = game.StarterGui.ScreenGui.TextLabel
	local eventNumber = math.random(1,5)
	print(eventNumber)
while true do
	if eventNumber == 1 then
		textLabel.Text = "wait whats that falling from the sky"
		local brick = Instance.new("Part")
		brick.Size = Vector3.new(20, 20, 20)
		brick.Position = Vector3.new(0, 800, 0)
		brick.BrickColor = BrickColor.new("Really red")
		brick.Anchored = false
		brick.Parent = game.Workspace

		local touch_event = brick.Touched:Connect(function(hit)
			local hitPlayer = game.Players:GetPlayerFromCharacter(hit.Parent)
			if hitPlayer then
				local explosion = Instance.new("Explosion")
				explosion.Parent = game.Workspace
				explosion.Position = hitPlayer.Character.Head.Position
			end
		end)

		wait(8)

		touch_event:Disconnect()
		brick:Destroy()
		textLabel.Text = ""

	elseif eventNumber == 2 then
		print("Event 2")
		textLabel.Text = "oh no its raining acid"
		wait(3)
		textLabel.Text = ""
		local Players = game:GetService("Players")
		local Workspace = game:GetService("Workspace")
		local brickColor = BrickColor.new("Lime green")

		while true do
			local part = Instance.new("Part", Workspace)
			part.Size = Vector3.new(1,1,1)
			part.CFrame = CFrame.new(math.random(-80,80),200,math.random(-80,80))
			part.Anchored = false
			part.CanCollide = false
			part.BrickColor = brickColor
			part.Touched:Connect(function(hit)
				if hit.Parent:FindFirstChild("Humanoid") then
					hit.Parent.Humanoid:TakeDamage(5)
				end
			end)
			wait(0.05)
		end
		wait(5)
		for i,v in pairs(Workspace:GetChildren()) do
			if v:IsA("Part") then
				v:Destroy()
			end
		end

		print("Event has occurred!")
	elseif eventNumber == 3 then
		textLabel.Text = "someone will get targeted by an orbital strike"
		wait(3)
		textLabel.Text = ""
		local Players = game:GetService("Players")
		local Workspace = game:GetService("Workspace")
		local brickColor = BrickColor.new("Really red")

		while true do
			local player = Players:GetPlayers()[math.random(1, #Players:GetPlayers())]
			local part = Instance.new("Part", Workspace)
			part.Size = Vector3.new(30,1,30)
			part.CFrame = player.Character.Head.CFrame * CFrame.new(0,100,0)
			part.CanCollide = false
			part.Anchored = true
			part.BrickColor = brickColor
			part.Material = Enum.Material.Neon
			part.Touched:Connect(function(hit)
				if hit.Parent:FindFirstChild("Humanoid") then
					local explosion = Instance.new("Explosion", Workspace)
					explosion.Position = hit.Parent.HumanoidRootPart.Position
					explosion.BlastPressure = 200
					explosion.BlastRadius = 100
				end
			end)
			part.Size = part.Size + Vector3.new(0,300,0)
			wait(2)
			part:Destroy()
			wait(5)
		end

	elseif eventNumber == 4 then
		textLabel.Text = "some dude will get a sword"
		wait(3)
		textLabel.Text = ""
		local Players = game:GetService("Players")
		local randomPlayer = Players:GetPlayers()[math.random(1, #Players:GetPlayers())]
		local gear = game.ReplicatedStorage.swords.ClassicSword
		gear.Parent = randomPlayer.Backpack
		local textLabel = game.StarterGui.ScreenGui.TextLabel
	else
		print("Event 5")
	end
	wait(5)
	end

4 comments

0

You didn't even put eventNumber inside the loop

0

When i put the event number inside the loop, it doesnt work. Also please read the description first :) @T3_MasterGamer

0

Wdym I did read your description first. What I meant is that your script should work if only you put local eventNumber = math.random(1,5) inside the loop.

0

But it doesn't matter anymore since someone already solved it.

1 answer

✓ Accepted answer

When using while true do loops. You need something to break out from the loop, otherwise it will continue looping forever. So with that in mind, I've gone over your code and implemented a timer for your while loops, so they can break out after a time.

The modified code is as follows:

local textLabel = game.StarterGui.ScreenGui.TextLabel
local eventNumber = 0--math.random(1,5)
local AcidRainTime = 5
local LAZORTime = 2

while true do
	eventNumber = math.random(1,5)
	print(eventNumber)
	if eventNumber == 1 then
		textLabel.Text = "wait whats that falling from the sky"
		local brick = Instance.new("Part")
		brick.Size = Vector3.new(20, 20, 20)
		brick.Position = Vector3.new(0, 800, 0)
		brick.BrickColor = BrickColor.new("Really red")
		brick.Anchored = false
		brick.Parent = game.Workspace

		local touch_event = brick.Touched:Connect(function(hit)
			local hitPlayer = game.Players:GetPlayerFromCharacter(hit.Parent)
			if hitPlayer then
				local explosion = Instance.new("Explosion")
				explosion.Parent = game.Workspace
				explosion.Position = hitPlayer.Character.Head.Position
			end
		end)

		wait(8)

		touch_event:Disconnect()
		brick:Destroy()
		textLabel.Text = ""

	elseif eventNumber == 2 then
		print("Event 2")
		textLabel.Text = "oh no its raining acid"
		wait(3)
		textLabel.Text = ""
		local Players = game:GetService("Players")
		local Workspace = game:GetService("Workspace")
		local brickColor = BrickColor.new("Lime green")
		--// Create a timer since we're using a while loop so we can count upto 5 
		--// seconds before breaking out from the loop
		local StartTime = tick()
		--// create a container for our Rain so its easyer to clean up as the original 
		--// code would destroy the baseplace ... lolz
		local RainBits = (function() 
			local Folder = workspace:FindFirstChild("Rain") 
			if(Folder == nil) then
				Folder = Instance.new("Folder",workspace)
				Folder.Name = "Rain" 
			end
			return Folder 
		end)()
		while true do
			--// grab now time fom tick()
			local NowTime = tick()
			--// subract nowtime from the start time to get the seconds passed
			local DTime = NowTime - StartTime

			local part = Instance.new("Part", RainBits)
			part.Size = Vector3.new(1,1,1)
			part.CFrame = CFrame.new(math.random(-80,80),200,math.random(-80,80))
			part.Anchored = false
			part.CanCollide = false
			part.BrickColor = brickColor
			part.Touched:Connect(function(hit)
				if hit.Parent:FindFirstChild("Humanoid") then
					hit.Parent.Humanoid:TakeDamage(5)
				end
			end)
			--// if dtime greater than AcidRainTime then break out of this loop! 
			if(DTime >= AcidRainTime) then
				break
			end
			wait(0.05)
		end
		wait(5)
		--[[
			old code use to remove the Baseplate.... FUN!
			for i,v in pairs(Workspace:GetChildren()) do
			if v:IsA("Part") then
				v:Destroy()
			end
		end]]
		if(RainBits ~= nil) then
			RainBits:Destroy()
		end

		print("Event has occurred!")
	elseif eventNumber == 3 then
		textLabel.Text = "someone will get targeted by an orbital strike"
		wait(3)
		textLabel.Text = ""
		local Players = game:GetService("Players")
		local Workspace = game:GetService("Workspace")
		local brickColor = BrickColor.new("Really red")
		--// same idea as the above rain code aka create a start timer
		local StartTime = tick()
		while true do
			local player = Players:GetPlayers()[math.random(1, #Players:GetPlayers())]
			local part = Instance.new("Part", Workspace)
			--// now tick
			local NowTime = tick()
			--// subtract now tick from start tick to get seconds
			local DTime = NowTime - StartTime

			part.Size = Vector3.new(30,1,30)
			part.CFrame = player.Character.Head.CFrame * CFrame.new(0,100,0)
			part.CanCollide = false
			part.Anchored = true
			part.BrickColor = brickColor
			part.Material = Enum.Material.Neon
			part.Touched:Connect(function(hit)
				if hit.Parent:FindFirstChild("Humanoid") then
					local explosion = Instance.new("Explosion", Workspace)
					explosion.Position = hit.Parent.HumanoidRootPart.Position
					explosion.BlastPressure = 200
					explosion.BlastRadius = 100
				end
			end)
			part.Size = part.Size + Vector3.new(0,300,0)
			--wait(2)
			--// if DTime greator or equal to LAZORTime then remove the LAZOR 
			--//part and break out fom the loop
			if(DTime >= LAZORTime) then
				if(part ~= nil) then
					part:Destroy()
					break
				end
			end
			
			wait(5)
		end

	elseif eventNumber == 4 then
		textLabel.Text = "some dude will get a sword"
		wait(3)
		textLabel.Text = ""

		local Players = game:GetService("Players")
		local randomPlayer = Players:GetPlayers()[math.random(1, #Players:GetPlayers())]
		local gear = game.ReplicatedStorage.swords.ClassicSword
		gear.Parent = randomPlayer.Backpack
		local textLabel = game.StarterGui.ScreenGui.TextLabel

	else
		print("Event 5")
	end
	wait(5)
end

There are still a few problems with the orbital strike Lazar part as it doesn't disappear when the event is over, and you may need to sort out your GUI as this works in the studio, but I doubt it will work online though.

Anyway i hope this helps you and you should be able to read up on the GUI problem through RemoteEvents https://create.roblox.com/docs/reference/engine/classes/RemoteEvent

This discussion is preserved as it was. New answers, comments, and votes are closed.