DEV Community

Cover image for Input lag, what's going on?
Jens Andersson for GOALS Engineering

Posted on

Input lag, what's going on?

Input lag, input latency, bad servers, and low tick rate are some of the phrases used to describe unresponsive gameplay. Let’s break it down into smaller parts and talk about where and why this happens, and what we can do to improve the experience.

At GOALS we want to create the best player experience possible, and we know there are no shortcuts to achieving that. GOALS should feel good and responsive to play; there shouldn’t be any delay when you press a button. To make this happen we’re going to build tools that help us measure the delay early on in the development process.

The tests in this article were performed with an Unreal Engine 4 empty project with a dedicated server and one client on a single machine. These values might not be 100% accurate but they will give you some information about where the latency happens. The client was running at 120fps and the server was set to a tick rate of 60. The client FPS and server tick rate for these tests were selected to make it easier to measure and present for the reader.

Hardware

The hardware you use can be a factor for the perceived input lag. We have a controller, mouse, or keyboard connected through Bluetooth, USB, or Wi-Fi. All of these devices have a small delay and it varies between the specific device, polling rate, and connection type. Both Xbox and PlayStation controllers have a small delay but they have a different default polling rate which could cause a bigger variety in the delays. The polling rate of a device is the number of times the operating system/driver will ask for changes. For example, an Xbox 360 controller has a default polling rate of 120 times per second and a Playstation 4 controller of 250 times per second. This means that the Xbox controller has a max delay of 8.3 ms and the Playstation controller 4 ms.

The delay to render a frame on your Monitor or TV can vary between 1 ms and 200 ms. For a new gaming monitor, the delay is very low (usually between 1-2 ms) and for older monitors, it can be around ~2-6 ms. TVs are different, they have a bigger screen and are not optimized for fast rendering. The delay can vary between 14 ms and up to 200 ms. Some new TVs are GSync compatible and have a gaming mode setting where some of the filters are disabled to reduce the delay in rendering. The refresh rate on monitors and TVs differs as well. Monitors have a refresh rate between 60 and 360hz while TVs are between 50 and 120hz. The refresh rate is how often a frame will be drawn on the screen, higher values will make motions appear more smooth and responsive.

Client frame rate table

Frame rate Time per frame Comment
30 33 ms Older TVs and consoles
60 16.7 ms Most common refresh rate
120 8.3 ms
144 6.9 ms
240 4.2 ms

The server tick rate

Let’s take a closer look at how game servers, specifically how tick rate works, and how it affects the responsiveness.

Tick rate is the number of times a server will process input, update the game state, and send updates back to the clients per second. A server at 60 tick rate will process input every 16.7 ms and for a server set to 120 tick rate, it's every ~8.3 ms. A higher tick rate on the server will decrease the time it takes to process the input from the client and update the game logic. This comes at the cost of more processing power and network traffic since more data has to be synchronized and processed.

In a game where the game state is big and there are a lot of changes, the server might not be able to process the entire state more than 30 times per second (30 tick rate), while in a game where the state is really small it might be able to process the game state at 240 times per second without any problem.

The tick rate will affect the input latency between 0 and 1/[tick rate] seconds depending on when the input package arrives at the server.

Internet and networked communication

Multiplayer games over the internet will always have a varied latency and this is due to the connection type, the number of routes between the client and the server, as well as the amount of traffic on that physical line. The Internet is very unreliable and can cause packages to arrive in the wrong order or get lost on the way. When a package is lost the client/server has to decide if it should request a resend or just discard it. This is usually done upfront in the game engine, marking some packages as reliable or unreliable. Reliable packages require the server/client to respond with an ack (acknowledgment) when the package has arrived while the unreliable version is just fire-and-forget, and ignores lost packages.
Input should always be sent as a reliable package since that data should never be lost, while position updates can be sent as unreliable. Resending an old position of a player in the game might be a waste because by the time it reaches the destination the data is old (this varies between different types of games).

When packages are lost some kind of delay will happen, in some cases, the game might appear frozen and in other cases, you might experience that your character did not react to your input fast enough.

Rendering and synchronization

There are a handful of settings that can change how a frame is rendered on the screen to increase performance, reduce the latency, avoid screen tearing, etc. Here’s a brief overview of how they affect performance and the perceived input lag.

A frame can be rendered to the back buffer (the buffer that the display reads) either by writing directly to the buffer, writing to a temporary buffer and copying the buffer when it's ready or to several buffers and just swapping the source. The two latter ones are called double and triple buffering. Both of these will increase the performance of the game since it doesn't write directly to the back buffer but it will also introduce a small latency. (see references for in-depth information about this)

Screen tearing is something that happens when the monitor's refresh rate doesn’t match the frame rate in the game. VSYNC is a way to solve this by keeping the frame rate (writing to the back buffer) in sync with the monitor's refresh rate. This will give the player a very smooth experience with no screen tearing, but it will introduce a small latency on the input since each frame has to wait until the monitor is ready to render it.

GSync/Freesync is a new monitor technology that lets the GPU control how often the monitor should render instead of the other way around. This eliminates both the input lag and the screen tearing and will give the best possible experience. The downside is that it requires special hardware, both the GPU and the monitor must support either GSync(Nvidia) or Freesync(AMD).

The tests in Unreal Engine

We’ve built some simple tools to track the latency from a button press until the server responds with the updates.

The blue bar is the Client and that’s how long it takes for Unreal Engine to register a button click. In Unreal Engine the input is tied to the frame rate, a high frame rate will poll the input more often, lower frame rate will increase the latency. The red bar is the communication to the server where it will package the data, send the package, unpack the data and run the method on the server. The yellow bar is the time it took for the response to come back to the client.

Image description

If we break these down into smaller parts and compare them to what we’ve learned so far: The client is running at 120fps, which means that the input will be polled every ~8.3 ms which would give us an average input delay of ~4 ms. This can be seen in the graph above.
The server tick rate is set to 60 and each input will be read every 16.7 ms (average at ~8.3 ms), this is the red bar in the graph. The server sends the response back to the client and the client reads that response every 8.3 ms (120fps), this is the yellow part.
The worst-case in this scenario is 30 ms between a button click and the code gets run on the client, and the best is below 10 ms.

In the graph below we can see a comparison of how long it takes before a button release event happens (this is a normal click with the thumb on a PS4 controller). This means that if the game reacts on button-up instead of button-down you’ll have a 50-120 ms delay before the input has even been read and processed by the game loop. To reduce the input delay you should do the action on button-down events, this might not be possible in some cases though. For example, in games where you have a double tap or a press+hold, the game code has to wait for a certain amount of time before it can decide which action you’re doing. If you use the same button for a single tap you’ll still have to wait that amount of time before it knows which action you are performing.

Image description

Summary

We’ve talked about the hardware, the software, and the internet. There are a lot of steps between pressing a button until something happens on the screen. In the table below you can see all the steps that happen when you press a button in the test we did. When everything is perfect most of these steps will be very close to 0 and in the worst case it will add up to a high number based on the frame rate, tick rate, internet latency, input device, and rendering settings.

The rendering and display times were not measured by us, these numbers are from tests that can be found in the references section.

Source     Possible Latency   Comment
Input device (controller, keyboard, mouse) 0 - 10 ms The delay in the physical device, the drivers, and the Operating System.
Game loop (Read input) 30 fps = 33 ms
60 fps = 16.7 ms
120 fps = 8.3 ms
The frame rate that the game is running at if the engine polls the input once each frame.
Send input to server 0 - 0.2 ms Packaging/Serializing the data on the client.
Internet/Network > 0 ms This is the time it takes for a package to reach the server (This is not RTT or Ping). This can vary a lot depending on your location and your ISP.
Process input on the server 30 ticks = 0 - 33 ms
60 ticks = 0 - 16.7 ms
120 ticks = 0 - 8.3 ms
The package will be processed every tick on the server, so depending on when it arrives the delay will vary.
Send response to client 0 - 0.2 ms Package/Serializing the data on the server.
Internet/Network > 0 ms Time for a package to reach the client.
Process message on client 30 fps = 0 - 33 ms
60 fps = 0 - 16.7 ms
120 fps = 0 - 8.3 ms
In most game engines the network packages will be processed at the start of the game loop and systems can look at the values in their tick/update function.
Render 0-10 ms Depending on the rendering technique used this can vary between 0 and a couple of milliseconds. It also depends on when in the game loop graphics are processed.
Display on monitor/TV 1 - 200 ms The time it takes for the monitor to show what the GPU has in the back buffer.

There are some things we didn’t mention in this article and that are issues that happen on the server, for example, a short “freeze” on the server that causes the processing time to take longer than it should, disconnects, or dropped packages due to overflow of input, etc.

What can you do?

There are a few things you can do to reduce the perceived input latency.

  • Do some testing with VSync and enable/disable double/triple buffering.
  • If your device supports a higher polling rate you can probably find something in the manual or some online forum on how to increase it.
  • If you’ve got an older Monitor or TV and are considering an upgrade, look for something that is made for gaming.
  • GSync/Freesync/GSync compatible monitors and TVs will make the game look and feel better, make sure your Graphics card supports it.

What will GOALS do?

Some of these things that we’ve talked about are not something that GOALS can do anything about, but there are some parts where we’ll do our best to improve the responsiveness of the game.

The performance on the client and the server is one part that affects the input latency and it's something we can work with. We'll add a lot of telemetry points early in the development of the game so we can track the impact of every change and feature we add. This will give us a better understanding of which parts can be further optimized to achieve a higher frame rate.

There are a lot of different techniques that can be used to improve the perceived latency by predicting the move that the player does, like starting an animation when the button is pressed instead of waiting for the server to approve it. The downside is when the client and server disagree on something and you’ll experience a small rubber-band effect.
We’re going to spend a lot of time testing out different solutions to this problem so that we can give the player a great experience even when the network condition isn’t optimal.

We’ll keep you updated with our progress and share details about how we’re measuring the performance and responsiveness.

Links and References

Monitor/TVs

Monitors Input lag for controllers

Rendering

Top comments (0)