All Questions

Community

D
pbrighenti

Stutter

Hello Nathan,

Any clue as to why calling is_on_floor instead of using velocity.y when building the expression that produces the is_jump_interrupted value causes the engine to stutter? Mind you that this doesn't happen with every jump, but it's definitely noticeable.

I understand that doing a function call instead of reading a property is mostly costly, but given this is a very simple game and the physics process loop is not that busy I'm wondering if calling the is_on_floor function for this purpose is strictly incorrect.

Here is what I mean:

var is_jump_interrupted: = Input.is_action_just_released('jump') and velocity.y < 0.0

instead of

var is_jump_interrupted: = Input.is_action_just_released('jump') and velocity.y < 0.0
  • D
    pbrighenti replied

    For some reason I'm not able to edit my question and I have a typo in my first snippet due to copy-pasting it. The first snippet should read as following:

    var is_jump_interrupted: = Input.is_action_just_released('jump') and !is_on_floor()
  • Nathan Lovato replied

    Doing a function call isn't costly, you could easily call a million per second, probably even with GDScript.

    I'm unsure what causes the stutter exactly just like that. Is the character's shaking? Or is it more of a slight freeze or delay when interrupting the jump?

    And it's happening precisely when changing only the velocity check by is_on_floor(), right?

    If so, floor detection with the KinematicBody2D happens when a collision happens with the floor.

    In other words, until you called move_and_collide or move_and_slide(), Godot doesn't detect the character is on the floor, a wall, or the ceiling.

    So sometimes, you need to reorder your code to account for that, making checks after moving the character. But I'm unsure here because that shouldn't cause what I understand of stuttering, that is, some kind of shakiness.

    Would you have more details on the issue perhaps?

  • D
    pbrighenti replied

    It was more like a slight freeze and it happened when I moved the character left and right while it was in the air.

    I can easily reproduce it by:

    • changing the way the check is done from using velocity.y <  0.0 to !is_on_floor()
    • running the level scene
    • spamming left/right + up at the same time.

    if you do this, revert back the changes in the check and do the same thing in-game you'll see that when using is_on_floor in the boolean expression will make it so that you fall slower. Maybe it's not a matter of performance but of the way is_on_floor is implemented. Either way I was not expecting this behaviour.

    Let me know if you can reproduce it as well (if you have the time). This is true for me both in 3.2 stable and on today's RC (3.3 rc7).

    If you want I can get the project in a github repo, but I believe you'll be able to reproduce it by changing the expression I mentioned.

    Cheers

  • Nathan Lovato replied

    I just tested the code and now I understand. I was thinking the code was from a different project, my bad.

    So it's just that the condition you're using doesn't do anything because the character is not on the floor when the jump interruption comes into play. The expression:

    !is_on_floor()

    Is always true while the character is moving in the air (it's not on the floor)

    In other words, it's about the same as writing:

    var is_jump_interrupted: = Input.is_action_just_released('jump')

    We need the extra condition checking the Y velocity because we don't want to run the code that interrupts the jump when the character is already falling.

    And we don't want to do that because it causes that little stutter you observed, as the code resets the character's vertical velocity on a given frame.

    Please let me know if that helps and if this was the issue you noticed. I couldn't notice any other in the project.

  • D
    pbrighenti replied

    Ah, I see. Thanks, that settles it.