The Importance of Delta Time (Part 1)
Despite our best efforts, Quantum Caverns is not locked at 60 fps on the GameShell. Based on some initial prototyping, the fps fluctuates anywhere between 40-60 fps when on the GameShell. Now this shouldn’t be a problem, but due to some naive programming on my part, this is actually game breaking.
See for yourself. This is the player jumping when the game is locked at 60 fps on my computer.
This is fine, but check out what happens if I lock the framerate to something else like 30 fps.
Notice how the player hits his head on the ceiling in the second GIF. The physics behind the player’s jump is not consistent across different frame rates. As mentioned earlier, on the GameShell Quantum Caverns is running anywhere between 40-60 fps in any given level depending on the complexity of what is on screen. In other words, the player jumps higher when there are more blocks on the screen.
This is bad.
Given the title of our game, I could just make this bug a feature! PROBLEM SOLVED. It all makes sense right? There are uh some quantum mechanics at play in this cave . . . so that’s why the player jumps at variable heights . . . and did I mention he sometimes falls through the world . . . perfect right? Well I’ll admit, that could be an interesting mechanic, but that wasn’t what we were going for so it must be fixed!
Now right off the bat, a lazy fix could be to just lock the game’s frame rate at 30 fps. I have yet to see the game dip anywhere near that when ran on the GameShell. This is a valid solution, but the game feels extremely sluggish at 30 fps so this solution is out the window.
Well then what do we do?
The solution to this problem revolves around the concept of delta time, which is simply the amount of time in between updates. This is a very important concept when it comes to game development and programming in general. Fundamentally, anything involving motion should be multiplied by delta time. This will insure that regardless of the hardware of the computer and how fast it can run your game, movement will always be consistent.
This concept is very trivial, but it introduces something new for the all ready stressed out developer to manage, and for that reason alone is quite often neglected.
While we are on the topic, I would like to give a shout out to Skyrim and Fallout 4 just to show AAA companies make these mistakes too!
Anyways, here is an example on how to apply this concept to your game.
Consider the code below that moves the player horizontally 100 pixels every frame.
location = Vector2(0, 0)
location.x += 100
If the game is running at 30 fps, then this will be applied 30 times in 1 second. So the player will move 3000 pixels in 1 second.
30 * 100 = 3000
If the game is running at 60 fps, then this will be applied 60 times in 1 second. So the player will move 6000 pixels in 1 second.
60 * 100 = 6000
You can tell this discrepancy only gets worse the higher the fps gets, but we can solve this by bringing delta time into the equation. Our new update method looks like this.
location.x += 100 * delta_time
(I should note that delta time is just
(1 / frame_rate). Usually your game engine should have this value calculated somewhere for you to use).
If we try out the code now, the player moves 100 pixels in 1 second no matter the frame rate. Multiplying by delta time cancels out the discrepancy.
30 fps Calculation:
delta_time = 1 / 30.0
30 * 100 * delta_time = 100
60 fps Calculation:
delta_time = 1 / 60.0
60 * 100 * delta_time = 100
Okay so now the player moves horizontally consistently across different frame rates, so now all we have to do to get the jump to work is multiply his jump height by delta time right? Well, it’s actually not that easy.
In the case of Quantum Caverns the player jumps in a parabola. This is a result of giving the player an initial velocity and reducing its velocity by gravity every frame. This is how that looks like in code.
gravity = 10
jump_velocity = 100
velocity = Vector2(0, 0)
location = Vector2(0, 0)
velocity.y = -jump_velocity
velocity.y += gravity
location.y += velocity.y
We need to change the update method to use delta time, but what exactly needs to be multiplied by delta time in the first place?
In part two of this post I’ll over complicate all of this and lay down some calculus and physics to show you a solution to this whole ordeal, explain why this code works in the first place, and show you a couple of ways to use the physics behind this to improve your platformer jump code. Stay tuned!