[Godot] _process vs _physics_process: Choosing the Right One

Created: 2025-12-10Last updated: 2026-07-07

The difference between _process and _physics_process, the basics of variable and fixed timesteps, and best practices for choosing between them.

Introduction: Why This Distinction Matters

Everyone who starts building with Godot Engine meets _process and _physics_process early on. And most people run into problems like "the character moves faster on a beefier PC," "movement looks choppy," or "sometimes objects pass through walls."

Almost all of these come from not understanding the roles of _process and _physics_process and putting logic in the wrong place. This article breaks down the difference between the two functions at the heart of Godot's game loop.

Two game-loop lanes: one running at a steady rhythm and one with irregular gaps

What You'll Learn

  • The difference in how they're called: _process (variable) vs _physics_process (fixed)
  • Using delta correctly so game speed doesn't change with PC performance
  • A character movement pattern that separates input, physics, and visuals
  • The physics interpolation setting that eliminates jitter
Sponsored


_process vs _physics_process: The Core Differences

The most important difference between the two functions is when and how often they're called. This maps directly onto the game development concepts of "variable timestep" and "fixed timestep."

Aspect_process(delta)_physics_process(delta)
When it's calledEvery frame (every draw)At a fixed interval (every physics step)
TimestepVariableFixed
Call frequencyDepends on PC performance and load (e.g. 60 FPS, 144 FPS)Depends on project settings (default: 60 times/second)
The delta argumentElapsed time since the previous frame (varies)Time between physics steps (constant)
Main usesUI updates, input polling, visual effects, non-physics animationPhysics, collision detection, timing-critical logic
Comparison of when _process and _physics_process are called. The gaps between _process calls vary with FPS, while _physics_process is always regular (60 times per second)
  • _process: called every time the screen updates, so it suits anything visual. Its interval is unstable, though, which makes it unsuitable for precise work like physics.
  • _physics_process: called at a constant interval regardless of frame rate, which guarantees reproducible physics-based movement (the same result no matter when or on whose machine it runs).

Here's the mental model: the parts players see and touch belong in _process, and the physical laws of the game world belong in _physics_process. When in doubt, come back to that mapping.

Concrete examples. _process handles gamepad input, UI updates, and visual effects, while _physics_process handles move_and_slide and collision detection
Sponsored

Common Mistakes and Best Practices

Understanding the theory doesn't stop you from slipping up in practice. Here are specific mistakes paired with the best practices that fix them.

Common MistakeBest Practice
Running physics (move_and_slide) in _process.
→ Behavior becomes frame-rate dependent and unstable.
Always run physics in _physics_process.
→ You get reproducible, stable physics behavior.
Adding values in _process without using delta.
→ Game speed changes with PC performance.
Always multiply by delta for time-based work in _process.
→ You get a uniform speed independent of frame rate.
Polling input (Input.is_action_pressed) in _physics_process.
→ Inputs get dropped and controls feel sluggish.
Poll input in _process or _input and store the result in member variables.
→ Input is detected every frame, which feels smooth.
Updating visuals (UI, effects) in _physics_process.
→ It doesn't sync with rendering, which causes jitter.
Do visual work in _process.
→ It syncs with the draw frame for smooth visuals.

Here's what delta does, as a diagram. Because per-frame movement is automatically scaled by speed * delta, the distance covered in one second is the same at high FPS and low FPS.

The effect of speed * delta. A high-FPS PC takes many small steps and a low-FPS PC takes fewer large steps, but both end up in the same place after one second
Sponsored

Practical Code: Character Movement

Let's look at character movement code that follows these best practices. The key is properly separating input, physics, and animation.

extends CharacterBody2D

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

# Gravity as computed by the physics engine
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var input_direction = Vector2.ZERO
var jump_requested = false

# 1. Input: runs every frame and only stores input into variables
# _input() works too, but _process is more intuitive for continuous input
func _process(delta):
    # Read horizontal input
    input_direction.x = Input.get_axis("move_left", "move_right")

    # Jump input is only recorded as a flag (physics applies it in _physics_process)
    if Input.is_action_just_pressed("jump"):
        jump_requested = true

    # Visual work (e.g. updating animation)
    update_animation()

# 2. Physics: runs on a fixed timestep
func _physics_process(delta):
    # Apply gravity
    if not is_on_floor():
        velocity.y += gravity * delta

    # Consume the stored jump input here
    if jump_requested and is_on_floor():
        velocity.y = JUMP_VELOCITY
    jump_requested = false

    # Set horizontal velocity from the input direction
    velocity.x = input_direction.x * SPEED

    # Run the physics
    move_and_slide()

func update_animation():
    # Put visual code here, such as updating the animation tree
    pass

In this code, _process handles smooth input detection and animation updates, while _physics_process focuses on stable physics (gravity and movement). The key point is that jump input is "recorded" in _process and "consumed" in _physics_process. Physics state like velocity is only modified inside physics steps. Keep that separation and you avoid dropped inputs and unstable physics at the same time.

Sponsored

Performance and Advanced Topics

Smoother Motion with Physics Interpolation

When physics runs at 60 times per second but rendering runs at 144, the difference in frequency makes objects look choppy. That's jitter, and physics interpolation solves it.

Enable this feature and the engine automatically interpolates positions between physics steps, drawing them smoothly on render frames.

  • How to enable: turn on Project Settings > Physics > Common > Physics Interpolation.

For games where the camera follows a character, this setting is essentially mandatory.

Input in _input() vs _process()

Besides using Input.get_axis() inside _process(), you can handle input through the _input(event) callback.

  • _input(event): called the moment an event occurs, such as a mouse click or key press. It suits one-shot actions (opening an inventory, firing a weapon).
  • _process(): better for checking continuous state. Movement code that checks "is the key still held down" with is_action_pressed() is more intuitive here.

Both are valid; using each for its intended role makes your code's intent clearer.

Sponsored

Summary and Next Steps

Choosing correctly between _process and _physics_process is one of the first and most important steps in Godot development. Get into the habit of asking yourself: "does this need physical reproducibility, or visual smoothness?"

Now that you've got the basics, here's what to tackle next.

  • Signals: a powerful system for keeping nodes loosely coupled.
  • AnimationTree: blends multiple animations and manages complex character states.
  • Custom resources: create reusable data sets like weapon stats and character parameters.

Learning these concepts will make your Godot projects considerably more scalable and easier to manage.