Gamasutra is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Gamasutra: The Art & Business of Making Gamesspacer
View All     RSS
February 25, 2020
arrowPress Releases

If you enjoy reading this site, you might also want to check out these UBM Tech sites:


UNET Unity 5 Networking Entity Interpolation Part 2 of 6 - Clientside Input Buffering

by Christian Arellano on 11/04/16 01:50:00 pm   Featured Blogs

9 comments Share on Twitter    RSS

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.


In this article, we will implement a way of reducing the frequency at which clients send inputs to the server, in the same way that SyncVars are capped at 10 updates per second. We will do this by buffering inputs and sending them out at a given frequency. This way, we get transmission rate throttling for both inbound and outbound data, and more control over how we utilize network bandwidth.

Because of the way we split our networking code into smaller components in the previous article, it should be relatively easier for us to add our changes without having to wrangle through too much code.

Download The Source Code

If you haven't already, you can download the source code for this article. Also included in the download are the project folders for the upcoming articles in this series, so if you want to, you can skip ahead and see how the full entity interpolation implementation looks like.

Buffering Commands

In Unity Networking, clients send input information to the server using Commands. Without buffering, what we did instead was call the corresponding Command every time input is made, potentially causing the client to call Commands on the server during every frame.

With input buffering, we take a different approach. When input is generated, instead of calling the corresponding Command immediately, we place the input in a buffer:

// in Awake ():
List<Vector2> inputBuffer = new List<Vector2> ();

// in FixedUpdate ():
Vector2 input = /* poll input device here */;
inputBuffer.Add (input);

Immediately after we buffer the captured input, we check to see if the buffer is full. If it is, we call the appropriate Command and send the buffered inputs to the server.

// Since FixedUpdate runs at 50 times a second,
// we set inputBufferSize to 5 so that we can send
// our inputs to the server at 10 times a second.
public int inputBufferSize = 5;

// back to FixedUpdate ():
if (inputBuffer.Count < player.inputBufferSize) return;
player.CmdMove (inputBuffer.ToArray ());

// don't forget to make room for new inputs!
inputBuffer.Clear ();

Batching on the Server

Since we're now sending multiple inputs at a time to the server, we have to change our Command's function signature so that it can accept arrays:

[Command(channel=0)] public void CmdMove (Vector2[] inputs) {
    server.Move (inputs);

Once we receive the inputs on the server, we can apply them all in one go by iterating on the inputs array (similar to how we do client side prediction and server reconciliation):

public void Move (Vector2[] inputs) {
    CubeState serverState = player.serverState;
    foreach (Vector2 input in inputs) {
        serverState = CubeState.Move (serverState, input);
    player.serverState = serverState;

And that does it for buffering!

Choppy Movement

When controlling your own player object, client prediction does a very good job of making sure that the experience always stays smooth and responsive. However, by introducing input buffering, other players will not see you in the same way that you see yourself! Since inputs are received at a low frequency and applied in batches, your movement will probably look choppy. You won't necessarily be slower; in fact you would probably move at the same speed as everyone else. However, visually it will seem that you're being rendered at a lower frame rate. This is expected - once we add interpolation in, your movement should become smooth again.

Speed Hacks

Our current implementation has a flaw that cheaters can take advantage of. Can you spot it?

What happens if the client sends more than 5 inputs in a single Command? What if it sends 10, or 50, or more? When the server receives the batched inputs, it accepts and applies all of them at the same time, regardless of the number of inputs received. This allows the client to make more moves than it should be allowed to in a given time frame. The server could potentially let you take 100 steps when you would normally be allowed to take only 5 steps, giving you an unfair advantage over other players. In multiplayer games, this is called a "speed hack," and we will look into how we can prevent this in the next article.

To see all of this in action on your own machine, be sure to download the project folder for this article! Thank you for reading, and until next time.

Related Jobs

Purdue University
Purdue University — West Lafayette, Indiana, United States

Assistant Professor in Game Development and Design
Vicarious Visions / Activision
Vicarious Visions / Activision — Albany, New York, United States

Senior Software Engineer
Sucker Punch Productions
Sucker Punch Productions — Bellevue, Washington, United States

Gameplay Programmer
Airship Syndicate
Airship Syndicate — Austin, Texas, United States

Mid to Senior Programmer

Loading Comments

loader image