How Would I Avoid Using a While Loop in This Script?

I heard that while loops are bad for memory, so I want to know if there is a way I can change this script to not use a while loop.

minutesAfterMidnight = 6 * 60

while true do
	minutesAfterMidnight += 1
	game.Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
	wait(.3333)
end

Use RunService this is how I would script it

game:GetService("RunService").Heartbeat:Connect(function()
    --code here
end

But that does something every frame. I want it to do something every 1/3 of a second.

I don’t think that’s necessarily the case assuming that you’re not doing a ton of logic within the loops, but I could be wrong :man_shrugging:


Heartbeat’s only parameter is step or delta time. Pretty much the time between the current and last frame.

We can create an elapsed variable and add the deltaTime in order to determine how long has passed

Here’s what I would do:

local RunService = game:GetService("RunService")

local elapsed = 0
RunService.Heartbeat:Connect(function(deltaTime)
    elapsed += deltaTime -- adding to our time
    if elapsed < .3 then return end -- guard clause, ends the code here if under .3
    elapsed = 0

	minutesAfterMidnight += 1 -- rest of the code
	game.Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
	wait(.3333)
end)
2 Likes
local run = game:GetService("RunService")

local delay = 1
local now = tick()

run.Heartbeat:Connect(function()
  local now2 = tick()
  local diff = now2 - now
  if (diff >= delay) then
    -- do stuff
  end
  now = now2
end)
1 Like

Although this while loop is not really subject to any bad memory usage, we can swap it for a function called on RunService.Heartbeat. Heartbeat can also be more “accurate” as it runs on a 60hz framerate as opposed to wait (as well as spawn and delay) on 30hz.

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

local minutesAfterMidnight = 6 * 60
local t = 0
local waitTime = 1/3

local function onHeartbeat(dt)
	t += dt
	if t > waitTime then
		t -= waitTime
		minutesAfterMidnight += 1
		Lighting:SetMinutesAfterMidnight(minutesAfterMidnight)
	end
end

RunService.Heartbeat:Connect(onHeartbeat)

@p49p0 's code is close but should compare the total time passed instead of the difference in time from last call, which is already given by the Heartbeat event, voiding the need for tick().

6 Likes