Research • Not playable yet
Valve Hardware Audit & Planned 3rd Output Backend

Valve Steam Controller Haptics Engineering

Community players asked for HD Rumble on the Steam Controller. Because the author does not own the hardware, we audited upstream SDL 3.4.8 drivers first and published our architectural findings openly before writing any code.

Please don't report bugs for this controller yet — they are not supported.

Actuators Dual Trackpad LRAs Left / Right Pads
Vendor ID VID 0x28DE Valve Corporation
2015 Model Pulse 0x8F 65-byte SendJoystickEffect
2026 Triton Tone 0x83 MsgHapticLfoTone (Direct HID)
LEFT PAD RIGHT PAD SC 2015: 0x8F Pulse Feature Report Stock SDL3 SDL_SendJoystickEffect (65 Bytes) SC 2026 Triton: 0x83 MsgHapticLfoTone Direct HID Write (frequency, duration, dBgain, LFO) Valve Steam Controller Trackpads
Upstream Driver Architecture Audit

What We Verified in SDL 3.4.8 (VID 0x28DE)

Neither the 2015 Steam Controller (PID 0x1102 wired, 0x1142 dongle, 0x1105/0x1106 BLE), the 2026 Steam Controller (“Triton”) (PID 0x1302 wired, 0x1303 BLE, 0x1304 “Proteus” dongle), nor the Steam Deck (0x1205) exposes a USB audio device. That completely rules out our DualSense 48 kHz USB audio pipeline—every tactile command must be transmitted as a structured HID packet.

On the 2015 Steam Controller (two trackpad LRAs), SDL3's standard RumbleJoystick returns SDL_Unsupported(), meaning standard emulator fallback rumble produces zero vibration. Fortunately, SDL3's SendJoystickEffect forwards raw 65-byte feature reports directly (enabled by default on Windows), allowing RenHDrum to send 0x8F (MsgFireHapticPulse: which_pad, pulse_duration, pulse_interval, pulse_count, dBgain, priority) on stock SDL3 without patching SDL.

On the 2026 “Triton” controller, SDL3's RumbleJoystick sends output report 0x80 with motor speed only, while SendJoystickEffect returns SDL_Unsupported() (as does Steam Deck). SDL 3.4.8 headers define frequency tone report 0x83 (MsgHapticLfoTone: side, gain_db, frequency, duration_ms, lfo_freq, lfo_depth) and pulse 0x81, but SDL3 does not allow raw passthrough yet.

Hardware PID (VID 0x28DE) RumbleJoystick SendJoystickEffect Native Haptic Command RenHDrum Path
Steam Controller (2015) 0x1102 / 0x1142 SDL_Unsupported() Supported (65 bytes) 0x8F MsgFireHapticPulse Stock SDL3 (Planned)
Steam Controller 2026 (“Triton”) 0x1302 / 0x1303 / 0x1304 0x80 (speed only) SDL_Unsupported() 0x83 MsgHapticLfoTone Direct HID (Planned)
Steam Deck 0x1205 0x80 (speed only) SDL_Unsupported() 0x83 Tone • 0x81 Pulse Deferred

⚠ Unverified / Community Reports

The following claims come only from community projects (such as PadForge and standalone “singer” tools) and are unverified: (1) 8 kHz PCM streaming over HID 0x86/0x88 on Triton (absent in SDL 3.4.8, where 0x86 is HAPTIC_SCRIPT); (2) a 100–1300 Hz usable range (this is PadForge's software filter clamp, not a Valve specification); and (3) ~10 ms safe command spacing and latency figures.

Engineering Realities & The Road to Implementation

Current Roadblocks & Planned Valve Haptics Backend

⚠ Current Roadblocks

  • No Hardware on Hand: The author does not own a Steam Controller, so community testers with physical hardware are needed to test and tune the beta.
  • Steam Input Contention: Steam / Steam Input claims exclusive access to the controller while running. Players must close Steam or disable Steam Input for the controller.
  • Band Merging Required: Each side accepts only one frequency per command, whereas Switch HD Rumble carries two simultaneous bands (Low + High) per side.
  • Triton Raw HID & SDL3 Target: Sending tone 0x83 on Triton requires direct HID writes (an SDL patch or standalone hidapi). Because Ryuhdr runs on SDL2 with its vibration logic frozen, the beta will live in an SDL3-based emulator (which specific emulator is not finalized yet).

📋 Planned Approach (Not Yet Implemented)

3rd Output Path

Planned Valve Haptics Backend in RenHDrum: Pick the stronger amplitude band on each side per frame, convert frequency + amplitude into a Valve command, and dispatch every ~10 ms (interval to be validated by testers).

Step 1 (Planned)

Steam Controller 2015: Send 65-byte 0x8F pulse feature reports via stock SDL_SendJoystickEffect (frequency ≈ 1 / (on + off), amplitude = dBgain).

Step 2 (Planned)

Steam Controller 2026 (“Triton”): Send 0x83 tone reports via direct HID writes. Steam Deck support is deferred until later.

Monograph 08 • Research Only • Needs Community Testers

Full Steam Controller Haptics Monograph

No code written yet • No release date announced