All skills
thedivergentai avatar

/godot-input-handling

@9d6e91e

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.

Use this Skill: https://skilld.dev/gh/thedivergentai/gd-agentic-skills/godot-input-handling

This session only. Nothing lands on disk.

SKILL.md

β‰ˆ91 tokens always: the name and description. β‰ˆ3.9k when used: this file. β‰ˆ1.7k more on demand in 6 files.

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 use InputMap actions. 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_changed to 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_pressed for 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.

  1. _input(event): High-priority global intercept. Use for dev consoles or debug overlays.
  2. _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.
  3. _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

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)

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 InputMap action 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_mode capture/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_event so menus stop events before _unhandled_input gameplay.

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 InputEvent branches, StringName actions, and safe signal/await patterns used in buffers and device routers.
Complements
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.

Source: SKILL.md on GitHub

1 warning16d4 checks Β· Risk MEDIUM
  • Gen Agent Trust Hub16d

    The skill provides comprehensive patterns for Godot input handling, but includes a medium-severity risk involving unsafe deserialization of local configuration files via bytes_to_var and str_to_var.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW Β· No issues

  • Runlayer7mo

    1/4 files flagged

Signed by skilld at 9d6e91e. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 weeks ago.

Activeupdated 2 months ago

README badge

README badge for thedivergentai/gd-agentic-skills/godot-input-handling