@thedivergentai/godot-input-handling
Expert patterns for input handling covering InputMap actions, InputEvent processing, controller support, rebinding, deadzones, and input buffering. Use when setting up player controls, implementing input systems, or adding gamepad/accessibility features. Keywords InputMap, InputEvent, gamepad, controller, rebinding, deadzone, input buffer.
| name | godot-input-handling |
| description | Expert patterns for input handling covering InputMap actions, InputEvent processing, controller support, rebinding, deadzones, and input buffering. Use when setting up player controls, implementing input systems, or adding gamepad/accessibility features. Keywords InputMap, InputEvent, gamepad, controller, rebinding, deadzone, input buffer. |
Input Handling
Handle keyboard, mouse, gamepad, and touch input with proper buffering and accessibility support.
MANDATORY script triggers (by scenario)
| Scenario | Load before coding |
|---|---|
| Jump/dash/coyote feel | input_buffer.gd (physics-tied decay) + advanced_input_buffer.gd for multi-action priority |
| Settings remapping UI | safe_runtime_rebind.gd (ConfigFile persist to user://) |
| Analog stick movement | analog_deadzone_manager.gd — never raw axis without radial deadzone |
| "Press X / Press E" prompts | glyph_prompt_manager.gd |
| UI nav vs gameplay confirm | input_echo_filter.gd — echoes move menus, not Confirm/Back |
| Gameplay vs menu clicks | unhandled_input_priority.gd |
Do-NOT-Load (by scenario)
| Scenario | Load | Do NOT load |
|---|---|---|
| Settings remapping UI | safe_runtime_rebind.gd |
multi_touch_gestures.gd, mouse_capture_manager.gd, combo/replay injectors |
| Mobile / touch gestures | multi_touch_gestures.gd |
mouse_capture_manager.gd, desktop remapper persistence |
| Jump/dash buffer only | input_buffer.gd / advanced_input_buffer.gd |
Remapper, multi-touch, replay, combo validator |
| FPS mouse look | mouse_capture_manager.gd + deadzone/glyph as needed |
multi_touch_gestures.gd, combo/replay |
| Combo / fighting sequences | combo_validator.gd + buffers |
Touch gestures, mouse capture |
| Replay / virtual injection tests | input_replay_buffer.gd / virtual_input_injector.gd |
Remapper UI, multi-touch |
Available Scripts
advanced_input_buffer.gd
Frame-perfect input buffering system for responsive jumps, dashes, and combo chains.
input_buffer.gd
Timed action buffer with _physics_process decay so windows match CharacterBody consumption, not render FPS.
safe_runtime_rebind.gd
Dynamic input rebinding with conflict detection and user://input_rebinds.cfg persistence.
analog_deadzone_manager.gd
Radial deadzone management for analog sticks to eliminate drift while maintaining natural follow-through.
multi_touch_gestures.gd
Handling touch, drags, and pinch-to-zoom gestures for mobile and touchscreen compatibility.
input_echo_filter.gd
Filtering echo events to distinguish between hold-to-navigate (UI) and one-time gameplay actions.
mouse_capture_manager.gd
Robust mouse capture and sensitivity scaling logic for FPS and mouse-intensive systems.
hold_toggle_accessibility.gd
Software-side support for user-defined 'Hold' vs 'Toggle' accessibility preferences.
glyph_prompt_manager.gd
Real-time switching between Keyboard and Gamepad UI prompts based on the last active device.
action_state_machine.gd
Tracking the lifecycle of an action ('Just Pressed', 'Held', 'Released') for complex state logic.
unhandled_input_priority.gd
Demonstrating the correct use of _unhandled_input to prevent gameplay logic from leaking into UI.
virtual_input_injector.gd
Input.parse_input_event injection for CI tutorials / AI assistance — not physical hardware.
combo_validator.gd
Rolling timed sequence buffer for special-move validation (fighting / action RPG).
input_replay_buffer.gd
Frame-tagged capture + deterministic replay via parse_input_event.
NEVER Do in Input Handling
- NEVER poll input in
_process()for gameplay actions — Use_physics_process()or_unhandled_input()._process()is frame-rate dependent, causing dropped inputs at low FPS [22]. - NEVER use hardcoded key checks (e.g.,
KEY_W) — Always useInputMapactions. Hardcoded keys prevent rebinding and break compatibility with non-QWERTY layouts [23]. - NEVER ignore analog stick deadzones — Drifting sticks at 0.05 magnitude will cause unintended movement. Implement a radial deadzone (not axial) in code or settings [24].
- NEVER assume a single input device — Players may switch between Keyboard and Controller mid-session. Use
Input.joy_connection_changedto update UI prompts dynamically [25]. - NEVER use
_input()for gameplay actions —_input()fires for ALL events (including UI). Use_unhandled_input()so gameplay logic doesn't trigger while clicking menus [26]. - NEVER omit input buffering in fast-paced games — If a player presses jump 50ms before landing, the input is lost without a buffer. Implement a 100-150ms buffer for a "tight" feel [27].
- NEVER use
Input.is_action_pressed()for one-time triggers — It returns true every frame the key is held. Use_just_pressedfor jumps, attacks, and toggles to avoid logic spam. - NEVER implement manual 'Hold vs Toggle' logic in multiple places — Centralize it in a setting or input wrapper to ensure accessibility consistency across the whole game.
- NEVER forget to handle
InputEvent.is_echo()in UI navigation — Echo events (keyboard repeat) should move menus but rarely should they trigger "Confirm" or "Back" actions. - NEVER capture the mouse without a 'Release' shortcut — If your game crashes or blocks
ui_cancel, the user is trapped. Always provide a fallback escape for mouse capture.
Input Propagation & Isolation
Godot propagates input events in a specific order. Understanding this is key to isolating UI from gameplay.
_input(event): High-priority global intercept. Use for dev consoles or debug overlays._gui_input(event): Handled by Control nodes (UI). If a UI element consumes the event (e.g., clicking a button), it callsaccept_event(), stopping further propagation._unhandled_input(event): Reached ONLY if no UI element consumed the event. Expert Pattern: Put all gameplay logic (jump, shoot) here to prevent accidental triggers while interacting with menus.
InputMap Best Practices
Avoid physical key checks. Define semantic actions (e.g., move_left, interact) in Project Settings > Input Map.
1. Analog Deadzones
Analog sticks suffer from drift. MANDATORY: analog_deadzone_manager.gd. Prefer Input.get_vector() for circular deadzones — never subtract axes into a square deadzone.
2. Expert polling delta (no hardcoded keys)
Gameplay samples actions in _physics_process / _unhandled_input — never KEY_* / MOUSE_BUTTON_* branches. Pause/cancel must be InputMap actions (e.g. ui_cancel) so rebinds and non-QWERTY layouts work. See unhandled_input_priority.gd.
Multi-Modal Input & UI Glyphs
Modern games must handle simultaneous Controller and Keyboard/Mouse input smoothly.
1. Handling Input Modes
- Mouse Aiming: Process
InputEventMouseMotionin_unhandled_input()for relative movement (mouse_capture_manager.gd). - Stick Movement: Poll vectors in
_physics_process()after analog_deadzone_manager.gd.
2. Dynamic Glyph Swapping
MANDATORY: glyph_prompt_manager.gd for last-device prompt swaps. Do not hand-roll event is InputEventJoypadButton detectors in every HUD widget.
Expert Input Extensions (script sole-source)
- Input buffering — MANDATORY: input_buffer.gd + advanced_input_buffer.gd. Do not paste jump-timer tutorials inline.
- Coyote time — Owned by movement skills: godot-characterbody-2d (
frame_perfect_coyote_time.gd) and godot-genre-platformer. Pair with buffers from this skill; do not re-implement coyote here. - Multiplayer input sync — Do not RPC
sync_inputhere. Route to godot-multiplayer-networking for authoritative action snapshots /get_remote_sender_idvalidation. - Virtual injection — MANDATORY: virtual_input_injector.gd (
Input.parse_input_event). - Combo sequences — MANDATORY: combo_validator.gd; fighting fiction stays in
godot-genre-fighting. - Deterministic replay — MANDATORY: input_replay_buffer.gd.
Deep recipes (on demand)
| Topic | Reference / script |
|---|---|
| Buffering / coyote / MP sync | input-event-processing.md |
| Virtual injection / combos / replay | expert-input-extensions.md |
| InputMap & device IDs | inputmap-best-practices.md |
Reference
Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.
Official Documentation
- Using InputEvent — Event propagation order (
_input→ GUI →_unhandled_input) and why gameplay belongs after UI consumes events. - Input examples — Practical
InputMapaction polling, mouse buttons, and keyboard patterns this skill builds on. - Controllers, gamepads, and joysticks — Joypad connection, button/axis events, and multi-device mapping for remappers and glyph swaps.
- Controller vibration and features — Extended pad capabilities beyond basic buttons when shipping console-style feedback.
- Mouse and input coordinates — Viewport vs screen coordinates for clicks, aim, and capture-relative motion.
- Customizing the mouse cursor — Cursor shapes alongside
Input.mouse_modecapture/release flows. - Handling quit requests — Safe ESC / back / quit paths so mouse capture never traps the player.
- Input — Singleton API:
is_action_*,get_vector,mouse_mode,parse_input_event, and joy connection signals. - InputMap — Runtime
action_add_event/ erase / conflict checks for safe rebinding. - InputEvent — Base event API including
is_echo(),is_action_pressed(), and device IDs. - Idle and Physics Processing — Why hold/poll gameplay input in
_physics_process, not frame-tied_process. - Control —
_gui_input/accept_eventso menus stop events before_unhandled_inputgameplay.
Related Skills
Prerequisites
- godot-project-foundations — Project Settings Input Map, scene boot, and Autoload registration that host remappers and glyph managers.
- godot-gdscript-mastery — Typed
InputEventbranches,StringNameactions, and safe signal/awaitpatterns used in buffers and device routers.
Complements
- godot-ui-containers — Control focus and
_gui_inputownership so menus consume clicks before gameplay_unhandled_input. - godot-signal-architecture —
device_changedand rebind events should signal up to HUD/prompt listeners without hard UI refs. - godot-autoload-architecture — Singleton ownership for InputBuffer / GlyphPrompt / Remapper services that survive scene changes.
- godot-characterbody-2d — Consumes buffered jump/dash and
get_vectormovement inside physics steps. - godot-camera-systems — Mouse-look sensitivity and capture modes pair with FPS camera rigs.
- godot-state-machine-advanced — Action just-pressed / held / released phases drive FSM transitions without polling spam.
- godot-save-load-systems — Persist
InputMaprebinds and hold/toggle accessibility prefs touser://config. - godot-adapt-desktop-to-mobile — Virtual joysticks and touch cameras extend this skill’s multi-touch gesture patterns.
Downstream / consumers
- godot-genre-platformer — Coyote time and jump buffers are the primary consumer of input buffering.
- godot-genre-shooter-fps — Captured mouse aim, fire just-pressed, and gamepad look rely on this skill’s capture/deadzone stack.
- godot-genre-fighting — Combo sequence validators and frame-perfect buffers feed special-move detection.
- godot-multiplayer-networking — Authoritative peers need sanitized action snapshots / RPC’d input, not raw local keycodes.
Master
- godot-master — Library router and mirrored module entry; open when discovering which Domain Skill owns a cross-cutting input concern.
Loading...
Select a file to preview
Analyzing security...
Checking scan reports and verification data.
Bill of Materials
Everything this skill can do — files, network, commands, and more.