Introduction
In order to properly understand how input lag can be reflected in a device, we need to basically understand how does a controller PCB work on the inside and where lag can arise.
A system MUST somehow access in his internal state the status of each buttons on each game engine tick.
Legacy controllers
We will not detail a lot here but it is interesting to see how old systems handled it. If you are interested, check out this great video from the 8-bit guy on the topic.
Direct pins controllers
Examples: all arcade controllers, most DB9 and DB15 controllers (Commodore, Atari, NeoGeo, Sega Genesis for instance) uses a direct access to the pins cable. This means that, the system has a way to measure if a pin is pressed or not without any complex data transmission protocol or any sampling issues.
Those controllers are therefore lag-less.
Serial transmission
The next generation of controllers could fit more buttons in few wires using serialization. We can see it used on the NES and SNES controllers as a simplified version. When the system is ready, it sends some kind of a signal to the device this will freeze the state of the device. Then the data is sent bit by bit using a clock and a data wire. This great article details the internal and timing of this mecanism: NES Controller Handler. An illustrated example is shown in the aforementioned 8-bit guy video.
Most of the controllers before USB uses a similar technology. It may be a bit more complex with more words and bilateral data exchange (e.g. the PSX controller), but the idea is always the same.
The lag for those devices depends on the clock speed and the amount of data to transmit but it operates in a synchronous manner. Most will be less than a millisecond.
USB devices
From the XBox and PS3 generation, we started to have a universal use of USB for controllers. However the way that devices are handled is completely different now.
Polling protocol
The general idea is the following:
-
When a device is plugged, the host (meaning the system which receives the controller) queries the device for its descriptor. This will describe what the device does and how to talk to the device.
For instance, it can say that it’s a controller and it will give the bus address to talk to and a polling rate.
- Afterwards, if the host desires to get the status of the device, it can send a request on the desired address every few milliseconds according to the polling rate specifications.
Operating system impact
One of the major change that the USB introduces is that the polling is performed by the operating system regardless of the game engine. On legacy controllers, the controller status is available at the beginning of the game engine tick for the game to handle the change. In this case, the USB polling is completely separated from the game engine clock.
For instance, in case of a 60fps game, the game will read the state of the inputs every 16.6ms, but if the polling rate is 10ms, then assuming that the device has no internal lag, the input state may be 10ms old in the worst case.
The core idea is that the data is always polled by the system at the pace decided by the device. The game engine will read the state at yet another pace.
Additional sampling phases
The usb devices now embeds micro-controllers which are capable of doing plenty of operations. However, it means that the implementation is more complex and prone to bad coding or weak architectures.
Thus, we can now see devices that will not provide data on polling. The device may decide to read its button state on the background into a buffer at a 5ms pace for instance, then the buffer is sent whenever the system polls via USB. Or, the device may decide to read the buttons when the device is polled but the results will be only available on the next polling.
In conclusion, the polling rate is not the only culprit when it comes to device lag. The sampling internals can change and introduce lag penalties of sometimes several milliseconds.
Data parsing and compatibility
It is not directly related to lag but because it is a pain when it comes to measure, so it needs a section.
The USB protocol is a generic one. The first consequence is that it works only if the host knows the language that the device is talking with. Fortunately, there are two known protocols to get the state of controllers: HID (standard) and XInput (microsoft).
Those protocols are now well documented but additional security measures may be introduced by the constructors to restrict the amount of devices compatible with their platforms. For instance, PS4 needs regular packets exchange with encryption to check that the device is certified.
Conclusion & Recommendations
Here is a simplified view of the input lag chain from the controller side, everything that has been presented in this page is depicted:
To avoid lag in controllers, here is a list of important points to watch for:
- Be careful of your polling rate, some devices are slower just because a bad configuration (e.g. the Dualshock 4 is slower on wired compared to bluetooth just because of the polling rate).
- Every additional sampling is bad for lag. Try to keep the polling of the actual button either using a synchronous method on the usb polling or using a fast sampling (500µs is enough).
- Head over to the result sections to compare against known controllers.