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.
What this skill does
# Input Handling
Handle keyboard, mouse, gamepad, and touch input with proper buffering and accessibility support.
## Available Scripts
### [advanced_input_buffer.gd](scripts/advanced_input_buffer.gd)
Frame-perfect input buffering system for responsive jumps, dashes, and combo chains.
### [safe_runtime_rebind.gd](scripts/safe_runtime_rebind.gd)
Dynamic input rebinding with conflict detection, persistence, and multi-device support.
### [analog_deadzone_manager.gd](scripts/analog_deadzone_manager.gd)
Radial deadzone management for analog sticks to eliminate drift while maintaining natural follow-through.
### [multi_touch_gestures.gd](scripts/multi_touch_gestures.gd)
Handling touch, drags, and pinch-to-zoom gestures for mobile and touchscreen compatibility.
### [input_echo_filter.gd](scripts/input_echo_filter.gd)
Filtering echo events to distinguish between hold-to-navigate (UI) and one-time gameplay actions.
### [mouse_capture_manager.gd](scripts/mouse_capture_manager.gd)
Robust mouse capture and sensitivity scaling logic for FPS and mouse-intensive systems.
### [hold_toggle_accessibility.gd](scripts/hold_toggle_accessibility.gd)
Software-side support for user-defined 'Hold' vs 'Toggle' accessibility preferences.
### [glyph_prompt_manager.gd](scripts/glyph_prompt_manager.gd)
Real-time switching between Keyboard and Gamepad UI prompts based on the last active device.
### [action_state_machine.gd](scripts/action_state_machine.gd)
Tracking the lifecycle of an action ('Just Pressed', 'Held', 'Released') for complex state logic.
### [unhandled_input_priority.gd](scripts/unhandled_input_priority.gd)
Demonstrating the correct use of `_unhandled_input` to prevent gameplay logic from leaking into UI.
> **MANDATORY - For Responsive Controls**: Read input_buffer.gd before implementing jump/dash mechanics.
## 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. Use `Input.get_vector()` for mathematically correct **circular deadzones**.
- **Bad**: Subtracting axis strengths manually creates "square" deadzones.
- **Good**: `var input := Input.get_vector("left", "right", "up", "down")` applies a perfectly circular deadzone and clamps magnitude to 1.0.
### 2. Basic Polling
```gdscript
# Check if action pressed this frame
if Input.is_action_just_pressed("jump"):
jump()
# Check if action held
if Input.is_action_pressed("fire"):
shoot()
# Check if action released
if Input.is_action_just_released("jump"):
release_jump()
# Get axis (-1 to 1)
var direction := Input.get_axis("move_left", "move_right")
# Get vector
var input_vector := Input.get_vector("left", "right", "up", "down")
```
## InputEvent Processing
```gdscript
func _input(event: InputEvent) -> void:
if event is InputEventKey:
if event.keycode == KEY_ESCAPE and event.pressed:
pause_game()
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
click_position = event.position
```
## Multi-Modal Input & UI Glyphs
Modern games must handle simultaneous Controller and Keyboard/Mouse input smoothly.
### 1. Handling Input Modes
- **Mouse Aiming**: Process `InputEventMouseMotion` in `_unhandled_input()` for relative movement.
- **Stick Movement**: Poll `Input.get_vector()` in `_physics_process()` for clamped state.
### 2. Dynamic Glyph Swapping
To update UI prompts (e.g., "Press E" vs "Press X") in real-time:
- **Autoload Strategy**: Create a singleton that monitors `_input(event)`.
- **Detection**: Check `event is InputEventJoypadButton` or `InputEventJoypadMotion` to detect gamepad use.
- **Broadcasting**: Emit a signal (e.g., `signal device_changed(is_gamepad: bool)`) when the hardware type shifts. All UI elements should listen to this signal to swap their prompt textures.
## Expert Input Extensions
### 1. Input-Buffering (Action Queuing)
Decouple input presses from physics execution to make controls feel "tight." Store the input in a timed buffer and consume it when a valid state (e.g., landing) is reached [1, 2].
```gdscript
var jump_buffer_timer: float = 0.0
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("jump"):
jump_buffer_timer = 0.15 # 150ms window
func _physics_process(delta: float) -> void:
if jump_buffer_timer > 0.0:
jump_buffer_timer -= delta
if is_on_floor():
jump()
jump_buffer_timer = 0.0
```
### 2. Coyote-Time (Jump Leniency)
Allow a jump for a few frames after the character leaves a ledge by tracking the time since last grounded [4].
```gdscript
var coyote_timer: float = 0.0
func _physics_process(delta: float) -> void:
if is_on_floor():
coyote_timer = 0.1 # 100ms grace period
else:
coyote_timer -= delta
if Input.is_action_just_pressed("jump") and coyote_timer > 0.0:
jump()
coyote_timer = 0.0
```
### 3. Multiplayer-Input-Synchronization
Route local device input to the authoritative server using RPCs and `multiplayer.get_remote_sender_id()` for validation [7, 8].
```gdscript
@rpc("any_peer", "call_local", "unreliable")
func sync_input(dir: Vector2) -> void:
var sender = multiplayer.get_remote_sender_id()
# Apply dir to the player body associated with sender...
```
## Reference
- [Godot Docs: InputEvent](https://docs.godotengine.org/en/stable/tutoriRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.