UDP reliable ack system, is it necessary for movement?

Started by
0 comments, last by SeanMiddleditch 9 years, 10 months ago
I wanted to know when it comes to using UDP in a game for real-time movement,
if I should build an ack layer on top of it.
My game uses an 8-directional movement system. And right now I'm sending keypresses/keyreleases. It works completely fine with UDP, but I'm running it locally.
Eventually when players try sending data to my server via my external IP, there are most likely going to be datagrams dropped. So I was thinking of building an ack layer over top of it, which works like this:
My player would send a movement datagram, saying that he moved to the left.
The server may/may not receive this. If it does receive this, the server will then send back an acknowledgement. If the client does not receive this after a certain amount of time (I set an alarm which is equal to double the ping), then we assume the datagram was dropped and we send the exact same data (move left) to the server and the process repeats until we have an acknowledgement.
The same system is implemented on the server in which the server would then send the move packet back to the client to allow it to move, and wait for an acknowledgement. If it doesn't get one, it re-transmits.
So now it comes to my two questions:
1) Is this a fairly efficient system for an acknowledgement system over-top of UDP messages that are required to be sent/received? When it comes to things like movement and actions in real-time in which dropped messages can have an effect on the game/
2) Is this system really necessary? In other words, do I really need to worry about datagrams being dropped?
I've heard that in reality, it really doesn't happen that often, but when you've got a ton of real-time movement data being transmitted back and forth, one would think it would happen.
The thing is, the way my movement system works is, the server is in control of the movement. The client simply sends a keypress/keyrelease and doesn't move the player until the server sends back a movement datagram. I mention this because, if a datagram gets dropped and I don't have any sort of re-transmit system in place, there would be times when the player would press the movement keys and not even move anywhere because a datagram got dropped.
This can be very annoying, and I know games such as Halo use this system (waiting for the server to tell us to move rather than the clients moving on their own).
And games like that, you hardly ever have times where you would press the movement keys and nothing would happen. Most likely because they have some sort of UDP-ack-reliable system implemented overtop of UDP.
So is it worth it to implement an ack system for things like UDP movement? Or should I not even worry about it? I'm not exactly sure on average, how often a datagram is dropped, and if it would heavily interfere with gameplay?
Advertisement

My player would send a movement datagram, saying that he moved to the left.
The server may/may not receive this. If it does receive this, the server will then send back an acknowledgement. If the client does not receive this after a certain amount of time (I set an alarm which is equal to double the ping), then we assume the datagram was dropped and we send the exact same data (move left) to the server and the process repeats until we have an acknowledgement.


How is this any better than just using TCP? If you don't also have sequence numbers and protection against delayed duplicates, this will actually be much worse than TCP (i.e. it's broken).

2) Is this system really necessary? In other words, do I really need to worry about datagrams being dropped?


They will be dropped. Whether you need to worry about it is another question that is highly dependent on all sorts of game-specific factors, like how important it is in your game's architecture to get every message. The server for example can continuously stream positions to the client. If the client misses some of those updates there will be no reason to retransmit them since there will be a new update on its way. The retransmission would be a pointless use of bandwidth just to send stale data.

There are a myriad of ways to get the client inputs up to the server fairly reliably. The client can stream input state or retransmit commands. Queuing a message for every input event and reliably delivering it (with sequencing and retransmission) has many advantages, though it's certainly not the only way. In such a case you will need message sequence IDs and a system to retransmit non-acked messages.

There is going to need to be some advanced logic on both client and server to make the lag (independent of dropped packets!) tolerable. The server needs to deal with the fact that it doesn't know about player input until some time after the player produced that input and the client needs to deal with the fact that it doesn't know what other players did until some time after the server found out. In particular, you may find that you need a model where the player moves instantly on his local client and uses the server updates as hints rather than authoritative positions, as otherwise all player input lags on a round-trip to the server and feels horrible.

I highly suggest you read and then re-read:

http://fabiensanglard.net/quake3/network.php
http://gafferongames.com/networking-for-game-programmers/
http://udn.epicgames.com/Three/NetworkingOverview.html
https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

Note these have some contradictory approaches. There is no best way to do something for all games, so you will need to evaluate the models for your specific game to choose a satisfactory solution. You'll also notice that a considerable amount of thought and effort has to go into hiding lag/latency.

Sean Middleditch – Game Systems Engineer – Join my team!

This topic is closed to new replies.

Advertisement