Improve readability

This commit is contained in:
Paul Pacheco 2019-03-13 22:57:09 -05:00 committed by GitHub
parent 536441f002
commit fd8389bb97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,11 +1,7 @@
# Why TCP by default and not UDP?
## The same old Discussion
It's the year 2019 and every game developer swears by UDP. Yet we chose TCP as default for Mirror. Why is that?
UDP vs. TCP, the technical aspects
First of all, a quick word about the major differences between UDP and TCP.
- UDP has lower latency, unreliable and hard to use correctly
@ -13,19 +9,19 @@ First of all, a quick word about the major differences between UDP and TCP.
## TCP (Transmision Control Protocol)
[Tcp](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Congestion_control) is a protocol built on top of IP. It is by far the most popular protocol on the internet. Everything you are seeing in this page was sent to your browser via TCP. It is designed to be simple to use, scalable and for transmiting large amounts of data.
[Tcp](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Congestion_control) is a protocol built on top of IP. It is by far the most popular protocol on the internet. Everything you are seeing in this page was sent to your browser via TCP. It is designed to be simple to use and scalable.
A server opens a port and waits for connections. Clients send an initial message to establish the connection (handshake) and after that a connection is considered established. Data flows both ways as a stream, one byte after another, always in the right order, without missing anything. Some of the key features include:
Servers open a TCP port and wait for connections. Clients send an initial message (handshake) to establish the connection then send data. Data flows one byte after another, always in the right order, without missing anything. Some of the key features include:
* Reliable: if you try to send data, it will either make it to the other end, or you will get an error, nothing is ever silently dropped.
* Fragmented: Your network card cannot just send 1 MB of data, it can only send small packets of 1.5Kb or less. If you try to send a lot of data, TCP will split your data into small packets and reassemble the data on the receiving end.
* Sequenced: If you send data a,b,c in that order, TCP guarantees that it will arrive in the same order or an error will be generated.
* Connection oriented: you don't just send data, TCP will send a message first to let the server know that they will be talking together. Both the client and server can disconnect and react to the disconnection.
* Reliable: if a packet gets lost, TCP will resend it. All data is either transmitted successfully or you get an error and the connection is closed. Applications don't have to worry about missing packets.
* Fragmented: network cards cannot just send 1 MB of data. They can only send small packets of 1.5Kb or less. If a lot of data is sent by the application, TCP will split it into small packets and reassemble the data on the receiving end.
* Sequenced: If you send data "a" and "b" you will not receive "b" and "a". TCP guarantees that every byte will arrive in the same order it was sent.
* Connection oriented: TCP has the concept of a connection. A client sends an initial handshake message. A connection is considered established until either the client and server decides to disconnect. Both the client and server get notified when the connection ends and can react accordingly, for example saving and destroying player object.
* Congestion control: If a server is being overwhelmed, TCP will throttle the data to avoid congestion collapse.
These are great features that make it very easy for programmers to work with TCP, but they come at a cost: Latency.
Suppose an object is moving from point a to b to c. Our server sends 3 messages: a, b, c. Suppose b gets lost (wify drops a lot of packages for example) and c arrives fine. We could skip b and move towards c instead, but we can't because the operating system won't give us c until b is retransmited.
Suppose an object is moving from point a to b to c. The server sends 3 messages: move to a, b, c. Suppose b gets lost (wify drops a lot of packages for example) and c arrives fine. We could skip b and move towards c instead, but we can't because the operating system won't give us c until b is retransmited.
For this reason, AAA studios consistently prefer UDP for fast paced action games.
@ -33,13 +29,13 @@ For this reason, AAA studios consistently prefer UDP for fast paced action games
[UDP](https://en.wikipedia.org/wiki/User_Datagram_Protocol) is also a protocol based on IP. It is used for real time applications such as fast paced action games or voice over ip, where low latency is more important than reliability.
A server opens a port and waits for messages. Clients send messages to such port, and the server may send messages back. Data flows in both ways as individual messages.
A server opens a port and waits for messages. Clients send messages to the port, and the server may send messages back. Data flows in both ways as individual messages.
There is no concept of connection, so there is no built in way to determine if a client disconnects. Messages are delivered as soon as possible, there is no guarantee that the order will be preserved or that they will be delivered at all. Messages must be small, typically 1.5Kb or less.
Mirror does need reliability, fragmentation, sequenced, connections for many things, so we would not use raw UDP. We would use a library that implements those features on top of UDP such as [ENet](http://enet.bespin.org/), [LiteNetLib](https://github.com/RevenantX/LiteNetLib) or LLAPI, typically refered to as RUDP (Reliable UDP)
The obvious question is: do RUDP libraries just reinventing TCP? yes, to some degree they do. But the point is that those features would be optional and we would be able to send messages without the extra features for low latency data such as movement or voice.
The obvious question is: do RUDP libraries just reinventing TCP? yes, to some degree they do. But the point is that those features are optional and we can send messages without the extra features for low latency data such as movement or voice.
## Dark ages
@ -64,5 +60,5 @@ That's why we made Telepathy and Mirror. **Life is short. We just need the damn
We acknowledge not everyone will agree with our reasoning. Rather than push our views on users, we made Mirror transport independent. A few months later, Unity did the same thing. You can easily swap out the transport for one of the several RUDP implementations simply by dragging it into your NetworkManager gameobject. Pick whatever works best for you. We recommend you profile your game and collect real world numbers before you make a final decision.
After we made Mirror transport independent, the community stepped up and several RUDP transports have been adapted to work with Mirror as we hoped. While the default is Telepathy (simple "just works" TCP transport), you can choose any of [these](../Transports) transports or even write your own.
After we made Mirror transport independent, the community stepped up and several RUDP transports have been adapted to work with Mirror. While the default is Telepathy (simple "just works" TCP transport), you can choose any of [these](../Transports) transports or even write your own.