How do I make my timers framerate independent?

So I’ve been dealing with a ton of inconsistencies between my debug and my packaged builds. And I am assuming this is because my code is framerate dependent, and packaged builds have a higher framerate, ergo:

The problem is I’m not finding any good examples online on how to fix these. I see folks say to multiply the speed floats by deltaspeed, but they only use math equations and as a Grade A Doofus I really need to see what the blueprints look like here.

Current Setup for my slide-over/vault logic:

This is the logic that actually moves the player during this loop.

I’m assuming if I can fix this, the solution can be ported over to my other timers too (I have a lot of them).

Any assistance with this would be greatly appreciated!

Timers/Delays are not millisecond accurate. They do checks each “tick” to evaluate if the given time has elapsed.

Tick 1 deduct deltaseconds. Is remainder < = 0
Tick 2 deduct deltaseconds. Is remainder < = 0
etc

The higher the FPS the more accurate they get.

1 Like

So if I’m trying to get the behavior to be more consistent, what should I do? Is there an alternative way to loop things without using a timer or delays?

What Netmode are you running?
Turn on debug corrections. Net.ShowCorrections

You should step away from timers and use the tick function instead.
Running timers every 0.01 second is almost equivalent to the tick.

Now, to have things consistent, this is where you need to use DeltaTime.

Its common practice to take delta time into account when computing velocity / location data inside the movement code.

For instance velocity v = delta_x / delta_time

It’s pretty crucial that you understand this principle, otherwise your logic will be very different based on the power of the machine running your game..

1 Like

I am not sure how. I enter “Net.ShowCorrections”into the CMD and nothing seems to happen? I can't find the relevant documentation on this command either. Could you clarify?

Aw man, I was told to have less things on event tick.

As for using DeltaTime, could you provide me a blueprint example of how it’d be used?

That’s a very common misconception.
Tick is not bad, its the workload that matters.

For instance the entire Movement Logic of your Character actually runs even multiple times per tick.
Something as crucial as movement should and is allowed to take up resources!

To give you an example I would need to know a bit more about your BP, what is your “Slide Over Curve” supposed to be?
Also why do you directly modify the location of the actor instead of writing to the velocity of it?

However, technically speaking, after you calculated your delta movement vector, you should multiply that result by delta time.
Just note that you will find yourself moving at very slow speeds suddenly as the delta time mostly is a very small value.

1 Like

My bad it’s p.NetShowCorrections

The slide over curve is just a curve, it affects the rate of change for the alpha, allowing it to vary over the course of the slide-over event (The rate of change decreases near the end). I think we’re not setting velocity because of gravity (we disable it for the slideover event). But assuming this was just setting the velocity, could you provide an example of that? I’m not opposed to rewriting this to use velocity instead, but I’m not sure how to go about calculating any of these delta values, and I think a blueprint graph could help me figure it out.

I used that command but I’m not seeing any changes here. Looking at the documentation, I think this might be for multiplayer games? Or can a singleplayer game also be networked?

p.NetShowCorrections is to show visual differences/errors between server and client.
I don’t see how that is related to your topic

This would be an extremely simplified approach of having frame-rate independent velocity/acceleration.

Its all just physics…

Just note that you technically shouldn’t modify movement logic outside the CMC and instead build custom movement modes.

Ah, so we just multiply the final vector by Get World Delta Seconds. That’s way easier than I was imagining. I’ll try to implement this and we’ll see if it works!

1 Like

No dice, it still behaves super differently. Works well enough in editor but the velocity is way too slow in a packaged build.

Rewrote slideOver to update velocity:

And here’s where I’m calculating the velocity:

You need to decide which way you want to be going with.

Either writing to the CMC’s velocity or directly updating the players location.
(I see you’re doing both at the moment)

Also if you want to test how it behaves on different framerates you can run the commandt.MaxFPS <num_fps>.

Just note that both things are generally considered “bad practice”.
You might want to look into MOVER as it has more blueprint exposed functionality for movement code if you don’t want to write cpp.

This code is no longer looping, it instead teleports the player up a set amount, disables gravity, then attempts to apply their previous velocity again to move them forwards. I am not sure if there’s a clean way of getting the player high enough off the ground for them to clear the obstacle. I’ll look into Mover, but I’d really like to know where the flaw in my calculation is.

If you want deterministic movement you need to substep your calculations. The game framerate will vary depending on performance which fluctuates the delta time. Naive integration (pos += vel*dt) becomes unstable as dt becomes larger (see visual examples of euler integration, verlet integration, runge kutta, etc). This is a numerical reality of physics simulations that we cannot get away from when we do not have an exact analytical solution.

For deterministic calculations you need at least to ensure the delta time is at a fixed rate, for example 60 hz, 100 hz, etc. Naively this is done by adding a loop in your tick that “consumes” the fixed deltatime from the frame delta time N times until you have no remaining dt left.

Instead of going through all this hassle (unless you enjoy learning about it), follow the advice by @MajorT and look into the existing movement components in the engine. Not necessarily to use them, but you can reference the source code to see how Epic handles the math.

1 Like

My bad, I was still in multiplayer brain mode. Wanted to see if server corrections where adding to the problem.