ADR-019: Steam Input for Gamepad Support
Status
Accepted
Context
The catnet VR overlay system requires gamepad input support for navigation and interaction. We initially used the gilrs library for cross-platform gamepad support, which worked well but had limitations:
- Platform Inconsistencies: Different behavior across Windows, Linux, and Steam Deck
- Limited Controller Support: Some controllers weren't properly detected or mapped
- No Action System: Raw button/axis mapping required manual configuration
- Steam Integration: No native integration with Steam's controller configuration UI
Steam Input offers several advantages:
- Unified input across all Steam-supported controllers
- User-customizable bindings through Steam's UI
- Action-based system instead of raw button mapping
- Built-in support for haptics and advanced features
- Automatic controller type detection and appropriate glyphs
However, Steam Input has one major limitation: it requires a valid Steam App ID to function properly. During development with Spacewar's test App ID (480), the action system doesn't work.
Decision
We will implement Steam Input as the primary gamepad backend using the steamworks crate, with gilrs as an automatic fallback option.
Implementation Details
-
Dual Backend Support
- Steam Input via
steamworks = "0.11"crate (feature-gated) - Gilrs via
gilrs = "0.10"as default/fallback - Both implement the same
InputSourcetrait
- Steam Input via
-
Automatic Fallback
InputManager::add_gamepad_auto()attempts Steam Input first- Falls back to gilrs if Steam is unavailable or not initialized
- Manual selection possible via
add_steam_input()oradd_gamepad()
-
Action Configuration
- Steam Input actions defined in
steam_input_actions.vdf - Two action sets:
ship_controlsandmenu_controls - Maps to existing ButtonId/AxisId enums for compatibility
- Steam Input actions defined in
-
Development Workflow
- Use gilrs during development (works immediately)
- Test Steam Input with detection examples
- Full Steam Input activated once real App ID is available
Consequences
Positive
- Better User Experience: Players can configure controls through familiar Steam UI
- Broader Controller Support: Any controller Steam supports works automatically
- Future-Proof: Ready for Steam release without code changes
- Maintains Compatibility: Gilrs fallback ensures non-Steam users aren't affected
Negative
- Development Complexity: Can't fully test Steam Input during development
- Additional Dependency: Requires steamworks crate and Steam client
- Configuration Files: Must maintain steam_input_actions.vdf manifest
Neutral
- Feature Flag: Steam Input is optional via
steam-inputfeature - No Breaking Changes: Existing InputSource trait unchanged
- Testing Strategy: Multiple test binaries for different scenarios
Implementation Notes
The implementation is complete and merged. Key files:
crates/vr-input/src/steam_input/- Full implementationsteam_input_actions.vdf- Action manifest (IGA format)steam_appid.txt- Contains development App ID- Multiple test examples in
crates/examples/src/bin/input/
Once the project has a real Steam App ID, update steam_appid.txt and Steam Input will become fully functional. Until then, gilrs provides reliable gamepad support for development and testing.