Quick answer: Build a debug scene with one button per haptic channel, run it on every supported controller (Xbox, DualSense, Switch Pro, mobile), and document the expected sensation in a manual QA checklist. Detect controller capabilities at runtime so missing motors degrade gracefully instead of crashing.

Rumble is the most underspecified feature in cross-platform game development. Every platform exposes a different API, every controller has different motors, and the only way to know your game feels right is to actually plug each controller in and feel it. Most studios skip this and ship games where the Xbox version rattles your hands and the PlayStation version produces a faint hum. Here is how to build a repeatable haptic QA pass that catches those bugs before launch.

The Haptic Hardware Landscape

Each controller has fundamentally different hardware. Building one rumble curve and shipping it to all platforms produces wildly different sensations.

Xbox Controller (One, Series, Elite). Two main motors (high frequency right, low frequency left) plus two impulse triggers (vibration motors inside L2 and R2). Total: four channels. Range 0–1 per channel. Latency < 10 ms.

PlayStation DualShock 4. Two main motors. No trigger feedback. Connected over Bluetooth or USB.

PlayStation DualSense. Linear actuators (not eccentric motors), so the response is much faster and more nuanced. Adaptive triggers can apply variable resistance and clicks. Total: four channels (LF, HF, L2 trigger, R2 trigger). Requires the platform’s native haptic API for full effect — the legacy API gives you weak, generic rumble.

Switch Pro Controller / Joy-Con. HD rumble, which is essentially a small linear motor capable of producing arbitrary waveforms (within a frequency band). Nintendo’s SDK exposes amplitude and frequency parameters per channel. Joy-Con also have a smaller motor in each side; combined, they can simulate object motion across the player’s hands.

Mobile devices. Apple Haptic Engine (iPhone 7+) supports complex Core Haptics patterns. Android exposes a vibration API that varies by device — flagship phones have linear actuators, budget phones have basic ERM motors that can only be on or off.

Asking “does my rumble work” without specifying which controller is meaningless. You have to test each combination.

Step 1: Build a Haptic Test Scene

Create a debug scene with a grid of buttons, one per haptic effect in your game. For each effect, also add buttons for “25%”, “50%”, “75%”, and “100%” intensity. Wire each button to play the corresponding effect immediately. Add a label that names the active controller and lists its detected capabilities.

// Unity example: HapticTestPanel.cs
public class HapticTestPanel : MonoBehaviour
{
    [SerializeField] private Button explosionBtn;
    [SerializeField] private Button footstepBtn;
    [SerializeField] private Button heartbeatBtn;
    [SerializeField] private Text controllerInfo;

    void Start()
    {
        explosionBtn.onClick.AddListener(() => HapticManager.Play("explosion"));
        footstepBtn.onClick.AddListener(() => HapticManager.Play("footstep"));
        heartbeatBtn.onClick.AddListener(() => HapticManager.Play("heartbeat"));

        var caps = HapticManager.DetectCapabilities();
        controllerInfo.text = $"{caps.deviceName}\nLF: {caps.hasLowFreq}\nHF: {caps.hasHighFreq}\nTriggers: {caps.hasTriggerHaptics}";
    }
}

This scene goes into the QA build, hidden behind a debug menu. Anyone testing the game can play any haptic effect on demand and verify it feels right.

Step 2: Capability Detection

At runtime, ask the controller what it can do before you play an effect.

public class HapticCapabilities
{
    public string deviceName;
    public bool hasLowFreq;
    public bool hasHighFreq;
    public bool hasTriggerHaptics;
    public bool hasAdaptiveTriggers;
}

public static class HapticManager
{
    public static HapticCapabilities DetectCapabilities()
    {
        var gamepad = Gamepad.current;
        if (gamepad is XInputController) return XboxCaps();
        if (gamepad is DualSenseGamepadHID) return DualSenseCaps();
        if (gamepad is SwitchProControllerHID) return SwitchCaps();
        return new HapticCapabilities { deviceName = "Unknown" };
    }
}

If a feature is missing, fall back to a degraded version: when adaptive triggers are not available, use a strong rumble pulse instead of trigger resistance. Players on a third-party gamepad still get feedback, just less of it.

Step 3: The QA Matrix

Make a spreadsheet with rows for each haptic effect in your game and columns for each supported controller. Have a tester check each cell with the test scene and rate the sensation: too weak, too strong, missing, or correct.

Effect          | Xbox | DS4  | DualSense | Switch Pro | Mobile
----------------|------|------|-----------|------------|-------
Explosion       | OK   | OK   | OK        | weak       | OK
Footstep        | OK   | weak | OK        | OK         | OK
Heartbeat       | weak | OK   | OK        | OK         | weak
Trigger pull    | n/a  | n/a  | OK        | n/a        | n/a
Bow draw        | OK   | weak | OK        | weak       | n/a

The matrix exposes systematic problems. If a single column is full of “weak,” that platform’s rumble curve needs a global boost. If a single row is full of “weak,” that effect’s definition needs more amplitude. Either way, the bug is now actionable.

Step 4: Automated Smoke Tests

You cannot fully automate haptics — the test requires a human to feel the device. But you can automate the “does the API call succeed” layer. Build a CI test that walks through every haptic effect, calls the play function, and asserts the call returns success. This catches API regressions without needing a tester for every build.

Common Bugs This Catches

“Rumble is part of the game feel. Shipping a game where the haptics differ wildly between platforms is shipping a different game on each platform. The QA matrix is the only honest way to check.”

Related Issues

For broader controller debugging, see how to debug controller dead zone issues. For Steam Deck specific testing, check how to test Steam Deck compatibility. For controller tracking on PlayStation, see crash reporting for PlayStation PS5 games.

Always include a “Rumble Intensity” slider in your accessibility menu. A surprising number of players prefer it at 50% or off entirely — respecting that preference is more important than any clever effect.