Search code examples
network-programmingmultiplayer

Send inputs immediately to server or in an input cache periodically in network game


I am writing a networked multiplayer game where all inputs that affect gameplay are saved and handled as Events in a queue to make it possible to re-produce all actions given a set of Events. For example: A user presses the left arrow button; then an event with "Press Left" is added to the queue, saved with the current time t, and is then executed using a fixed timestep http://gafferongames.com/game-physics/fix-your-timestep/.

These Events are also sent to a server, that periodically sends out a set of Events received from clients to all other clients, let's say every 100ms. The game is a fast paced multiplayer, so entity interpolation is used as described here: http://www.gabrielgambetta.com/fpm3.html

What would be the best way to send these Events to a server? Would it make sense to send each Event immediately and separately, or to save an "Event cache" on the client, and also on the client periodically send a list of new Events to the server? I'm worried that if I send the Events immediately something could happen with the synchronization of the events, or it could clog up somehow with an excess of messages on the network.

The problem with the Event cache is that I would have to add an extra delay to everything since the events would only get sent every n seconds from the client, and then again every n seconds from the server. What is a tolerated delay for a player from an input is made, to it is executed?

I hope I've made myself clear.


Solution

  • The acceptable delay is really depending on the type of the game. For fast paced games (FPS for example) you would want delay to be as low as possible, and i think that anything that is not immediate is not acceptable in that case.

    You should probably send updates to the server in fixed time intervals but lower them if you can to, let's say, 15-20ms. Between the update intervals you will buffer the commands (events). I don't know what kind of game is it exactly but probably it's better to do the calculation of object states on the client (and display it immediately) and than send the states to the server for validation. For example if we're talking about player movement you would for example send current coordinates and velocity vector and the server will check if provided new coordinates are valid (was it possible to get there from previous point). In the meantime you would display the new coordinates in the client and correct them if needed after server response.

    For networking at those rates the best choice is UDP. Since it's connectionless you need to handle dropped or out of order packets yourself. Depending on the game you might be able to classify your commands as those that must be transmitted reliably and those which do not. Responses from the server can be sent with larger intervals (100ms for example). Back to the example of player movements, if you send your coordinates every 15ms (lets sat at t, t+1, t+2) and if you drop the packet at t+1 you can still interpolate t+1 values from t and t+2 (because server will respond in 100ms intervals) so that kind of things can be transmitted unreliably. But if the player casts a spell, uses an item or something like that you need to make sure that that message reaches the server.

    Your worries about synchronisation and packet loss are valid but those things could (and will happen from time to time) in both scenarios. Anyway i think that it's better to drop one packet with one or two events (smaller intervals) than to drop one packet with tens of them. Also in most network configurations that use QoS smaller packets are less likely to be dropped or delayed. Also depending on the data you are sending to the server, the amount of bandwidth needed might not be that big at all.

    This is kinda a broad question so these are just some things to consider. Some of them are probably explained in the link you provided, and you could also read this