Flukz — open-source shmup community resource open-source GPL devlog  ·  about
// indie shmup & game-dev resource

Shmup Design · June 30, 2026

Controller Rumble and Haptic Feedback in Shmups: Designing Feel Through Vibration

Most indie shmups skip controller rumble entirely. It is a mistake. Rumble is the only feedback channel that bypasses the visual system completely and reaches the player through touch. In a genre where visual attention is at maximum load during intense play, a well-designed rumble signal can communicate hit confirmation, power level, and boss phase transitions without demanding any additional visual processing. The players who notice rumble most are the players who play without it after getting used to it — the game suddenly feels distant and disconnected.

Two motors, two functions

Standard game controllers contain two vibration motors: a large low-frequency motor (the left motor in Xbox-style controllers) that produces a heavy, rumbling sensation, and a small high-frequency motor (right motor) that produces a buzzing, tingling sensation. These are designed for different categories of event.

Motor Character Ideal shmup uses
Large / low-frequencyHeavy rumble, impactPlayer hit, large explosion, boss contact, death
Small / high-frequencyBuzz, tingleRapid-fire shot, engine vibration, graze proximity

Using only one motor for all events flattens the expressive range. Using both motors for every event simultaneously is fatiguing and makes distinct events indistinguishable by feel. The design goal is to use each motor for events in its natural frequency range and reserve combined motor use for the most significant moments.

Mapping game events to rumble

A practical starting point for a standard shmup:

Rumble budget management

Multiple simultaneous rumble events stack, and unconstrained stacking produces undifferentiated constant vibration that loses all expressiveness within seconds. A simple priority queue solves this: each rumble event has a priority level, and only the highest-priority active event drives each motor. Lower-priority events queue but do not activate until the current event expires.

Set player hit and death as the highest priority events so they can never be masked by ongoing shoot rumble. Bomb effects take second priority. Ambient shoot vibration is lowest priority and is suppressed whenever any other event is active.

Platform considerations

Rumble API availability varies by platform and engine. In Godot, Input.start_joy_vibration(device, weak_magnitude, strong_magnitude, duration) controls both motors. In Unity, Gamepad.current.SetMotorSpeeds(low, high) provides direct control. SDL-based implementations use SDL_GameControllerRumble.

Notably, not all controllers implement rumble, and some controllers only implement one motor. Design rumble as enhancement, not dependency: the game must be fully playable with rumble disabled or absent without any mechanical disadvantage. This is also an accessibility requirement — some players with motor control differences find rumble disorienting and need a clean disable option in settings.

Testing methodology

Rumble design cannot be tested by reading code or looking at parameter values. It must be felt. The correct testing protocol:

  1. Set up a build on a device with a real controller, not a keyboard.
  2. Play through a full stage with rumble enabled, focusing attention entirely on what you feel rather than what you see.
  3. Identify events where rumble was unexpectedly absent (adding feedback opportunity) or unexpectedly present (causing confusion).
  4. Disable rumble entirely and play the same section. Note what feels missing — those absences identify the most valuable feedback slots.
  5. Have a second player do the same test blind, without being told what rumble events are designed. Their reactions identify whether the feedback is communicating what it is supposed to.

Tuning rumble magnitudes from a number in code produces guesses. Tuning them from what you feel while playing produces the correct values. Budget an afternoon for this process — it takes longer than expected but the improvement to game feel is disproportionate to the engineering effort.