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.
npx skills add https://github.com/thedivergentai/GD-Agentic-Skills --skill godot-input-handling
Handle keyboard, mouse, gamepad, and touch input with proper buffering and accessibility support.
| 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 |
| 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 |
Frame-perfect input buffering system for responsive jumps, dashes, and combo chains.
Timed action buffer with _physics_process decay so windows match CharacterBody consumption, not render FPS.
Dynamic input rebinding with conflict detection and user://input_rebinds.cfg persistence.
Radial deadzone management for analog sticks to eliminate drift while maintaining natural follow-through.
Handling touch, drags, and pinch-to-zoom gestures for mobile and touchscreen compatibility.
Filtering echo events to distinguish between hold-to-navigate (UI) and one-time gameplay actions.
Robust mouse capture and sensitivity scaling logic for FPS and mouse-intensive systems.
Software-side support for user-defined 'Hold' vs 'Toggle' accessibility preferences.
Real-time switching between Keyboard and Gamepad UI prompts based on the last active device.
Tracking the lifecycle of an action ('Just Pressed', 'Held', 'Released') for complex state logic.
Demonstrating the correct use of _unhandled_input to prevent gameplay logic from leaking into UI.
Input.parse_input_event injection for CI tutorials / AI assistance — not physical hardware.
Rolling timed sequence buffer for special-move validation (fighting / action RPG).
Frame-tagged capture + deterministic replay via parse_input_event.
_process() for gameplay actions — Use _physics_process() or _unhandled_input(). _process() is frame-rate dependent, causing dropped inputs at low FPS [22].KEY_W) — Always use InputMap actions. Hardcoded keys prevent rebinding and break compatibility with non-QWERTY layouts [23].Input.joy_connection_changed to update UI prompts dynamically [25]._input() for gameplay actions — _input() fires for ALL events (including UI). Use _unhandled_input() so gameplay logic doesn't trigger while clicking menus [26].Input.is_action_pressed() for one-time triggers — It returns true every frame the key is held. Use _just_pressed for jumps, attacks, and toggles to avoid logic spam.InputEvent.is_echo() in UI navigation — Echo events (keyboard repeat) should move menus but rarely should they trigger "Confirm" or "Back" actions.ui_cancel, the user is trapped. Always provide a fallback escape for mouse capture.0 — use InputEvent.DEVICE_ID_MOUSE and InputEvent.DEVICE_ID_KEYBOARD.event.device == 0 for mouse/keyboard; joypads may legitimately use ID 0.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 calls accept_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.Avoid physical key checks. Define semantic actions (e.g., move_left, interact) in Project Settings > Input Map.
Analog sticks suffer from drift. MANDATORY: analog_deadzone_manager.gd. Prefer Input.get_vector() for circular deadzones — never subtract axes into a square deadzone.
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.
Modern games must handle simultaneous Controller and Keyboard/Mouse input smoothly.
InputEventMouseMotion in _unhandled_input() for relative movement (mouse_capture_manager.gd)._physics_process() after analog_deadzone_manager.gd.MANDATORY: glyph_prompt_manager.gd for last-device prompt swaps. Do not hand-roll event is InputEventJoypadButton detectors in every HUD widget.
frame_perfect_coyote_time.gd) and godot-genre-platformer. Pair with buffers from this skill; do not re-implement coyote here.sync_input here. Route to godot-multiplayer-networking for authoritative action snapshots / get_remote_sender_id validation.Input.parse_input_event).godot-genre-fighting.| 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 |
> 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.
_input → GUI → _unhandled_input) and why gameplay belongs after UI consumes events.InputMap action polling, mouse buttons, and keyboard patterns this skill builds on.Input.mouse_mode capture/release flows.is_action_*, get_vector, mouse_mode, parse_input_event, and joy connection signals.action_add_event / erase / conflict checks for safe rebinding.is_echo(), is_action_pressed(), and device IDs._physics_process, not frame-tied _process._gui_input / accept_event so menus stop events before _unhandled_input gameplay.InputEvent branches, StringName actions, and safe signal/await patterns used in buffers and device routers._gui_input ownership so menus consume clicks before gameplay _unhandled_input.device_changed and rebind events should signal up to HUD/prompt listeners without hard UI refs.get_vector movement inside physics steps.InputMap rebinds and hold/toggle accessibility prefs to user:// config.Take thedivergentai/godot-input-handling from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.