[Godot] Controlling Pause Behavior with Process Mode

Created: 2025-06-20Last updated: 2026-07-07

A guide to Godot Engine's pause system and the Process Mode property on nodes. Covers the basics, building UI that keeps running while paused, cutscene and dialogue use cases, and performance considerations.

Overview

A pause feature is essential in game development, whether players need a breather or want to change settings. Godot gives you get_tree().paused = true, a one-liner that halts most of the game. But you'll often run into problems like "I paused, but now the UI won't respond" or "some characters keep moving anyway."

The cause is usually a misunderstanding of Process Mode. This article covers Godot's pause system from the basics, the Process Mode concept that lets you control it precisely, and some advanced implementation techniques.

The game world frozen mid-pause, with a jumping player and a running enemy suspended in midair

What You'll Learn

  • What get_tree().paused actually stops, and what it doesn't
  • How to choose among the five Process Modes (Inherit / Pausable / WhenPaused / Always / Disabled)
  • The right way to build a pause menu: the game stops, the menu stays alive
  • Advanced techniques for keeping just part of the scene running, such as cutscenes

Sponsored

Pause Basics in Godot

To stop most of the game loop in Godot, you set the scene tree's paused property.

# Get the scene tree and toggle its pause state
func toggle_pause():
    get_tree().paused = !get_tree().paused

    if get_tree().paused:
        print("Game paused.")
    else:
        print("Game resumed.")

When you run get_tree().paused = true, Godot stops the following:

  • Calls to _process(delta) and _physics_process(delta)
  • Physics simulation (collisions, gravity, and so on)
  • InputEvent handling (with some exceptions)

But this doesn't stop every node. Deciding which nodes are affected by the pause is exactly what Process Mode is for.

Process Mode: Five Modes That Control Pausing

Process Mode determines how each node reacts to the scene tree's pause state (get_tree().paused). You can set it in the Inspector under Node > Process.

The five Process Modes: Inherit (follows the parent, default), Pausable (stops when paused), WhenPaused (runs only while paused), Always (always runs), Disabled (never runs)
ModeBehaviorTypical Use
InheritTakes the parent node's setting as-is. This is the default.Most nodes in a scene, where no special control is needed.
PausableStops processing when get_tree().paused = true.Players, enemies, moving backgrounds, and other core gameplay elements.
WhenPausedProcesses only while get_tree().paused = true.Pause menus, settings screens, dialogs, and other UI you want to use while paused.
AlwaysKeeps processing regardless of get_tree().paused.Singletons (autoloads), BGM management, online communication.
DisabledNever runs any processing (_process, _physics_process, _input).Objects you want temporarily disabled, or debug-only nodes.
The Process Mode setting in the Inspector

Key point: because Inherit is the default, changing the Process Mode of a root node affects all of its children.

Here's what a paused game screen looks like as a diagram. The game world (Pausable) freezes, and only the pause menu (WhenPaused) stays alive. This split is the basic shape of every pause implementation.

Diagram of a paused game screen. The Pausable player and enemy are frozen, while only the WhenPaused pause menu (Resume / Settings / Return to Title) remains interactive
Sponsored

Practical Use Cases and Code

Use Case 1: A Robust Pause Menu

You need the game to stop while the menu UI stays interactive.

Step 1: Create a pause manager singleton (PauseManager.gd)

# PauseManager.gd
extends Node

const PAUSE_MENU_SCENE = preload("res://ui/pause_menu.tscn")

var is_paused: bool = false
var pause_menu_instance: Control = null

func _unhandled_input(event: InputEvent) -> void:
    if event.is_action_pressed("pause"):
        is_paused = !is_paused
        get_tree().paused = is_paused

        if is_paused and pause_menu_instance == null:
            pause_menu_instance = PAUSE_MENU_SCENE.instantiate()
            get_tree().root.add_child(pause_menu_instance)
        elif not is_paused and pause_menu_instance != null:
            pause_menu_instance.queue_free()
            pause_menu_instance = null

Register this script as a singleton under Project Settings > Autoload.

Step 2: Set up the pause menu scene (pause_menu.tscn)

  1. Create a scene with a Control node as its root.
  2. In the root node's Inspector, change Node > Process > Mode to WhenPaused.
  3. Add Button nodes to the scene, such as "Resume" and "Return to Title."

Use Case 2: Cutscenes

During a cutscene, you want to disable player input while specific characters and cameras keep playing their animations.

# CutsceneTrigger.gd (attach to an Area3D or similar)

@export var animated_characters: Array[Node]
@export var animated_camera: Camera3D

func _on_body_entered(body: Node) -> void:
    if body.is_in_group("player"):
        start_cutscene()

func start_cutscene() -> void:
    get_tree().paused = true

    # Temporarily change Process Mode for the nodes that should keep moving
    for character in animated_characters:
        character.process_mode = Node.PROCESS_MODE_ALWAYS
    if animated_camera:
        animated_camera.process_mode = Node.PROCESS_MODE_ALWAYS

    $AnimationPlayer.play("cutscene_animation")

func _on_animation_player_animation_finished(anim_name: StringName) -> void:
    if anim_name == "cutscene_animation":
        end_cutscene()

func end_cutscene() -> void:
    get_tree().paused = false

    # Restore the original Process Mode (important!)
    for character in animated_characters:
        character.process_mode = Node.PROCESS_MODE_PAUSABLE
    if animated_camera:
        animated_camera.process_mode = Node.PROCESS_MODE_PAUSABLE
Sponsored

Common Mistakes and Best Practices

Common MistakeBest Practice
Calling get_tree().paused from everywhereKeep pause state management in a single singleton (autoload) and avoid touching it directly from other scripts.
UI freezes while pausedCheck that the root node of the UI you want to use while paused has its Process Mode set to WhenPaused.
Overusing AlwaysLimit Always to nodes that truly need it (BGM, singletons). Overusing it degrades performance while paused.
AnimationPlayer won't stopIf an AnimationPlayer ignores the pause, check its Process Mode setting. Changing it to Pausable makes it stop along with the game.

Performance and Alternative Patterns

Performance Notes

  • Always is a last resort: it can hurt performance while the game is paused.
  • Save cycles with Disabled: setting Process Mode to Disabled on temporarily unneeded nodes lowers CPU load.

Alternative: Pause Management Without get_tree().paused

Since get_tree().paused affects the entire scene, you can also keep your own pause flag in a singleton when you need more localized control.

# Player.gd
extends CharacterBody3D

func _process(delta: float) -> void:
    if GameStateManager.is_gameplay_paused:
        return
    # ...normal processing...

Godot's built-in get_tree().paused plus Process Mode handles almost every case, so consider this alternative only when you have specific advanced requirements.

Summary

get_tree().paused and Process Mode are powerful features in Godot. Understand the two and use them together, and you can elegantly implement pause menus, cutscenes, dialogue displays, and every other situation a game needs.

  • Pause basics: get_tree().paused = true halts most of the game.
  • The key to control: Process Mode lets you fine-tune behavior per node.
  • Best practice: centralize pause management in a singleton, and set UI to WhenPaused.
  • Performance: avoid overusing Always, and use Disabled wisely.