Discuss Scratch

crash_bandicam
Scratcher
3 posts

Δ time and Framerate Independent Velocity!

Hello!

I'm working on a project which is starting to feel great in the movement department. I've been developing it and setting the numbers based on playback at 60fps in TurboWarp. I later realized this isn't a great idea, as users can set their framerate to whatever the hell they want and dramatically change the difficulty and playback, so I started reading about framerate independent movement and attempting to implement that.

My tick counter looks like this:


Combined with a test movement script that looks like this…

I get perfectly adequate movement that's tied to the framerate. You can run it at 15fps, you can run it at 144fps, it works.

But the velocity/friction aspect… does not work. The movement with the scripts is binary- either on or off. No matter what I attempt to incorporate the standard velocity calculations (the standard stuff) with delta time, it breaks. At best, the velocity works but scales incorrectly- slippery at low framerates and tight at high frame rates.

Has anybody worked with a framerate independent velocity in their projects? Also, if need be I can upload my current project, but it's basically stripped of all code except for the scripts above.
rdococ
Scratcher
1000+ posts

Δ time and Framerate Independent Velocity!

I'm not sure this topic is in the right category, although I also don't think the folks over at Show and Tell would know what you're talking about

What it looks like you're doing is changing the velocity based on player input, adjusting for frame rate within the velocity variable itself, and then moving by that amount.

First things first, when you change the velocity in response to player movement, you're not taking into account the frame rate. That acceleration is a continuous process, so if the acceleration is being applied less frequently, as it would do if the FPS dropped, the amount you apply should be scaled up to compensate for it.

Then, when you adjust the velocity for the frame rate, you're setting the new velocity to the adjusted amount. This means that on every tick, you're adjusting the velocity for the frame rate, and then on the next tick, an already adjusted velocity is being adjusted again - and then again, and then again… Rather, you should account for the frame rate while actually moving the sprite itself. The velocity variables themselves can be blissfully ignorant of the game's performance, as long as you make sure to correct for it when you get around to updating the sprite's position.

On the topic of friction, here's how I handled it in a frame-independent manner in a game I was working on:

set [x velocity v] to ((x velocity) / ([e^ v] of (([ln v] of (friction) :: operators) * (frame time)) :: operators))
set [y velocity v] to ((y velocity) / ([e^ v] of (([ln v] of (friction) :: operators) * (frame time)) :: operators))

I'm using the ‘e^ of’ and ‘ln of’ blocks here as a workaround for exponentiation (raising a number to the power of another). If that block was available, it'd look like this:

set [x velocity v] to ((x velocity) / ((friction) ^ (frame time) :: operators))
set [y velocity v] to ((y velocity) / ((friction) ^ (frame time) :: operators))

I'm taking the friction factor, and raising it to the power of the time it took for the last frame to run before applying it to the velocity. ‘Frame time’ here is normalized to an arbitrary ‘standard’ of 30 FPS that I picked - of course, you may want to go with 60 FPS for your project.

If ‘frame time’ is 1, meaning that the game is running at 30 FPS, the adjusted friction factor will be equivalent to the standard one. However, say your computer is really lagging, and ‘frame time’ is 2 (= 15 FPS), the friction factor will be squared - in other words, multiplied with itself, and thus essentially applying itself to the velocity twice, which is exactly what you want when your game is only running at half speed. Essentially, I'm “scaling” the effect of the friction value based on the game's performance.

Last edited by rdococ (April 30, 2021 23:07:51)

crash_bandicam
Scratcher
3 posts

Δ time and Framerate Independent Velocity!

rdococ wrote:

I'm not sure this topic is in the right category, although I also don't think the folks over at Show and Tell would know what you're talking about

Oh shoot, you're right! Probably should have gone into Help With Scripts… if any moderators see this, my apologies!

By the way, your explanation was a huge help! I kept accidentally fluctuating between applying it directly to the movement and applying it inside the velocity variable while troubleshooting, but I feel like I've walked away with a better understanding after reading this and looking at that project. You'll be credited! lol

This is the final implementation of the movement script and timer script I went with:





Falonie
Scratcher
2 posts

Δ time and Framerate Independent Velocity!

Hey! I know this is a super old topic, but I was wondering how to add offsets to the smoothing operations? Such as if you where doing a smooth camera that takes in the offset of the player. Thanks!

WojtekGame
Scratcher
1000+ posts

Δ time and Framerate Independent Velocity!

Falonie wrote:

Hey! I know this is a super old topic, but I was wondering how to add offsets to the smoothing operations? Such as if you where doing a smooth camera that takes in the offset of the player. Thanks!


2 years is not that old.

also idk if no necro, but i think no.
Falonie
Scratcher
2 posts

Δ time and Framerate Independent Velocity!

WojtekGame wrote:

Falonie wrote:

Hey! I know this is a super old topic, but I was wondering how to add offsets to the smoothing operations? Such as if you where doing a smooth camera that takes in the offset of the player. Thanks!


2 years is not that old.

also idk if no necro, but i think no.

Ya I guess
Ok I will keep messing with it thanks for the response
op is the goat for those equations though works like a charm

Powered by DjangoBB