@gabrielverdon I've always used photo printing places. t.co/2gHMuX8snU is pretty decent, and they seem to work out good for arts. (Today)

RT @rustym: Astro Duel – My competitive local multiplayer game for iPad is live! t.co/PuNpRxw9vR (Today)

RT @McFunkypants: The average fulltime indie gamedev salary is $11,812 a year. But 57% make under $500. t.co/s74fYprMtC t… (Today)

@phubans I guess tennis is fine as long as real life windjammers doesn't exist. (Today)

RT @ColinNorthway: The new game we will announce today. After a year of secret toil: Deep Under the Sky t.co/FQVcOlE06T (Today)

RT @rustym: The Canabalt 2.0 update (which I helped program!) is on @toucharcade t.co/igbaTzpRTH (Today)

@ChevyRay Yeaah I tried json out, and editing it by hand made me go back to XML :I (Yesterday)

@ZeroFolio video games, whoa. ;D (2 days ago)

@alexdawsonca But "whoa" is the one that is said as "w-oh." (5 days ago)

@ADAMATOMIC @BenRuiz advancing guard advancing guardadvancing guard advancing guard advancing guard advancing guard advancing guard advanci (5 days ago)

@ADAMATOMIC @BenRuiz yooooooooooooooooooooooooooooooooooo (5 days ago)

@BenRuiz Vergil vs Vergil Training Stage only (5 days ago)

@BenRuiz ITS MAHVEL BABY (5 days ago)

RT @djcoreynolan: If a kirby came by and sucked you up, what power would he get? (6 days ago)

Dang, major bummer that @bitbucket now enforces hard limits on their repo sizes. Game projects can easily get past 2gb worth of assets. (6 days ago)

@obskyr No you fool woah isn't a word! (6 days ago)

RT @ted_martens: Crypt of the NecroDancer will be out on Steam Early Access July 30th! t.co/Grl2bPwrOu (6 days ago)

@LorenBednar All who approve say yea. (6 days ago)

Everyone talkin' about people saying videogames instead of video games when the real issue is woah instead of whoa. (6 days ago)

@Solidplasma Shoot me an email at hi@kpulv.com. I'm going to be kinda busy this next week, but maybe sometime after that? (6 days ago)

follow
search

2013 - 5 - 11 / 12:13 am / general

Platforming Ledge Forgiveness

Platforming Ledge Forgiveness

When it comes to making a cool platforming game there's all kinds of little tricks you can do to make your game shine above all the rest. I mentioned jump input buffering in a previous post and how silently helping the player out here and there can make a huge difference in the feel of your game. The topic of this post is very similar to that!

Image

Take a look at this typical platforming scenario. Our player is barreling toward a ledge at top speed, just holding right without a care in the world. They're going to want to jump when they get to the end of that ledge, and they're probably going to want to hit jump as late as possible so that they get the maximum distance out of their jump.

Image

Ideally they would hit the jump button right now. Their character is still on the ground, and in the most simple implementation of a platformer jump system then this would be fine. I assume that the code would be just something along the lines of if (onGround) { jump(); } and onGround would evaluate to true if our player collides with the ground at y + 1.

But what happens if the player just slightly overshoots the ledge?

Image

If our most basic platforming system is only looking at the player's y + 1 to detect the ground, then the player will not be able to jump in this case. At this point you might ask well doesn't that make sense? The player isn't on the ground, so they can't jump... that's how it would work in the real world!

Image

This isn't the real world though, this is video games! If you're playing a fast paced platformer running at 60 frames per second, it's incredibly easy to hit the jump button right after you run off a ledge, but to your feeble human eyes it looked like you hit the jump button while you were still on the ground. This can be incredibly frustrating, especially if you're trying to make jumps across some pretty wide gaps and you're trying to maximize your jump distance.

What I like to do for my games for this situation is to introduce a timer that keeps track of how long it has been since the player last touched the ground. I usually refer to it as a jump grace period.

The logic goes a little something like this: First I have a jumpGraceTimer and a jumpGraceTime. jumpGraceTime is a fixed value of how may frames I will allow the player to still have access to their jump after they leave the ground. Usually this is around 3 to 5 frames (at 60 frames per second) depending on the speed of the player and the game. The timer counts down from that value to 0 whenever the player is no longer touching the ground (no collision at y + 1) when they didn't jump. If they did jump, I assume that they are purposely leaving the ground and I don't need to help them, so I set the timer to 0. When the player is touching the ground, that timer is always set to jumpGraceTime, so that it's ready to count down when the ground collision is no longer happening.

Now when I check to see if my player can actually jump or not, I'm actually checking to see if they are on the ground (onGround) or if the jumpGraceTimer is greater than 0. If they indeed can jump, then I do the jump logic and set the jumpGraceTimer to 0 manually. I don't want the player to be able to jump multiple times if they happen to be really good at mashing.

if (jumpInput) {
if (onGround || graceTimer > 0) {
jump();
}
}

//somewhere else in the code:
public function jump():void {
//pretend theres more jumping logic here
graceTimer = 0;
}


You can implement this in any way you want really, but this is just my go to technique! (Edit: Actually I guess I could just check to see if the graceTimer is > 0... but there might be some reason why I'm still checking onGround || graceTimer > 0... I can't remember now, haha!)

So here we go again. Our player runs off the ledge and hits jump just 2 frames after they've left the ground...

Image

But thanks to our jumpGraceTime that allows the player to be off the ledge for 3 to 5 frames before their jump is taken away, they can jump!

Image

And all is right in the world. If you do this right then the player wont suspect a thing. A very popular platformer game that you've probably heard of before (Canabalt) makes use of this technique! If you really try to push the limit, you'll notice that your character can actually be totally off the ledge and still jump as if his feet were on solid ground, but just for a fraction of a second.

Just be careful with how much time you allow the player to have before they can no longer jump. I implemented this in Offspring Fling with a very small timing window and it works just fine. However, we implemented this technique in Snapshot as well, but the timing window might actually be too generous in this case. There are times where you can clearly see Pic falling before you push the jump button, and this can sometimes cause a weird disconnect, or reveal the "man behind the curtain" which can make the player feel a little disrespected.

Little tricks like this that help the player feel more in control can really help your platformer shine! But you don't want to go overboard and baby the player either. Let them roam free and hurt themselves sometimes and learn from their mistakes, but also make sure they don't get frustrated by tiny details like pushing a button too early or too late by fractions of a second (unless we're talking about Street Fighter.)

7 Comments
Avatar

2013 - 5 - 11 3:52 AM

NounVerber

Super meat boy made it so that some characters get an additional air-jump if they walk off the edge.

Avatar

2013 - 5 - 11 6:03 AM

Danik

Good post! I usually do this too for platforming movement. There are some other similar situations that you might want to help the player, for example when the player is jumping under a platform and collides with only one or two pixels, it can be a good idea to nudge him to the side of the platform, especially if it's a fast paced game.
The trick you describe works well in combination with this if the player should be able to jump from a low tunnel exiting out from a wall, without hitting the ceiling too easily, or running off the edge before jumping.

Avatar

2013 - 5 - 11 7:16 AM

bluescrn

Great explanation of these techniques, they really do make a big difference, don't they! - we had jump input buffering in Little Acorns from the start, and actually added a couple of frames of ledge forgiveness for the recent 3DS version, as playing it on 'real controls' made it more obvious that we needed something.

Avatar

2013 - 5 - 11 12:49 PM

Kyle

Thanks!

Also forgive the " or whatever is happening in the post sometimes, got a php function that's acting up somewhere at the moment -_-

Avatar

2013 - 5 - 11 1:45 PM

Cheshyr

I was reading one of the latest xkcd What If's.. http://what-if.xkcd.com/44/ and this kinda clicked for me. The relevant section mentioned "...it takes about five milliseconds for the fastest nerve impulse to travel the length of the arm...". While we're supposed to be anticipating the ledge, there's a certain inherent delay in the execution of our actions in relation in input. Making your jumpGraceTime correspond some portion of 5ms could be a good way to adjust your desired difficulty?

Avatar

2013 - 5 - 12 11:25 AM

Kyle

5ms might be a little too tight, since you are probably not even updating your game that fast. At 60 frames per second, which most games will be capped at, you're refreshing at 16.7ms.

Avatar

2013 - 5 - 12 12:39 PM

tonieprawda

flashback iirc had this wonderful idea of jumping only after the character prepared for it, so you had to hit jump way before the character actually jumped. It was more realistic and more fun!

Avatar

Post your comment!

POST COMMENT

about

About

Hi there, my name is Kyle, and I'm a 27 year old kid with adult powers. I'm making video games and living the indie game developer life in Tempe, Arizona. Here you will find my thoughts, games, websites, doodles, and other stuff like that. I worked on Snapshot, Offspring Fling, and a whole bunch of other games. I also created and maintain Otter, a 2d game making framework. If you want to get a hold of me use the form on the bottom of the page, leave a comment, or just tweet at me. I try to post three times a week. Thanks for stoppin' by! You're the coolest.

facebook

videos

Do you want to make a Let's Play of one of my games, or a just a video featuring footage of my games? You have my full permission to do so! Even if you are monetizing your videos, you still have my full permission to use any footage from any of my games. Go for it!

contact

Your message has been sent! Thanks :)
SEND MESSAGE