Flickering light does not work as intended

Hi, so I have a flickering light system thing. That’s really all it is
What it’ll do is play a sound and change brightness and range every so often as it should, but instead it only does this once and stays at the changed values instead of fluctuating. I know I did something wrong, but since I’m blind I’m not been able to spot the thing that causes this.

Code
local light = script.Parent
local brightness = light.Brightness
local range = light.Range

local flicker1 = script.Parent.Parent.Flicker
local flicker2 = script.Parent.Parent.Flicker2
local flicker3 = script.Parent.Parent.Flicker3

local S = 0

local function stopFlicker()
	brightness = 2
	range = 60
end

local function flicker()
	while true do
		light.Brightness = brightness + math.random(-1, 1)
		light.Range = range + math.random(-5, 5)
		wait(math.random(0.1,0.5))
		if flicker1.Ended or flicker2.Ended or flicker3.Ended then
			break
		end
		stopFlicker()
	end
end

while true do
	wait(math.random(10,20))
	S = math.random(1,3)
	if S == 1 then
		flicker1:Play()
		flicker()
	end
	if S == 2 then
		flicker2:Play()
		flicker()
	end
	if S == 3 then
		flicker3:Play()
		flicker()
	end
end

any help is appreciated, thank you in advance

math.random only does integer values. You can use local rand = Random.new instead to create a Random object, and with that, you can use wait(rand:NextNumber(0.1,0.5)).

Also, if the sound is looped, sound.Ended will not work, and you will need to do sound.DidLoop.

dunno if this would be a solution since all values like the light’s range and brightness are all integers anyways. Sounds are not looped

Not this one. It might just be choosing to wait nothing.

Also, instead of having flicker1, flicker2, flicker3 you can have a sounds folder and do local sound = sounds:GetChildren()[math.random(1, #sounds:GetChildren())].

1 Like

ok so i did what you said, i made a sounds folder and this is what the code looks like now

New code
local light = script.Parent
local brightness = light.Brightness
local range = light.Range
local rand = Random.new()

local sounds = script.Parent.Parent.Sounds
local flickerSound = sounds:GetChildren()[math.random(1, #sounds:GetChildren())]

local S = 0

local function stopFlicker()
	brightness = 2
	range = 60
end

local function flicker()
	light.Brightness = brightness + math.random(-1, 1)
	light.Range = range + math.random(-5, 5)
	wait(rand:NextNumber(0.1,0.5))
	flickerSound:Play()
	flickerSound.Ended:Connect(stopFlicker)
end

while true do
	wait(rand:NextNumber(5,10))
	flicker()
end

but now it runs the loop after some time and it just will not stop flickering. colloquially said, it spams the function.
The goal is for it to play the sound once, flicker the light a few times and then go back to its normal state. But I can’t seem to figure that out

Ok. I will just fix the code for you, and then explain it.

local light = script.Parent
local brightness = light.Brightness
local range = light.Range
local rand = Random.new()
local flickering = true

local sounds = script.Parent.Parent.Sounds
local flickerSound = sounds:GetChildren()[math.random(1, #sounds:GetChildren())]

local S = 0

local function stopFlicker()
	brightness = 2
	range = 60
	flickering = false
end

local function flicker()
	if flickering then
		light.Brightness = brightness + math.random(-1, 1)
		light.Range = range + math.random(-5, 5)
		wait(rand:NextNumber(0.1,0.5))
		flickerSound:Play()
		spawn(function()
			flickerSound.Ended:Wait()
			stopFlicker()
		end)
	end
end

while true do
	wait(rand:NextNumber(5,10))
	flicker()
end

So I added a variable, called flickering. When not flickering the variable is set to false, which prevents flicker() from running.

I appreciate the help a lot, so how would I make the light actually flicker a few times between wait()s instead of just changing to a value once every interval?

Well, that wouldn’t exactly be possible, since without the wait()s, it would not wait and it would look like it didn’t flicker. However, adding a for loop is something you might want, like this:

while true do
	wait(rand:NextNumber(5,10))
	for i = 1, rand:NextInteger(1, 5) do
		flicker()
		task.wait(0.1)
	end
end

i mean this sort of works, but i want to create a more precise effect, to put it that way
I found this example, it may not be the best but I think it demonstrates what I want to achieve

Also, how should I modify the main loop so it only plays a sound once while it flickers?

Instead of Sound:Play() do Sound.Playing = true.

i figured this out, i just put it outside the for loop
speaking of which, which numbers in the for loop would change the speed of the flicker? like speed it up or slow it down? or is that in a completely different section of the script

The part with the random value, specifically rand:NextInteger(), you can increase the 2nd argument to increase flickering.

so if i turned rand:NextInteger(1, 5) into rand:NextInteger(1, 10) it would flicker twice as fast?

Not twice as fast, twice as much. The for loop I gave you will cause the amount of flickers per the wait statement in the while loop.

oh i thought it was the speed of the flickering went at, not how many times it would flicker. How would i change the speed of the flickering?

Sorry for taking longer to reply, I was busy.

Anyways, you’d modify this line

in the for loop.

exp110213
Lights are SurfaceLights facing downwards 0 Brightness
bases are 4,4,4 transparent box parts about as high up as that light in the video.
(In the same spot)

local cs = game:GetService("CollectionService")
local Light = cs:GetTagged("Light")
local Lights = workspace.Lights:GetChildren()

for index = 1, #Lights do
	cs:AddTag(Lights[index], "Light")
end Light = cs:GetTagged("Light")

local rs = game:GetService("RunService")
local step = tick() + math.random(5,30)/10

rs.Stepped:Connect(function()
	if tick() >= step then rs.Stepped:Wait()
		step = tick() + math.random(5,30)/10
		for index = 1, #Lights do
			Lights[index].Light.Brightness = 0.1 rs.Heartbeat:Wait()
			Lights[index].Light.Brightness = 2.4 rs.Heartbeat:Wait()
			Lights[index].Light.Brightness = 3.6 rs.Heartbeat:Wait()
			Lights[index].Light.Brightness = 0.1 rs.Heartbeat:Wait()
			Lights[index].Light.Brightness = 2.4 rs.Heartbeat:Wait()
			Lights[index].Light.Brightness = 3.6 rs.Heartbeat:Wait()
			Lights[index].Light.Brightness = 0.1 rs.Heartbeat:Wait()
			Lights[index].Light.Brightness = 3.6 rs.Heartbeat:Wait()
			Lights[index].Light.Brightness = 0.0 rs.Heartbeat:Wait()
		end
	end
end)

Mimicked that light in the video …
You can do may lights this way by just adding more and they don’t mess with runtime.
This is from a modified example.