Making event fire once and only once

How do I make it so it doesn’t fire multiple times? This is the script:

game.Lighting:GetPropertyChangedSignal("ClockTime"):Connect(function()
	if game.Lighting.ClockTime >= 17.7 then
		
		repeat 
		wait(math.random(1,10))	
		game.ServerStorage.Beam:Clone().Parent = workspace
	until
	game.Lighting.ClockTime <= 7.2	
	end
end)

game.Lighting:GetPropertyChangedSignal("ClockTime"):Connect(function()
	if game.Lighting.ClockTime >= 17.7 then
		game.ServerStorage.Happy:Clone().Parent = workspace
	else
		workspace:FindFirstChild("Happy"):Destroy()	
		end
end)

You can also store the connection in a variable and call :Disconnect() on it later.

I forgot to mention that I’m a beginner scripter, and only know basic stuff. What I intended was that when the clocktime hits the designated time range, it would clone the object mentioned through the loop. What’s happening, I think, is that the script keeps detecting the clocktime to be in that range and continues to fire. I think “Once” is only detecting it Once, before the designated time.

1 Like

You want it to only happen once?

Yes, but can still be fired again after the loop stops.

Presumably use :Wait() or :Once() instead of :Connect().

Oh, yeah, it’s in a loop.

why not just do:

if game.Lighting.ClockTime >= 17.7 and game.Lighting.ClockTime <= 7.2 then
	game.ServerStorage.Beam:Clone().Parent = workspace
end

I found another way. I reformatted the script so it runs in a loop to check if the time is at a certain time.

repeat
	wait(0.001)
	if game.Lighting.ClockTime >= 17.7 then
		repeat 
		wait(math.random(1,10))	
		game.ServerStorage.Beam:Clone().Parent = workspace
	until
	game.Lighting.ClockTime >= 7.2	
	end
until nil

Very bad practice to have 2 loops inside of each other, You should reconsider and find better way to do this

Try using while true loop

while true do
    print("Hello World")
    task.wait(1)
end -- Prints "Hello World" every 1 second

I’m still kind of confused on what you’re trying to achieve, but yeah, as said above there’s probably a better solution.

Wouldn’t repeat loops be better for “unconditional” loops since the condition is evaluated after the code block finishes? If you want it to run no matter what, there’s no point in having the condition evaluated first.

Nope, Look at how he is using repeat loop, Thats not how repeat loops are suppose to be used, While true loops are used for infinite-loops, And conditioned loops, His way of using repeat loops is wrong

This is extremely bad practice, Hell, he can even try using PreRender/Heartbeat instead of this.

He can have a check for every frame that passes instead of 0.001 just so the script wont exhaust.

He’s using a repeat loop the exact same way you’d use a while infinite loop…?

(while true do ... end) and (repeat ... until false)

are essentially equivalent unless I’m misunderstanding.

Just like you can do

(while condition do ... end) and (repeat ... until not condition)

Theoretically, using repeat loops for infinite loops would be better from my understanding since it runs the code before evaluating the condition, but it’s quite insignificant anyway.

1 Like

Honestly, In his case i disagree with both methods
Because he can just use RunService to achieve what he is looking for

1 Like
local RunService = game:GetService("RunService")
local Lighting = game:GetService("Lighting")

local RNG = Random.new()

local beamSpawnTime = nil
local startTime, endTime = 17.7, 7.2

RunService.Heartbeat:Connect(function()
	local clockTime = Lighting.ClockTime

	if clockTime < startTime and clockTime >= endTime then
		warn("Already passed the timeline")
		return
	end
	
	if not beamSpawnTime then
		beamSpawnTime = os.clock() + RNG:NextNumber(1, 10)
	end
	
	if os.clock() < beamSpawnTime then
		return
	end
	
	-- Spawn the beam
	print("spawn beam")
	beamSpawnTime = os.clock() + RNG:NextNumber(1, 10)
end)

Try using this one

1 Like

There is nothing inherently wrong with having nested loops. It is very common to write one. However, nested infinite loops have no use case.

(And if you were thinking every computable program, e.g. one with terminating nested loops, can be turned into one with a single loop, then while that is true, it’s not actually practical in real situations.)

The only difference between the two is that repeat executes the loop body before the conditional and while executes the loop body after the loop conditional. Both can be used for infinite loops.

It’s fairly common to use a repeat for an infinite loop when the loop condition requires the existence of a resource that does not exist until the loop body has been executed and having identical code just before the loop or an if branch to handle the first iteration with a while is just awkward.

3 Likes

From my 4-5 years working experience I’ve never encountered people using repeat for an infinite loop, So this is an false statement.

Unless this was a thing in the past but i worked with alot of scripters, From the new ones to more experienced ones and all of them prefer while true do for inf-loops rather than repeat until for inf-loops

Matter of fact, I seen more people using while true loop for inf loops

There is something wrong with nested loop in this case, There is no need to have one at all in @Surnapsian’s problem.

nothing wrong with nested loops but Surnapsian doesn’t even need to use neither of the loops for this, Loops should be used when there is a condition to be met, Otherwise you can use RunService.

If any of the information I’ve provided is wrong, I am sorry :pray:

while true do
  local clockTime = Lighting.ClockTime
  if clockTime < startTime and clockTime >= endTime then
    task.wait()
    continue
  end

  task.wait(math.random(1, 10))
  Beam:Clone().Parent = workspace
end

Here is an example one of my experienced friends wrote, There was no need of nested repeats.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.