module
Docs::O_LOW_LATENCY_INPUT_GUIDE
Overview
O. Low-Latency Input & Responsive Controls Guide
LibGodot provides zero-overhead, highly responsive input handling across both event-driven virtual callbacks and high-frequency polling APIs.
1. Event-Driven Input vs. Polling
For high-frequency, responsive inputs like mouse look and twitch keypresses, rely on
virtual event callbacks (_unhandled_input or _input) rather than polling in _process:
| Paradigm | Method / API | Latency & Characteristics |
|---|---|---|
| Event Dispatch (Recommended for Mouse) | def _unhandled_input(event : Godot::InputEvent) |
Sub-millisecond immediate dispatch. Delivers raw mouse relative delta without filtering or frame delays. |
| Vector Polling (Recommended for Movement) | Godot::Input.get_vector(neg_x, pos_x, neg_y, pos_y) |
Runs single native engine dispatch with deadzone handling. Zero allocations per frame. |
| Velocity Polling (Avoid for Mouse Look) | Godot.input.get_last_mouse_velocity * delta |
Warning: Godot applies an internal low-pass decay filter, introducing 2-3 frames of perceptible inertia and lag. |
2. First-Class Virtual Input Callbacks
Declare input callbacks inside any node class. LibGodot automatically registers
the virtual call table entries and wraps native pointers into typed InputEvent subclasses:
node PlayerController < CharacterBody3D do
property mouse_sensitivity : Float32 = 0.002_f32
def _unhandled_input(event : Godot::InputEvent) : Void
if motion = event.as?(Godot::InputEventMouseMotion)
# Instantaneous mouse look delta with zero inertia
rotate_y(-motion.relative.x * @mouse_sensitivity)
elsif key = event.as?(Godot::InputEventKey)
if key.pressed? && !key.echo? && key.keycode == Godot::Key::Escape
Godot::Input.mouse_mode = Godot::Input::MouseMode::Visible
end
end
end
end
3. Disabling Accumulated Input for Ultra-Low Latency
By default, Godot batches input events to match the OS display refresh rate. For competitive games or high-polling-rate mice (500Hz - 8000Hz), disable accumulation:
def _ready : Void
# Disable frame batching to receive unbuffered sub-frame mouse events immediately
Godot::Input.use_accumulated_input = false
end
4. Zero-Allocation Action & Button Queries
Godot::Input action queries use process-wide thread-safe StringName caching and
stack-allocated argument buffers, guaranteeing zero GC heap allocations in _physics_process:
def _physics_process(delta : Float64) : Void
# Zero-allocation 2D composite input vector with circular deadzone
input_dir = Godot::Input.get_vector("move_left", "move_right", "move_forward", "move_back")
# Zero-allocation button press checks
if Godot::Input.is_action_just_pressed("jump") && is_on_floor
velocity = Godot::Vector3.new(velocity.x, jump_velocity, velocity.z)
end
end