【Godot】When to Use _process vs _physics_process in Godot

Created: 2025-12-10

Learn the difference between _process and _physics_process. Variable vs fixed timestep basics and best practices.

Overview

When starting game development with Godot Engine, everyone first encounters the two main callback functions for controlling node behavior: _process(delta) and _physics_process(delta).

However, if you don't correctly understand the difference between these two functions and when to use each one, you'll face issues like unstable game behavior, inaccurate physics calculations, or degraded performance.

This article carefully explains the basics of Godot's game loop, points out common beginner mistakes, and introduces best practices for stable game development with concrete code examples.

Core Concepts: Variable vs Fixed Frames

The most important difference between _process and _physics_process is the frequency and timing of their calls. This is based on the fundamental concepts of "variable timestep" and "fixed timestep" in game development.

_process(delta): Variable Timestep

  • Call frequency: Called as frequently as possible, every frame.
  • Use cases:
    • Processing directly related to rendering.
    • User interface (UI) updates.
    • Input handling (Input.is_action_pressed(), etc.).
    • Smooth animations and visual effects that don't affect physics.
  • delta argument: Contains the elapsed time (in seconds) since the last frame. Since the frame rate fluctuates, this delta value also varies.

_physics_process(delta): Fixed Timestep

  • Call frequency: Called at a fixed interval regardless of game frame rate (default: 60 times per second, or every 0.0166 seconds).
  • Use cases:
    • Physics calculations (movement with move_and_slide(), etc., for CharacterBody2D/3D).
    • Processing requiring accurate simulation, like collision detection and raycasts.
    • Game logic that needs to be time-strict (timers, cooldowns, etc.).
  • delta argument: Always contains a fixed value (default: 1/60 second).
Feature_process(delta)_physics_process(delta)
Call frequencyEvery frame (variable)Fixed interval (default 60/sec)
TimestepVariable timestepFixed timestep
delta valueVariesFixed (default 0.0166... sec)
Main usesRendering, UI, input, non-physics animationPhysics, collision detection, strict game logic

Common Pitfalls and Mistakes

The most common mistake beginners make with these two functions is writing all processing in _process.

Mistake 1: Doing Physics in _process

If you write character movement processing (like move_and_slide()) in _process, character movement speed and behavior may change depending on the player's PC performance or frame rate.

  • Low frame rate: Fewer _process calls result in jerky character movement and increased risk of collision detection failures (tunneling).
  • High frame rate: More _process calls may cause characters to move faster than intended (even with delta compensation, physics stability is inferior to fixed timestep).

Furthermore, doing physics calculations in _process breaks the "fixed step" assumption that the physics server expects. Even if you multiply by delta to compensate speed, collision detection and raycast results become frame rate dependent, causing behavior differences between test and production environments.

For example, the same code might have different "hit chance" or "pass-through likelihood" between 144Hz and 60Hz monitor environments.

Mistake 2: Calculating Movement Without Using delta

If you calculate movement with fixed values in _process without using the delta argument, character speed will change significantly when frame rate fluctuates.

# Wrong example: not using delta in _process
func _process(delta):
    # Higher frame rate means more executions per second, making the player move faster
    position.x += 5

When using _process, you must always multiply by delta to guarantee frame rate independent speed.

Best Practices and Examples

Let's learn the correct way to use _process and _physics_process to achieve stable game behavior.

Separating Physics and Input Processing

A common pattern is to do physics calculations in _physics_process and capture input in _process, storing it in a variable. For simple games, you can get input directly in _physics_process, but separating concerns makes refactoring and debugging easier, so we'll show the separated approach here.

Best Practice for Player Movement

extends CharacterBody2D

const SPEED = 300.0
var direction = Vector2.ZERO # Variable to store input direction

# 1. Input processing: get user input every frame
func _process(delta):
    # UI and animation, processing directly related to rendering goes here

    # Get input and store in variable
    direction.x = Input.get_axis("move_left", "move_right")
    direction.y = Input.get_axis("move_up", "move_down")

# 2. Physics processing: execute physics calculations at fixed step
func _physics_process(delta):
    # Calculate velocity using stored input direction
    velocity = direction * SPEED

    # move_and_slide() is physics, so always call it in _physics_process
    move_and_slide()

This approach ensures input is captured smoothly (every frame) while physics calculations run at a stable fixed step, guaranteeing frame rate independent consistent behavior.

Interpolation for Visual Smoothness

Physics calculations run at a fixed step (e.g., 60 TPS) while rendering runs at a variable step (e.g., 120 FPS), so there are moments between render frames where physics object positions aren't updated, which can look jerky.

Starting with Godot 4.3, Physics Interpolation is built-in to automatically eliminate this jitter.

How to enable:

  1. Open Project > Project Settings
  2. Enable Physics > Common > Physics Interpolation (check the box)

With this setting enabled, positions calculated in _physics_process are automatically interpolated between render frames, achieving smooth movement.

Note: 2D physics interpolation is available from Godot 4.3 onwards. Versions 4.0-4.2 only supported 3D, and 2D required external addons (like Smoother).

Summary

Properly using _process and _physics_process is the key to stability and performance in Godot Engine.

FunctionTimestepUse forAvoid for
_processVariableUI updates, input capture, non-physics animation, renderingPhysics calculations, collision detection, strict time management
_physics_processFixedPhysics (move_and_slide), collision detection, timers, game logicProcessing directly tied to rendering (for performance reasons)

Next time you write code in Godot, ask yourself whether the processing is rendering-dependent or physics-dependent, and choose the appropriate function.