Godot Input Patterns
Purpose
Implement Godot input through InputMap actions with correct event propagation, device support, and rebinding.
Use When
- adding or unifying input handling for a Godot game
- gameplay scripts read raw keycodes, scancodes, or joypad button indices directly
- input behaves differently between gameplay, UI, and pause states and the propagation order is unclear
Inputs
- list of gameplay actions (move, jump, fire, pause, confirm)
- supported devices (keyboard/mouse, joypad, touch) per platform target
- UI flow and pause/overlay states that consume input
- rebinding and accessibility requirements
Process
- define every action in the InputMap (project settings or at startup) and bind devices to actions; gameplay code calls
Input.is_action_*or handlesInputEventactions, never raw keycodes - choose polling versus events deliberately: poll continuous state (movement axes via
Input.get_vector) in_physics_process, and handle discrete edges (just pressed/released) through events oris_action_just_pressed - respect the propagation order —
_input, then Control_gui_input, then_unhandled_input— and put gameplay input in_unhandled_inputso UI consumes events first; callset_input_as_handled()explicitly when a layer swallows an event - handle joypads through actions with deadzone configured per action, listen to
joy_connection_changedfor hot-plug, and verify mappings on each exported platform - for touch targets, decide between
InputEventScreenTouchhandling andemulate_mouse_from_touch, and keep on-screen controls as a separate Control layer bound to the same actions - implement rebinding by editing InputMap at runtime (
action_erase_events/action_add_event), persist bindings to user settings, and expose them through the accessibility options - define how paused state affects input: which nodes keep processing via
process_mode, and which actions (pause/menu) must work while the tree is paused
Outputs
- InputMap action inventory with device bindings and deadzones
- propagation rules: which layer handles what, in which callback
- rebinding and persistence design
- device and platform test scenarios (hot-plug, focus loss, touch emulation)
Quality Bar
- no gameplay script references keycodes, scancodes, or joypad indices outside the InputMap setup
- UI reliably consumes events before gameplay, and nothing double-handles an event after
set_input_as_handled() - movement uses
Input.get_vector(or equivalent) with per-action deadzones, not per-frame keycode checks - pause/menu actions keep working while the tree is paused, and nothing else does
- rebinds survive a restart and are reflected in any input prompts shown to the player
Common Failure Modes
- mixing
_inputand_processpolling for the same action, double-counting presses across frames - gameplay input in
_inputso UI clicks also fire gameplay actions underneath - hardcoded joypad button indices that differ between controller types and platforms
- pause menus that cannot be closed because their own input stopped processing with the tree
- touch handled through mouse emulation only, breaking multi-touch (move plus fire) on mobile
Related Agents
- godot-reviewer
- gameplay-programmer
- ui-programmer
Related Commands
- input-review
- godot-review
- verify
Related Skills
- godot-signals-patterns
- godot-scene-architecture
Notes
- Keep this skill aligned with the relevant rules layer and current project documentation.
- The engine-neutral action-abstraction policy lives in
engineering-common/input-abstraction; this skill is the Godot-specific implementation of it.

