Skip to main content
Coding Quests

Jump buffering

Why did my jump get ignored?

  • Platformer feel
  • Beginner
  • 5 minutes
  • No account needed

You press jump right before you touch the ground, and nothing happens. Your timing was fine. The game only checks for a jump on frames where you are already standing, so a press one frame too early is thrown away.

Loading the lab...

No account needed. Nothing here is locked.

How it works

A jump buffer is a short memory. When you press jump, a timer starts. It counts down every physics frame. If you land while it is still above zero, the jump fires. One small timer turns a near miss into the jump the player meant.

Too much of a good thing

A window that is too long jumps after the player has changed their mind. At a quarter of a second it starts to feel like a delayed jump, not a forgiving one. Most platformers stay near 100 ms.

The usual mistake

Forgetting to clear the timer when the jump fires. One press should make one jump. Set the buffer back to zero on the frame you jump.

Use it when: Any time the player presses a button a moment before the game is ready for it. Landing is the classic one. Attacks that end, doors that open and dashes on cooldown work the same way.

The code in Godot

This is the whole trick: a timer that a press fills and every physics frame drains. Names and numbers match the free quest.

Show player.gd
player.gd
GDScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
extends CharacterBody2D
​
const JUMP_VELOCITY = -300.0
const JUMP_BUFFER = 0.10 # remember a jump press this long, in seconds
​
var jump_buffer_timer := 0.0
var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")
​
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y += gravity * delta
​
# Remember a fresh press, then let the memory tick down.
if Input.is_action_just_pressed("jump"):
jump_buffer_timer = JUMP_BUFFER
else:
jump_buffer_timer = max(jump_buffer_timer - delta, 0.0)
​
# Standing, and the press is still remembered: jump.
if is_on_floor() and jump_buffer_timer > 0.0:
velocity.y = JUMP_VELOCITY
jump_buffer_timer = 0.0 # one press, one jump
​
move_and_slide()

It needs a jump action in Project Settings, under Input Map. The free quest adds the buffer to a full controller, next to coyote time.

Build it for real

A lab shows you the decision. A quest has you write the whole system, with every step checked as you go.

Try another lab

All labs

Questions

What is jump buffering?

Jump buffering means the game remembers a jump press for a short time. If you press jump just before you land, the jump fires the moment you touch the ground. Without it, that press is thrown away.

How long should a jump buffer be?

Start at about 0.1 seconds, which is 6 frames at 60 frames per second. Go shorter if jumps fire when players did not mean them. Past about 0.2 seconds it starts to feel like a delayed jump.

Why does my jump not work when I press it right before landing in Godot?

Because the usual check is is_action_just_pressed and is_on_floor in the same frame. A press one frame before landing fails the floor check, and the next frame it is no longer a fresh press. A buffer timer fixes it.

Is jump buffering the same as coyote time?

No, they are mirror images. Jump buffering forgives a press that is too early, before you land. Coyote time forgives a press that is too late, after you run off a ledge. Most good platformers use both.

Does a jump buffer change at low frame rates?

Not in Godot's _physics_process, which runs at a fixed 60 steps a second by default. The timer counts real seconds through delta, so 0.1 seconds is 0.1 seconds on any screen.

The game above is a port of player.gd from the free quest A Jump That Feels Amazing. It uses the same numbers and steps at 60 physics frames a second, like Godot. The collision shape is simplified to a box. Art by Kenney, CC0.

Jump Buffering in Godot 4: Try It in Your Browser | Coding Quests