Possible to run a function every amount of frames?

Is it possible to run a function say like, every 30 or 60 frames per second? Is there a way to log what frame a player is currently on?

1 Like

You can use RunService.Heartbeat: RunService.Heartbeat (roblox.com)

That fires every frame, it doesn’t help with what trying to find what frame I’m currently running.

Just make a variable that keeps track of the frames and when the frames reach 30 or 60 reset the variable back to 0

How would I do that though? My problem right now is people will FPS unlock and cause lag by firing this function faster than needed. How would I check it precisely without worrying about client FPS.

Also to reiterate what I mean, if I just write a number variable called frame and add 1 until it reaches 60 then set it to 0, it would run 30x faster at 240 fps.

Heartbeat fires 60 times a second or per frame render if someone had 60 fps, regardless of client FPS

Devforum wiki says it runs every frame, and proceeds to say if you’re at 40 fps it’d run 40 times per second. I’ve also done testing with it, it does run faster and fire the functions faster if you unlock.

Then you could just compare the last timestamp with the current timestamp (os.time, os.clock, whatever). Lets say you want to run the function every 60 frames and the standard fps is 60 so you would just run the function every second. if currentTime - lastTime > 1 then func() end. I don’t think there’s another way to do this

Running a function every 30 or 60 frames per second is not guaranteed depending on the user’s hardware. The best way to go about this is to have a time variable get increased by deltatime and a separate variable incrementing every frame.

If the frames hit 30 ~ 60 and your time variable hasn’t reached 1 second yet, run the function. If the time variable has hit 1 second before the desired frame count, you could run the function. Both variables get reset when the function is run.

To calculate the frames per second, you just need to devide the frames rendered by the time passed. Every second that passes, just display framesrendered / 1. Display the result, then reset the framesrendered and recalculate the next second.

Could using tick() also work with this method?

Yes most definitely but you probably shouldn’t use it since it will be deprecated soon

local Last = 0
game:GetService'RunService'.Heartbeat:Connect(function()
	if os.clock() - Last >= 1 then
		print("Delta", os.clock() - Last)
		Last = os.clock()
	end
end)

image

If you are using HeartBeat or any Runservice events you can use an accumulator to guarantee the rate at which the code is run. If you do then using tick() is not necessary as the event returns the delta time for you to control rate.

This tutorial should help:

-- Step is the time elapsted between the last heartbeat and current heartbeat.
local StepsNeeded = 0.1 -- Idk how many seconds one frame has
local TotalStep = 0
RunService.Heartbeat:Connect(function(Step)
  if TotalStep < StepsNeeded then 
    TotalStep += Step
    return
  end
  TotalStep = 0
  -- Do stuff here
end)
2 Likes