Jump Input Buffering

Jump Input Buffering
Yesterday I updated Super Ninja Slash with a few tweaks, including the addition of jump input buffering. I talked about this a little bit on Twitter, but due to the 140 character limit I think I might've caused some confusion as to what I meant by jump input buffering.

First what I mean by input buffering is allowing the player (or any source of input) to input commands into the game and allow those commands to be effective for a short window of time after they are inputted. In the case of jump input buffering, the goal is to allow the player to input the jump button and still have a successful jump even if they mistimed their input by a tiny amount.

I made some doodles to try and illustrate what exactly is going on. Imagine that this is some typical platforming game.

Image


That pink box is the player descending from a jump that happened a little while ago. Imagine that in this scenario the player wants to immediately jump again after they touch the ground, so they try to push jump as soon as they touch the ground...

Image


They push the jump button here! Oh no, they actually pushed the jump button right before they touched the ground. This is a problem because in this example, my platformer jumping code is basically just "if player is on ground, and player pushes jump, then jump!" Since they are not on the ground, that code won't fire. Instead of jumping, they land on the ground like so.

Image


This sucks! As far as the player can tell, they pushed jump at the right time. With the game running at 60fps, they would have to hit a frame perfect timing of 1/60th of a second to actually jump on the very first available jump frame. If this were a game that had a big speed running element, then this would be pretty tough to consistently pull off, and I don't want the player to have to grab a frame perfect input just to jump as soon as they can.

To fix this I can buffer the jump input. This is just fancy speak for having a short timer variable that acts as the jump input instead of a boolean. When the jump input is pressed, set a timer to an amount of your choice. In the case of Super Ninja Slash, it's 6 frames of buffer time. When that timer is greater than 0, count it back down to 0. Now instead of checking to see if the player has pressed jump, I check to see if that timer is above 0. I also set the timer back to 0 if the player is not holding down the jump button at any time. If the player successfully jumps, I set the timer to 0 as well.

With this new system, the example now looks like this.

Image


Image


Awesome! The player now jumps again as they would expect in their brain. The key of making this work well is to choose a timing window small enough that the player does not really notice the helping hand that the game is giving them.

I make use of this technique in Offspring Fling to help make speed running levels a little bit easier. When playing Offspring Fling I found that the best runs of levels were when the player could jump on the very first available frame of a legal jump, however the timing of hitting that frame perfect was way too tough to get consistently. The jump input buffering helped a lot and in my opinion made speed running levels a lot more fun and consistent.

Jump input buffering is NOT when you jump again simply because the player is holding jump. You definitely want to have a small timing window for this, and only jump again if the player has PRESSED jump again. If you simply jump again while the player is holding the jump button, it can feel pretty goofy mostly because the jump action is now disconnected from the input. You want to avoid feeling that disconnect when adjusting your timing window for the buffering.

I hope this clarifies my tweet a little bit!

Comments

Matt Thorson
Matt Thorson
There's also a complimentary technique: letting the player jump a few frames after running off a ledge (even though they're technically no longer standing on solid ground). Sorry if I just spoiled the next blog post!
Posted April 4th 2013 2:15 PM
Greg Lobanov
Greg Lobanov
I..... never actually thought to do this before, despite having made a bunch of platformers. Good technique!
Posted April 4th 2013 2:26 PM
Kyle
Kyle
MATT!! Actually I was going to mention that, but decided not to in this blog post since I didn't want to distract from the topic at hand. I'll cover the ledge jumping in another post :)
Posted April 4th 2013 2:48 PM
Federico Fasce
Federico Fasce
Totally awesome.
Just a question: you said that you set the timer at 6 frames time.
Wouldn't it be better to set it in a time-dependent/frame-independent fashion?
So, no matter the speed of the computer you only have that "grace time" to jump.
Posted April 5th 2013 12:20 AM
uffle
uffle
Frederico in my experience console-style action games tend to live and die by the frame counter. If you're not reliably drawing to speed there are going to be a whole lot of problems with responsiveness, and mixing frame-dependent calculations with delta-time stuff is likely to cause more issues than it might theoretically solve. Not really worth it, in my opinion.
Posted April 5th 2013 1:07 AM
Fedyfausto
Fedyfausto
i've send you an email with my project :D
Posted April 5th 2013 2:46 AM
Miguel Gonzalez
Miguel Gonzalez
Awesome article! I never had that kind of problem but I'm gonna use this technology in my next game.
Posted April 5th 2013 3:57 AM
Kyle
Kyle
@Federico Fasce: That would apply if I was using a dynamic framerate, but for all of my games I use a fixed framerate of 60fps, so that I can do math with frames. It's just my personal preference to use a fixed frame rate, but if you were using delta time you'd probably want to use milliseconds instead of frames to determine your window.
Posted April 5th 2013 11:10 AM
Will McCullough
Will McCullough
I found this article to be really great. The implementation is dead simple and it works excellently (I couldn't help but test this out for fun!).
Posted April 20th 2013 8:51 PM
James Liljenquist
James Liljenquist
Now you're jumping with Pulver. Kyle Pulver.

Thanks for this. Blew my mind!
Posted May 6th 2013 6:08 PM
MFcoffee
MFcoffee
Not really crazy about making platform games, but I had to admit this article made a great point and suggestion, definitely a good read regardless.
Posted March 18th 2014 10:15 PM
Nick Yonge
Nick Yonge
This info still remains super rad and handy! Just came across this and used the same method for a tile-based action game. It takes about 0.5s to move from one tile to another, and if the player tries to move during that time the move gets queued for when they're finished moving on the one tile.

So good :D
Posted March 18th 2016 2:06 AM
Kyle
Kyle
Yay awesome!! :D
Posted March 23rd 2016 9:49 AM
new comment!

Post your comment!

Name
Email
Comment