How to measure hardware controller lag
Tags: hardware, gamedev
Published: 2022-09-04 14:38:38

While I'm in the process of writing another post about game backend development announced [recently](https://dev.to/konstantinusachev/what-ive-learned-after-10-years-of-game-backend-development-39h4), here is a short story from my current project. One part of this project is a custom hardware controller. At some point, we realised we needed a way to measure its lag because we started to feel it during tests.

The first thought would have been to do it programmatically. It has some benefits:
* You can do it automatically, even put the hardware to CI infrastructure and measure it every firmware update
* The results would be accurate and repeatable

But at the same time, there are some drawbacks:
* First, it would require additional development, in some cases even adding two-way communication to the controller, which we don't need
* It would require us to not only make the controller's firmware changes but also host device software changes
* This additional lag measurement–related software itself and its updates might affect the result
* We might have some mechanical design lag reasons, which we would also like to catch for new hardware iterations
* We cannot directly compare it with other existing devices to understand where we relate to other controllers out there

## Video-based measurement

So after a short discussion, we came up with a relatively simple approach that, in our case, covers all our needs. You can measure the lag using a high-FPS video camera with a high FPS display and counting the time it takes from the button press to reaction. 

Let's try to calculate this approach error. If we have a display with DisplayFPS and a camera with CameraFPS, the overall error would be something like ±(1000/CameraFPS) + (1000/DisplayFPS) / 2. So the result would be higher on average than the actual value.

I used a 165 Hz display and iPhone slo-mo camera with 240 FPS. So it would give an error of ±4 ms + 3 ms for a single measured lag. Is it much? It depends. We jumped from 70 ms to 140 ms lag when we started noticing it with our controller, so it is far enough in our case. Also, several measurements increase accuracy.

## The actual process

The main idea is to record a video with the button press and display the reaction simultaneously. The measurement accuracy is highly affected by the actual measurement protocol. I recommend using a holder or tripod for the camera and trying to hold the controller in a way that it is obvious when the button press started. In our case, we record ten presses and calculate a median value. Also, we notice some extreme values and try to determine whether it is a measurement or controller-related issue.

## Some results for on-hand controllers 
I've measured the lag of some controllers to demonstrate that it is accurate enough to detect Bluetooth overhead, for example.

| Type      | Name                 | Connection type | Lag   |
| --------- | -------------------- | --------------- | ----- |
| gamepad   | Xbox One Controller  | wired           | 38 ms |
| gamepad   | Xbox One Controller  | Bluetooth       | 46 ms |
| keyboard  | Laptop keyboard      | wired           | 29 ms |
| keyboard  | Logitech MX keys     | Bluetooth       | 42 ms |
| mouse     | Logitech G502 Hero   | wired           | 33 ms |
| mouse     | Logitech MX Master 3 | Bluetooth       | 38 ms |

---

You can find several descriptions of this approach with different variations. Here, the idea is that even a trivial and straightforward variation is sufficient and can be used as a cheap way to monitor latency for a custom controller. 

Did you encounter such a task in your practice and try a different approach?