I hate fiddling with meaningless magic numbers trying to get a behaviour right. I prefer a bunch of knobs with predictable effects. So I made this little tool for fine tuning variable-height jumping behaviour for platformers.
Note: As written, it's possible for the cart to get stuck in an infinite loop for certain values so read below on how to, hopefully, avoid that issue.
- Up/Down to select a value
- Left/Right to modify the value
- X to test the jump, tap for small jumps, hold for higher jumps
There are three tunable values and a fourth value which is calculated for you and can't be changed manually. Once you get something you're happy with, note down the values, and use or modify the jumping code from this cart in your own project. I think I've clearly indicated all the parts of the code that can be deleted and which parts should be modified. If you do use it, attribution is appreciated but not necessary.
The tunables are pretty self-explanatory. They are:
- initial acceleration
The fourth value, alpha, is calculated based on the other three.
This should be a negative number (upwards direction) in pixels. It's actually more like "requested height." Depending on the other values there is a certain amount of error in the calculations so the maximum height of the jump won't be exactly the height you specify but it should be close.
This should be a positive number (downwards direction). Technically, the units are pixels per frame per frame but that doesn't really matter. As you'd expect, this controls how fast you fall. Higher values make you fall faster; smaller values, slower.
This should be a negative number (upwards direction). This is the upwards acceleration of the character when you press the jump button. While you're holding the jump button, this acceleration slowly decreases until the character is once again only under the influence of gravity. If you let go of the jump button before the jump reaches its full height, the acceleration is cut immediately and the character starts to fall sooner.
Alpha is calculated from the other three values and controls how quickly the initial acceleration decays.
Given the specifics of the physics, it turns out that alpha can't be determined analytically: There's no nice simple formula for it. Or maybe there is and I'm just not patient enough to grind through the equations to figure it out...Anyway, it can be solved computationally, essentially using a binary search algorithm. Which is fine except that PICO-8's limited floating point precision as well as the way lua handles division by zero (turns out 0/0 = 32768, take that math!) means that the algorithm sometimes gets stuck in an infinite loop because it can't find a good enough solution.
Gravity and initial acceleration should have similar magnitudes, just in opposite directions. The greater the difference between them, the more error creeps into the requested height. Basically, if the difference is too great then once the upward acceleration cuts out, it takes longer for gravity to slow the character down and it over-shoots the target height. The closer the two are in magnitude, the closer to the target height you'll get. However...
Though it is by no means obvious, when gravity and initial acceleration have the same magnitude the code which calculates alpha will try to divide by zero and the program won't be able to find a suitable solution. But it'll keep trying. Forever.
PICO-8's limited floating point precision means that this actually become a problem when gravity and initial acceleration are even close to being the same magnitude. If gravity = 0.3 and acc=-0.3, that's going to cause problems.
In general, gravity and acceleration should be close to the same size (but in opposite directions) if you want accuracy in height but not too close or the cart will freeze up.
This is only a problem when calculating alpha based on the other values. When you copy/paste the code you'll just assign alpha and can tweak the other values to be as close as you want.
[Please log in to post a comment]