# Godot Input System: How Input Mapping and Event Processing Work

> Discover how Godot's input system works. Learn about input mapping with InputMap and event processing via the Input singleton for seamless game control.

- Repository: [Godot Engine/godot](https://github.com/godotengine/godot)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Godot's input system uses the `InputMap` singleton to bind physical input events to named actions, while the `Input` singleton processes raw OS events, updates action states, and provides cached queries for game scripts.**

The Godot input system provides a flexible, data-driven architecture that decouples physical input devices from game logic. By mapping hardware events to abstract actions, developers can support multiple control schemes without hardcoding device-specific checks. This article examines the core implementation in the Godot Engine source code, tracing the path from OS-level events to script-accessible action queries.

## Core Architecture of the Godot Input System

Godot's input subsystem is built around two complementary singleton classes that separate configuration from runtime processing.

### InputMap: The Action Registry

The `InputMap` singleton serves as the central registry for action definitions. According to the source code in [`core/input/input_map.h`](https://github.com/godotengine/godot/blob/main/core/input/input_map.h), each action is stored as an `Action` struct containing a unique ID, deadzone value, and a list of bound `InputEvent` objects.

When you define an action in the Project Settings or via code, `InputMap::add_action()` (implemented in [`core/input/input_map.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_map.cpp) at line 17) creates this registry entry. The deadzone parameter (default 0.5) filters noise on analog inputs like joystick axes.

### Input: The Runtime Event Processor

While `InputMap` stores static definitions, the `Input` singleton (declared in [`core/input/input.h`](https://github.com/godotengine/godot/blob/main/core/input/input.h)) handles dynamic event processing. This class maintains the runtime state of all input devices and computes action states each frame.

The implementation in [`core/input/input.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input.cpp) manages several critical data structures:
- Pressed key sets and mouse button masks
- Current mouse position and velocity
- Per-device `ActionState` caches containing `pressed`, `strength`, and `raw_strength` values

## Input Event Processing Pipeline

The Godot input system processes events through a four-stage pipeline that transforms raw OS signals into queryable action states.

### Step 1: OS Event Capture

Platform-specific display servers capture hardware events and convert them to Godot `InputEvent` objects. In [`platform/windows/display_server_windows.cpp`](https://github.com/godotengine/godot/blob/main/platform/windows/display_server_windows.cpp), [`platform/linuxbsd/display_server_x11.cpp`](https://github.com/godotengine/godot/blob/main/platform/linuxbsd/display_server_x11.cpp), and similar files, the display server creates concrete event subclasses like `InputEventKey` or `InputEventMouseButton` and forwards them to `Input::parse_input_event()`.

### Step 2: Event Parsing and State Updates

Inside [`core/input/input.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input.cpp) at line 792, `Input::_parse_input_event_impl()` performs several tasks:
- Updates the internal pressed key set or mouse button mask
- Adjusts mouse position and velocity tracking
- Generates emulated events for mouse-to-touch or touch-to-mouse conversion (marked with `DEVICE_ID_EMULATION` to prevent infinite loops)

### Step 3: Action Matching and State Caching

The event then flows to `InputMap::event_is_action()` in [`core/input/input_map.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_map.cpp) (lines 46-57). This method searches the action's `inputs` list using `_find_event()` to detect matches. For analog events like `InputEventJoypadMotion`, the deadzone threshold is applied during matching (see `InputEventJoypadMotion::action_match` in [`core/input/input_event.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_event.cpp), lines 122-145).

When a match is found, `Input` updates the per-device `ActionState::DeviceState` and triggers `Input::_update_action_cache()` (lines 48-63 in [`input.cpp`](https://github.com/godotengine/godot/blob/main/input.cpp)). This aggregates all device states and API overrides (such as `action_press()` calls from scripts) into the cached `pressed`, `strength`, and `raw_strength` values.

### Step 4: Querying Action States

Game scripts query the cached state through methods declared in [`core/input/input.h`](https://github.com/godotengine/godot/blob/main/core/input/input.h). `Input::is_action_pressed()` simply returns `ActionState::cache.pressed`, while `Input::get_action_strength()` returns the analog strength value. These queries have minimal overhead since they read pre-computed cache values rather than iterating through events.

## Input Mapping Configuration

Understanding how to configure the Godot input system requires examining the binding mechanisms between events and actions.

### Defining Actions and Deadzones

Actions are created using `InputMap.add_action()` with an optional deadzone parameter. In the engine source, `InputMap::add_action()` (line 17 in [`core/input/input_map.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_map.cpp)) initializes the `Action` struct with a unique ID and stores it in the internal map. The deadzone value (default 0.5) filters low-intensity analog inputs.

### Binding Events to Actions

Events are bound to actions through `InputMap.action_add_event()` (lines 201-224 in [`core/input/input_map.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_map.cpp)). This method normalizes the device ID (converting legacy `0` to `DEVICE_ID_KEYBOARD` or `DEVICE_ID_MOUSE`) and appends the event to the action's `inputs` vector. You can bind multiple events to a single action, enabling simultaneous keyboard and controller support.

### Built-in Default Actions

Godot provides default UI actions through `InputMap.load_default()` (line 527 in [`core/input/input_map.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_map.cpp)). This method constructs actions like `ui_left`, `ui_accept`, and `ui_cancel` with predefined key bindings. Platform-specific overrides (e.g., `ui_accept.macos`) are applied via `get_builtins_with_feature_overrides_applied()` (lines 883-924), which checks `OS::has_feature()` to determine active variants.

## Practical Code Examples

The following examples demonstrate how to interact with the Godot input system in GDScript, corresponding to the underlying C++ implementations.

### Defining a Custom Action and Binding Keys

```gdscript

# Create a new action called "jump" with default deadzone

InputMap.add_action("jump")

# Bind the Space key

var ev = InputEventKey.new()
ev.keycode = Key.SPACE
InputMap.action_add_event("jump", ev)

# Bind the gamepad "A" button

ev = InputEventJoypadButton.new()
ev.button_index = JoyButton.A
InputMap.action_add_event("jump", ev)

```

This corresponds to `InputMap::add_action()` (line 17 of [`input_map.cpp`](https://github.com/godotengine/godot/blob/main/input_map.cpp)) and `InputMap::action_add_event()` (lines 201-224).

### Querying an Action in Game Logic

```gdscript
if Input.is_action_pressed("jump"):
    $Player.jump()

```

Under the hood, `Input::is_action_pressed()` reads `ActionState::cache.pressed`, which is updated by `_update_action_cache()` (lines 48-63 in [`core/input/input.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input.cpp)) whenever a bound event occurs.

### Simulating Input Events Programmatically

```gdscript
var ev = InputEventKey.new()
ev.keycode = Key.SPACE
ev.pressed = true
Input.parse_input_event(ev)   # Triggers the same path as a real key press

```

`parse_input_event()` routes the event through `_parse_input_event_impl()` (line 792 in [`core/input/input.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input.cpp)), updates the key-set, finds matching actions via `InputMap::event_is_action()`, and refreshes the action cache.

### Adjusting Action Deadzones at Runtime

```gdscript
InputMap.action_set_deadzone("ui_up", 0.3)   # Higher deadzone for joystick axis

```

This calls `InputMap::action_set_deadzone()` (line 48 of [`core/input/input_map.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_map.cpp)). The new deadzone is used the next time an axis event is matched (`InputEventJoypadMotion::action_match` in [`core/input/input_event.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_event.cpp), lines 122-145).

### Reloading Default Actions

```gdscript

# Force a reload (useful after changing project settings)

InputMap.load_default()

```

This invokes `InputMap::load_default()` (line 527 in [`core/input/input_map.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_map.cpp)), which iterates over the built-in map returned by `get_builtins_with_feature_overrides_applied()` (lines 883-924).

## Summary

- **InputMap** ([`core/input/input_map.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_map.cpp)) stores action definitions and event bindings, handling deadzones and platform-specific overrides.
- **Input** ([`core/input/input.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input.cpp)) processes raw OS events through `parse_input_event()`, maintains device state, and caches action states for fast queries.
- The pipeline flows from platform display servers → `Input::_parse_input_event_impl()` → `InputMap::event_is_action()` → `Input::_update_action_cache()` → script queries like `is_action_pressed()`.
- Emulated input (mouse/touch conversion) is handled at the parsing stage with `DEVICE_ID_EMULATION` to prevent feedback loops.
- Built-in actions are loaded via `load_default()` with feature overrides applied for platform-specific variants.

## Frequently Asked Questions

### What is the difference between Input and InputMap in Godot?

`InputMap` is a singleton that stores static action definitions and their associated input events, acting as a registry that maps physical inputs to logical action names. `Input` is the runtime singleton that processes raw OS events, updates the state of pressed keys and buttons, and evaluates which actions are currently active based on the definitions stored in `InputMap`.

### How does Godot handle input events from different platforms?

Platform-specific display servers (such as [`display_server_windows.cpp`](https://github.com/godotengine/godot/blob/main/display_server_windows.cpp) or [`display_server_x11.cpp`](https://github.com/godotengine/godot/blob/main/display_server_x11.cpp)) capture OS-specific input and construct Godot `InputEvent` objects. These are passed to `Input::parse_input_event()`, which processes them through the same unified pipeline regardless of origin. Platform-specific action overrides (like `ui_accept.macos`) are applied via `get_builtins_with_feature_overrides_applied()`, which checks `OS::has_feature()` to determine active variants.

### What is the deadzone in Godot's input system and how is it applied?

The deadzone is a threshold value (default 0.5) stored per action in `InputMap` that filters out low-intensity analog noise from joystick axes. When an `InputEventJoypadMotion` is evaluated against an action, the `action_match` method (lines 122-145 in [`core/input/input_event.cpp`](https://github.com/godotengine/godot/blob/main/core/input/input_event.cpp)) applies the deadzone to determine if the event counts as "pressed" and calculates the final strength value, effectively ignoring input below the threshold.

### How can I simulate input events programmatically in Godot?

You can create `InputEvent` objects in GDScript (such as `InputEventKey` or `InputEventJoypadButton`), configure their properties like `keycode` or `pressed`, and pass them to `Input.parse_input_event()`. This method routes the synthetic event through the same internal pipeline as real hardware input, updating internal state and action caches via `_parse_input_event_impl()` and triggering any bound actions exactly as if the input originated from the OS.