The Android client drops HapticService:SetMotor on the Gamepad1 LeftHand and
RightHand motors: its haptics backend only consumes Large and Small. VR games
such as VR Hands drive those motors, so they never vibrated.
- Interpose HapticService::SetMotor through its reflection descriptor, call
the original, and forward Gamepad1 LeftHand/RightHand to OpenXR. The
descriptor and the engine's intensity reader are found by pattern at load,
for both the 2998 (tuple span) and 3222 (shared tuple) reader ABIs. The held
level renews a 50 ms lease every presented frame.
- Report the hand motors at x = -1/+1 in GetMotors. Positional HapticEffects
aim at a hand there with a 0.5 radius (VOXEL DESTRUCT 2 does), so at +-0.2
every effect mixed to zero.
- Play SetMotorState buffers sample by sample with trailing silence trimmed.
Roblox sends 100 x 25 ms look-ahead buffers; taking the peak for the whole
buffer turned a short bump into 2.5 s at full strength.
- Stop vibrating from the DebugDeviceVR haptic slot. The engine pulls it every
frame but with each mix buffer's first sample, held about a second, so it
duplicated the buffers as a long buzz.
- Enable SupportGenericHapticsOnVR and FixRegisterMotors with the other haptic
flags.