Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do game developers avoid TCP and make UDP reliable in the application level?

Many game developers choose to a make UDP reliable in the application level. Isn't that what TCP is made for? I made an API that enables Client-Server communication using UDP and TCP packets. Should I add Reliable UDP to the list? And why? Is there a problem if I use TCP?

I just want to know if RUDP has any benefits over TCP, so that I can choose whether to add RUDP support or not.

like image 954
None Avatar asked Sep 05 '16 03:09

None


1 Answers

Short answer: TCP is not optimized for latency (at all); as a result - it has several properties which are latency killers for games (though they come into play only when a packet is lost). In particular, head-of-line blocking and exponential backoff tend to be very annoying for fast-paced games.

The one which hurts latency the most is head-of-line blocking (a.k.a. HOL blocking): if one packet is lost, all the subsequent packets within the same stream, even if they reach the other side of communication, are not allowed to reach app-level (ouch!), until the lost packet is retransmitted (and this is going to take around 2*RTT, which even for a per-continent Server, is around 100 ms (="in a shooter, you already got killed)).

Long answer:

It is a complicated subject, and we need to distinguish several distinct scenarios:

  1. we DO need reliable ordered message (or byte) stream. In this case, RUDP benefits over TCP, while present, are very minimal (we can play a bit with reducing retransmission times - and eliminate exponential back-off, but that's pretty much it). In particular, head-of-line blocking is still inevitable with ANY kind of reliable ordered streams (whether TCP, RUDP, or whatever else).

  2. we DO need a reliable but potentially-unordered message delivery. This MAY allow to avoid HOL blocking, but requires rather complicated app-level handling.

  3. we DON'T need reliability at all (="fire and forget"). One prime example of such information is when we need to show a bullet hit - if we didn't show it right away, there is no need to show it half a second later, so if the packet didn't make it - well, it is better to just ignore it and not spend resources on re-sending the packet.

  4. we DO need eventually-synchronized state (but we DON'T care about going through all the intermediate states); this is an extremely common scenario for simulations. This IS possible to implement over UDP (and without incurring HOL blocking penalty). However - enabling compression over non-reliable connections is not trivial, and compression is THE MUST for most of the games out there. Fortunately - such compression IS doable (see http://gafferongames.com/networked-physics/snapshot-compression/ and/or http://ithare.com/udp-from-mog-perspective/#low-latency-compression for discussion). If this approach is implemented (which can be done on top of completely unreliable packets) - it will provide VERY significant improvement over TCP (it does eliminate HOL blocking, so we're speaking about delays of the order of network ticks - and this can be as low as 1/120sec~=8ms - over delays-around-RTTs, and these are at least 100ms for one single packet lost).

Side comment:

Actually, it IS possible to simulate UDP over TCP (eliminating TCP latencies) - see http://ithare.com/almost-zero-additional-latency-udp-over-tcp/ . Note though that to utilize it, all the stuff above should be still done manually. There is still no magic bullet which allows to avoid HOL blocking for a reliable-ordered stream; instead - this technique allows to make several TCP connections to behave "almost as if" it is unreliable-but-non-blocking UDP.

like image 65
No-Bugs Hare Avatar answered Oct 01 '22 05:10

No-Bugs Hare