I implemented some very simple code from a tutorial to add some variable jump height to my 2D platformer. Here's the jump and fall code specifically:

#JUMP
	if is_on_floor() and Input.is_action_pressed("jump") and !isAttacking:
		velocity.y = -jumpForce;
		stateMachine.travel("Jump");
	if Input.is_action_just_released("jump") and velocity.y < 0:
		velocity.y = 0.5;
		
#FALL
	if velocity.y >= 0 and !is_on_floor() and !isAttacking:
		stateMachine.travel("Fall");

This generally works, but it feels like if the player performs a short hop, they stop right where they are and immediately go to their falling state, which in turn makes it feel like gravity is really dragging them down. What I'm wondering is, how do I add a bit of leeway to that (for lack of a better term)? Like, if the player lets go of the button, they should still ascend for a little bit before going downward. I know it has to do with the line that sets my velocity to 0.5, but I'm unsure how to make do specifically what I'm asking.

I'm trying to go for a game feel similar to the Kirby or Shantae games, if that helps at all.

And because I'm wondering and never looked into it: does velocity in this case only go between 1 and -1?

This generally works, but it feels like if the player performs a short hop, they stop right where they are and immediately go to their falling state, which in turn makes it feel like gravity is really dragging them down. What I'm wondering is, how do I add a bit of leeway to that (for lack of a better term)?

What you can do is multiply the current Y velocity if the player releases the jump key early and the Y velocity is still negative (which means the player is still in the upward phase):

if velocity.y < 0:
    # Keep 50% of the original Y velocity.
    velocity.y *= 0.5

This is how I handled it in the 2D platformer demo. There are perhaps better ways to go around it, but this solution is easy to apply.

@Calinou said: What you can do is multiply the current Y velocity if the player releases the jump key early and the Y velocity is still negative (which means the player is still in the upward phase):

if velocity.y < 0:
    # Keep 50% of the original Y velocity.
    velocity.y *= 0.5

This is how I handled it in the 2D platformer demo. There are perhaps better ways to go around it, but this solution is easy to apply.

This works perfectly! Thank you!

If I may also ask (I know it's not part of the original question, but why not), there's a little too much hangtime between ascending and descending where the player is suspended in the air for about a full second. Is there a way to adjust that?

there's a little too much hangtime between ascending and descending where the player is suspended in the air for about a full second. Is there a way to adjust that?

I guess you could adjust the player's gravity scale during the jump. This can be either based on time since the jump was initiated, or based on the current Y velocity.

@Calinou said: I guess you could adjust the player's gravity scale during the jump. This can be either based on time since the jump was initiated, or based on the current Y velocity.

How can I go about doing that? I tried making some adjustments at the end of the jump statement, but I got mixed results to say the least.

a year later