RunService.Heartbeat switching to variable frequency

The frequency of Heartbeat is the same as the framerate. If your game slows down, so will Heartbeat. The step argument from Heartbeat tells you how much time it’s been since the last frame, so if you have time-dependent things you can multiply by step to make sure they stay consistent.

but i don’t bind things to heartbeat… just

while true do
runserv.Heartbeat:wait()
end

:c gonna have to get used to this new function stuff aren’t I?

That’s basicly the same (during-which-phase-of-a-step-wise)

Yeah, try something like
function foo(step)
--blah blah blah
end

RunService.Heartbeat:connect(foo)

I prefer Heartbeat:wait(), as you’ll only use one thread that you yield.
If you use :connect(), it’ll spawn a new thread every time it fires.
(Not that you should car too much about performance in ROBLOX though)

Somehow I don’t think that’s true, but I don’t really know enough to dispute it…

> x = Instance.new("BindableEvent")
> x.Event:connect(function() print(coroutine.running()) end)
> x:Fire()
thread: 0D1325B4
> x:Fire()
thread: 0D1325B4
> x:Fire()
thread: 0D1325B4
> x:Fire()
thread: 0D1325B4
> y = Instance.new("BindableEvent")
> y.Event:connect(function() wait(5) print(coroutine.running()) end)
> y:Fire()
> y:Fire()
> y:Fire()
thread: 0D132714
thread: 0D132874
thread: 0D132454

Well what do you know, looks like the event system re-uses coroutines (“threads”) when it can.

Only seems to happen if the function doesn’t yield and doesn’t error.
This is definitly something weird and unexpected, never knew that happens.
(Which makes me wonder for some sandboxes that use coroutines for data storage or identification…)

One more wrinkle to keep in mind from a game design perspective: you aren’t running your game on just one client at a particular frame rate, but across multiple clients which potentially have varying frame rates.

If you put game logic in methods bound by the local frame rate you will have players who are literally playing the game at different speeds (and a server trying desperately to interpolate between these different states). Imagine 10 people playing Tetris at 3 different speeds all on the same game board, it can cause all kinds of strange issues.

In short: separate your display logic from your game logic and have the game logic bound by time while the display logic is bound by framerate.

1 Like

I think it would be appropriate to adjust this wiki article:

It still says 1/30th of a second, it should probably include something about it being linked to FPS now.

@ProfBeetle: Yeah, both the RenderStepped and Heartbeat events have an argument that indicates the time since the last event, so people should definitely be using those values and they shouldn’t assume the passed time is always 1/60s.

2 Likes

Done, thanks for the suggestion.

@zeuxcg

Phantom Forces just switched to using heartbeat for all game logic and third person player animations, while keeping renderstepped for first person animations and camera movement.

We want to know whether this has helped improved performance for anyone, and whether the load in each frame has been reduced or not?

My computer is most likely too powerful to notice any appreciable difference.

I’m not gonna lie I just started lagging recently on my $1200 gaming PC.

I’ve NEVER lagged before that. I’m not saying it was that change, but I am saying it never lagged before on my i5 6600+16GB Ram + R9 390.

I get occasional lag spikes, not 24/7 FPS drops.

2 Likes

If devs are encouraged to put logic in heartbeat and rendering in renderstepped, what purpose does stepped have?

Right now in my vehicle physics code, I use stepped for all of the physics calculations.

1 Like

Post can’t be empty.

Your chosen quote fails to answer the question.

Stepped is for when you want things to run before the physics simulation. Heartbeat is for things you want to run after the physics simulation.

Stepped runs after the humanoid and before physics. That means that you can get noncollidable characters by setting each part’s CanCollide to false on Stepped.

afaik that’s the only major use case for Stepped that can’t be substituted or done better by Heartbeat, unless there are other physics-affecting behaviors that get overwritten by humanoids.

Updating your car in Stepped means that it’s using old physics data from the previous frame. Just use Heartbeat.

1 Like

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