UDP vs. TCP
Introduction
Hi, I’m Glenn Fiedler and welcome to the first article in my online book Networking for Game Programmers
In this article we start with the most basic aspect of network programming, sending and receiving data over the network. This is just the beginning – the simplest and most basic part of what network programmers do, but still it is quite intricate and non-obvious as to what the best course of action is. Take care because if you get this part wrong it will have terrible effects on your multiplayer game!
You have most likely heard of sockets, and are probably aware that there are two main types: TCP and UDP. When writing a network game, we first need to choose what type of socket to use. Do we use TCP sockets, UDP sockets or a mixture of both?
The choice you make depends entirely on what sort of game you want to network. So from this point on, and for the rest of this article series, I’m going to assume you want to network an action game. You know games like Halo, Battlefield 1942, Quake, Unreal, CounterStrke, Team Fortress and so on.
In light of the fact that we want to network an action game, we’ll take a very close look at the properties of each type of socket, and dig a bit into how the internet actually works. Once we have all this information, the correct choice becomes very clear!
TCP/IP
TCP stands for “transmission control protocol” and IP stands for “internet protocol”. Together they form the backbone for almost everything you do online, from web browsing to IRC to email, its all built on top of TCP/IP.
If you have ever used a TCP socket, then you’ll know that it is a reliable connection based protocol. This simply means that you make a connection between two machines, then you send data between the two computers much like you are writing to a file on one side, and reading from a file on the other.
This connection is reliable and ordered, meaning that all data you send is guaranteed to arrive at the other side in the same order that you wrote it. Its also a stream of data, meaning that TCP takes care of splitting up your data into packets and sending those across the network for you.
Again, remember its just like writing to a file. So simple!
IP
The simplicity is in stark contrast to what actually goes on at the lower level “IP” protocol underneath TCP.
Here there is no concept of connection, instead packets are passed from one computer to the next. You can visualize this process like a hand-written note being passed from one person to the next across a crowded room, eventually reaching the person it is addressed to, but only after passing through many hands.
There is no guarantee that this note will actually reach the person it is addressed to. The sender just passes the note along and hopes for the best, never knowing whether or not the note was received, unless the other person decides to write back!
Of course, it is in reality a little bit more complicated than this, since of course no one computer knows the exact sequence of computers to pass the packet along to so that it reaches its destination quickly. Sometimes “IP” passes along multiple copies of the same packet, these packets make their way to the destination via different paths, so will most likely arrive at different times.
This is because the internet is designed to be self-organizing and self-repairing, able to route around connectivity problems. It’s actually quite cool if you think about what it is really going on at the low level. You can read all about this in the classic book TCP/IP Illustrated.
UDP
Instead of treating communications between computers like writing to files, what if we want to send and receive packets directly?
We can do this using UDP. UDP stands for “user datagram protocol” and it is another protocol built on top of IP, just like TCP, but this time instead of adding lots of features and complexity it is just a very thin layer over IP.
With UDP we can send a packet to a destination IP address (eg. 112.140.20.10) and port (say 52423), and it will get passed from computer to computer until it arrives at the destination computer or is lost along the way.
On the receiver side, we just sit there listening on a specific port (eg. 52423) and when a packet arrives from any computer (remember there are no connections!), we get notified of the address and port of the computer that sent the packet, the size of the packet, and can read the packet data.
UDP is an unreliable protocol. In practice, most packets that are sent will get through, but you’ll usually have around 1-5% packet loss, and occasionally you’ll get periods where no packets get through at all (remember that there are lots of computers between you and your destination where things can go wrong…)
There is also no guarantee of ordering of packets. You could send 5 packets in order 1,2,3,4,5 and they could arrive completely out of order like 3,1,2,5,4. In practice, they will actually arrive in order almost all of the time, but again, you cannot rely on this!
Finally, although UDP doesn’t do much on top of IP, it does make one guarantee for you. If you send a packet, it will either arrive in whole at the destination, or not arrive at all. So if you send a 256 byte packet to another computer, that computer cannot receive just the first 100 bytes of the packet, it must get the full 256 bytes of data. This is pretty much the only guarantee you get with UDP, everything else is up to you!
TCP vs. UDP
We have a decision to make here, do we use TCP sockets or UDP sockets?
Lets look at the properties of each:
TCP:
- Connection based
- Guaranteed reliable and ordered
- Automatically breaks up your data into packets for you
- Makes sure it doesn’t send data too fast for the internet connection to handle (flow control)
- Easy to use, you just read and write data like its a file
UDP:
- No concept of connection, you have to code this yourself
- No guarantee of reliability or ordering of packets, they may arrive out of order, be duplicated, or not arrive at all!
- You have to manually break your data up into packets and send them
- You have to make sure you don’t send data too fast for your internet connection to handle
- If a packet is lost, you need to devise some way to detect this, and resend that data if necessary
The decision seems pretty clear then, TCP does everything we want and its super easy to use, while UDP is a huge pain in the ass and we have to code everything ourselves from scratch. So obviously we just use TCP right?
Wrong.
Using TCP is the worst possible mistake you can make when developing a networked game! To understand why, you need to see what TCP is actually doing above IP to make everything look so simple!
How TCP really works
TCP and UDP are both built on top of IP, but they are radically different. UDP behaves very much like the IP protocol underneath it, while TCP abstracts everything so it looks like you are reading and writing to a file, hiding all complexities of packets and unreliability from you.
So how does it do this?
Firstly, TCP is a stream protocol, so you just write bytes to a stream, and TCP makes sure that they get across to the other side. Since IP is built on packets, and TCP is built on top of IP, TCP must therefore break your stream of data up into packets. So, some internal TCP code queues up the data you send, then when enough data is pending the queue, it sends a packet to the other machine.
This can be a problem for multiplayer games if you are sending very small packets. What can happen here is that TCP may decide that its not going to send data until you have buffered up enough data to make a reasonably sized packet (say more than 100 bytes or so). This is a problem because you want your client player input to get to the server as quickly as possible, if it is delayed or “clumped up” like TCP can do with small packets, the client’s user experience of the multiplayer game will be very poor. Game network updates will arrive late and infrequently, instead of on-time and frequently like we want.
TCP has an option you can set that fixes this behavior called “TCP_NODELAY”. This option instructs TCP not to wait around until enough data is queued up, but to send whatever data you write to it immediately.
Unfortunately, even if you set this option TCP still has serious problems for multiplayer games.
It all stems from how TCP handles lost and out of order packets, to present you with the “illusion” of a reliable, ordered stream of data.
How TCP implements reliability
Fundamentally TCP breaks down a stream of data into packets, sends these packets over unreliable IP, then takes the packets received on the other side and reconstructs the stream.
But what happens when a packet is lost? What happens when packets arrive out of order or are duplicated?
Without going too much into the details of how TCP works because its super-complicated (please refer to TCP/IP Illustrated) in essence TCP sends out a packet, detects when that packet was lost, then resends that lost packet to the other machine. Duplicate packets are discarded on the receiver side, and out of order packets are resequenced so everything is reliable and in order.
The problem is that if we were to attempt to synchronize this using TCP, whenever a packet is dropped it has to stop and wait for that data to be resent. Yes, even if more recent data arrives, that new data gets put in a queue, and you cannot access it until you receive the lost packet. How long does it take to resend the packet? Well, it is going to take at least round trip latency for TCP to work out that data needs to be resent, and another one way trip from the sender to the receiver for the resent packet to get there. So if you have a 125ms ping, you will be waiting roughly 1/5th of a second for the packet data to be resent at best, and in worst case conditions you could be waiting up to half a second or more (consider what happens if the attempt to resend the packet fails to get through?) Fun times!
Why you should never use TCP to network a multiplayer game
The problem with using TCP for games is that unlike web browsers, or email or most other applications, multiplayer games have a real time requirement on packet delivery. For many parts of your game, for example player input and character positions, it really doesn’t matter what happened a second ago, you only care about the most recent data.
Consider a very simple example of a multiplayer game, some sort of action game like a shooter. You want to network this in a very simple way. Every frame you send the input from the client to the server (eg. keypresses, mouse input controller input), and each frame the server processes the input from each player, updates the simulation, then sends the current position of game objects back to the client for rendering.
So in our simple multiplayer game, whenever a packet is lost, everything has to stop and wait for that packet to be resent. On the client game objects stop receiving updates so they appear to be standing still, and on the server input stops getting through from the client, so the players cannot move or shoot. When the resent packet finally arrives, you receive this stale, out of date information that you don’t even care about! Plus, there are packets backed up in queue waiting for the resend which arrive at same time, so you have to process all of these packets in one frame. Everything is clumped up!
Unfortunately, there is nothing you can do to fix this behavior with TCP, nor would you want to, it is just the fundamental nature of it! This is just what it takes to make the unreliable, packet-based internet look like a reliable-ordered stream.
We don’t want a reliable ordered stream.
We want our data to get as quickly as possible from client to server without ever having to wait for lost data to be resent.
This is why you never use TCP for networking a multiplayer game.
Wait? Why can’t I use both UDP and TCP?
For realtime game data like player input and state, only the most recent data is relevant, but for other types of data, say perhaps a sequence of commands sent from one machine to another, reliability and ordering can be very important.
The temptation then is to use UDP for player input and state, and TCP for the reliable ordered data. If you’re sharp you’ve probably even worked out that you may have multiple “streams” of reliable ordered commands, maybe one about level loading, and another about AI. Perhaps you think to yourself, “Well, I’d really not want AI commands to stall out if a packet is lost containing a level loading command – they are completely unrelated!”. You are right, so you may be tempted to create one TCP socket for each stream of commands.
On the surface, this seems like a great idea. The problem is that since TCP and UDP are both built on top of IP, the underlying packets sent by each protocol will affect each other. Exactly how they affect each other is quite complicated and relates to how TCP performs reliability and flow control, but fundamentally you should remember that TCP tends to induce packet loss in UDP packets. For more information, read this paper on the subject.
Conclusion
My recommendation then is not only that you use UDP, but that you only use UDP. Don’t mix TCP and UDP, instead learn how to implement the specific pieces of TCP that you wish to use inside your own custom UDP based protocol.
The rest of the articles in this series show you how to do this, from creating your own virtual connection based protocol on top of UDP, to creating your own reliability and flow control.
But next, something much more concrete: how to send and receive packets using UDP
Enjoy!
{ 49 comments… read them below or add one }
Conclusion:
That’s why all major MMORPG uses TCP…
Did you ever develop a real time online game? If so, you’ll see that the TCP is good enough to make one and UDP will not add better performances compared to the time you need to rewrite a good protocol on UDP.
Um, you’re an idiot.
Do you even understand what he is saying? This guide is pretty fucking stupid, as are you for following it word for word. TCP is great, and unless you’re writing an FPS, it performs perfectly fine. My question is how low your IQ would have to be to listen to this guy when he says “Even with Nagle’s algorithm disabled, TCP still does bad fuck TCP” (paraphrased)? How does it do bad?
Do you understand what Nagle’s algorithm really does? Turning it off does not stop TCP waiting for lost packets to be resent – it just turns off the code that coalesces small packets into one large packet on the send side.
http://en.wikipedia.org/wiki/Nagle's_algorithm
Even with Nagle’s algorithm disabled my points about TCP’s behavior under packet loss still stand. When a packet is lost TCP must wait for that packet to be resent. While waiting any other (out of order) packets received are held hostage in a queue so that the data transmission looks like a reliable ordered stream.
The only way to avoid this is to use UDP.
Anon:
UDP is standard technique for action games. All FPS and action games use UDP. Its such standard practice that UDP vs. TCP is always the first question I ask in a network programmer interview
Not convinced? Ok fine, lets look at the games that use UDP then: tribes, quake, unreal, starwars battlefront, battlefield 1942, halo, gears of war, team fortress 2, COD4… yes, pretty much all of the top-tier action game use UDP.
Now, regarding MMOs i have heard some of them use TCP fine and get away with it. But remember that MMOs don’t have the same characteristics as an online action game. I’ve not worked on an MMO, but I’d guess in this case they would have lower frequency updates based around a reliable-ordered stream of commands, whereas action games are based around high frequency updates of most recent state.
Given that this article series is about networking action games and not about networking MMOs, I think we can all move forward in the knowledge that UDP is the right way to go, in context
cheers
if you have something such as a attack command (user fires a shot, swings their sword, etc), do you implement some kind of lossless UDP? Or, is their perhaps another model?
these things map well to reliable events. basically keep sending the event at some desired rate (more frequently = more time critcial info) until you receive an ACK for one of the packets which the event was sent in.
read the article or reliability and flow control later on in the series for more info about how to setup an ACK system over UDP
cheers
@Glenn:
Well laid out article, as most of yours seem to be.
I suggest you remind people that using a client’s IP address is not a reliable token to base a session on.
I mention this due to I’ve seen it overlooked many times before, resulting in a myriad of possible exploits due to the relative ease of session hijacking.
@Anon:
Because it’s totally implausible that those developers most likely don’t have the resources/time/know-how to develop a custom transport protocol; right? Lets not disregard the fact a good percentage of programmers are just afraid of the unknown, for whatever reason and would prefer to just stick to standards like sheep due to their own ineptitude.
yes absolutely i should add a small note about security and NAT, the idea would be to use a session id and a packet hash based on some secure crypto
this also helps with NAT because some routers like to dynamically reassign port on the fly for some reason, i’ve heard
cheers
“That’s why all major MMORPG uses TCP…”
My understanding of why MMORPG etc use TCP over UDP (this is from reading blogs of network programmers from these types of games) is that data is more important than anything else where as in a fast paced game (FPS for example) the most recent data snapshot is most important.
“That’s why all major MMORPG uses TCP…”
How many fast-action, no-mouse-click-based MMORPGs use TCP?
For a point n’ click MMORPG it’s great to use TCP, plus, you can always see people complaining about lag on the global chat
“How many fast-action, no-mouse-click-based MMORPGs use TCP?”
Quite a lot of them. Including World of Warcraft.
Game-state in MMOs is a pretty complex affair, meaning you often just send incremental updates of specific bits of data for your game objects, and not sync out the whole state. Interdependencies of data can also grow pretty strong. For most data, reliable ordering is a necessity.
Some MMOs actually do use both TCP and UDP, with most traffic going over TCP and things like position updates going over UDP. Dark Age of Camelot did this, for example.
Quick list found via some Googling:
UDP: Everquest, City of Heroes, Star Wars Galaxies, Ultima Online, Asheron’s Call, Final Fantasy XI
TCP: World of Warcraft, Lineage I/II, Guild Wars, Ragnarok Online, Anarchy Online, Mabinogi, Age of Conan
TCP + UDP: Dark Age of Camelot (and I’m going to assume Warhammer Online as well, due to being the same engine and company.).
Vinterstum, how many FPS games use TCP?
Reasonably few, I’d imagine. Very different beasts, with different latency tolerances in gameplay. I was just addressing the MMORPG question specifically
.
OMG!
I’ve been stumbling around in a quagmire of technology for almost 2 months. And FINALLY, I find your site which DIRECTLY addresses all the important questions.
Thank You!
thanks, really nice and useful post, helped me a lot for my college work. cheers
Thank you, I’m not a game developer, but I find some of your articles very interesting.
Speaking as a network researcher and not a game developer, the conclusion to never use TCP and UDP together seems a bit strong. TCP will only have packet loss if it is sending too much data; in some ways just like the UDP data you are sending. The difference is you have no direct control on the rate TCP sends at, this is hidden to you.
If you just need to send some reliable data and do not want to worry about retransmission and implementing a reliable protocol, and you know the rate will be low, then there wont be any problems with using both TCP and UDP.
The relationship isn’t all that complex between the two really: TCP merely increases its send rate (if there is data to send) until it gets packet loss, in which case it dials back its rate, then starts increasing the rate again (this time more slowly). When its increase in rate causes packet loss, it is quite likely to hit any other streams of data as well, including your UDP packets.
agreed. the point i am making in this article is that you should not use TCP and UDP together for the *bulk* of your protocol data, for example lets say 50% of your data is reliable, 50% is unreliable — and together these sum up to something close to the available bandwidth …
in this case, you can get a bit stung by your TCP vs. UDP, for example assuming TCP needs to do resends, so you can go over the bandwidth required, and you start inducing packet loss in UDP, then your TCP dials back of course — but you’ve now lost a packet that needs to be resent, so your reliable events are delayed
the point is that this condition is entirely avoidable by doing everything inside UDP, because you can ensure that you have a flat bandwidth profile, say 256byte packets 30 times a second, that always stays under the available bandwidth – no matter what is going on, so worst case within your internal reliable protocol, some events are throttled and arrive a (tiny) bit late, but your bandwidth doesn’t increase under poor conditions (no resends)
now, of course if you just had the occasional event sent via TCP, and the bulk of your time sensitive data in UDP, no problems at all
cheers
UDP for FPS games – no question.
A collection of possibly interesting papers and reports on various aspects of FPS games and their network traffic patterns can be found at http://caia.swin.edu.au/genius/ (also some papers on server discovery issues, and player tolerance of latency)
Awesome article and discussion.
It is great to hear the views with the ‘fors & againsts’.
Some more thoughts on TCP vs. UDP:
* In network protocol design, be careful to optimize for the “normal” case, not the error cases. Think about how often a packet is actually dropped, and whether it is your own fault. Do you want to buy into a lot of protocol design (no matter how much fun that might be) to support the few users that are stuck on a low bandwidth connection?
* Surprisingly UDP tends to drop packets because the application uses more bandwidth than the user’s ISP connection can handle or if the app doesn’t drain the local buffers more often. Backbone WAN connections almost never need to throw something away. UDP packets are pretty much never lost on a LAN.
* From your app, you can tune the TCP stack to not have such large delays in transmitting a send request removing a *log* of latency. If you don’t overload the connection resending isn’t as big an issue as you might think.
* Look into TCP_NODELAY (http://en.wikipedia.org/wiki/Nagle%27s_algorithm)
* It is “hard” to get all this stuff working right if you build a custom protocol over UDP: bundling (reducing header overhead), rate limiting, congestion control, packet splitting, prioritization, connection error detection, …
* Be very sure your latency requirements do demand all that investment. It is a slippery slope. Start with latency hiding techniques (predictive contracts, optimistic client movement and fixup when the server responds…), they may wind up good enough. You may even be able to change your game design to not require so much finesse. Bioware survives very well just using dice.
* Data centers prioritize TCP and UDP differently. WAN switches have a lot of different modes. You may find your low priority stuff accidentally choking the stuff you wanted at high priority. These WAN level priorities are different in Asia than in the US.
all good points darrin, thanks for your advice
but what about the problem with getting past firewalls? when a TCP server accept()s, can you have any control over the port number it chooses? if not, how can the client properly set up his router to allow port forwarding to his gaming PC? I know UDP can and must define the port for send and recv; so there’s no arbitrary port number assignments.
If anyone can show me how to bind the TCP sockets on both ends of the connection (client and server), I’d be happy to try TCP.
thanks
I can think of a good reason to go with TCP over UDP, so perhaps your “never” could use a qualifier. Flash currently only supports TCP. So if you want to make a multiplayer game for Flash clients, you’ll need to do it over TCP (or HTTP which is of course even worse, speed wise).
that’s a fair point – but i’d consider it a great reason *not* to use Flash instead
when do you think they’ll fix that? it’s madness – 2009, and you can only use TCP in your flash application? *boggle*
Some additional informations about Darrin West’s remarks:
- there are several ‘action’ games made in Flash (so using only TCP) which do behave very well.
Some good examples: the website omgpop.com which includes a bomberman-like and a mario-kart like game. I even saw once a flash FPS (2D graphics, top view, don’t remember his name) which was behaving ok too.
- Another example: Skype, which falls back to a TCP based protocol when UDP is not suitable (behind a proxy, …). It is still acceptable even if voice streaming typically has ‘real time’ needs too.
- Last but not least: in a client/server ‘star’ topology, TCP leads to an higher connexion success rate. For example, people behind a proxy have almost no chance to use UDP while TCP may be suitable (like corporate or university networks).
To be clear: I’m of course not saying that UDP is crap and TCP is heaven: typically UDP remains the best choice for FPS games. On the other hand I think it’s quite important to not let beginners think UDP is the ONLY way to do things.
A bomberman game, a car racing game, a FPS and a pong game don’t have the same requirements, and in some cases (when UDP is not an option like in flash, or when you don’t want to loose too much time in protocol design) TCP may be a really good compromise.
Darrin West said that better than me. His two remarks (“It is “hard” to get all this stuff working right” and “Be very sure your latency requirements do demand all that investment”) are really important and must be carefully considered before making a choice.
Best regards,
Nouk²
PS: sorry for my bad english
Dude, check this out: An Empirical Evaluation of TCP Performance in Online Games:
http://mmnet.iis.sinica.edu.tw/publication_detail.html?lang=EN&key=chen06_tcp
According to the paper, TCP is not suitable for online games even for slow-paced games like MMORPG.
Anon, I think you should rather make your own tests than only relying your judgement on articles readen among the web.
You may want to check too already existing online action flash games like those of omgpop.com, or even WoW to see that TCP usability in arcade multiplayer games can be a choice too.
Everything is not fully black or white.
I think that’s also true for the limit between usage of TCP and/or UDP in games.
My 2 cents.
I think it’s pretty fair point to look at that article and conclude that TCP is probably not a good choice. If you would like to refute the points raised in the article and the research supporting it – go right ahead, but I hardly think it’s fair to tell somebody to ignore research and “make your own tests” when the research is in fact doing exactly that… testing how TCP performs in a real world situation.
Not only the papers deals only with one specific type of game (MMORPG) whereas Anon concludes it’s the same for all multiplayer games, which is wrong.
But also the paper only deals with the advantages of UDP over TCP, but this paper’s goal has neven been to give an objective comparison, as there are no mention about udp drawbacks.
Finally, I already gave a few arguments in my previous post (9 oct), and I’m still waiting counter arguments
Some points on this paper:
- their tests assume a bandwith of a few hundreds kilobits/sec, which is clearly insufficiant and probably leads to packets drops. This is not the case in the real life where the backbone and game servers are typically well dimensionned to support the amount of traffic received and sent.
- their tests have also been performed with a loss packet rate of 4% ! I never encountered such high packet loss rate in my life (except if I unplug my network card
). Concretely, that means for their data sent 8 times per second (their testing base), something like one loss happend every 3 seconds ! This is even not coherent with their remark a few line before telling that some clients never encountered packet loss during the whole testing session.
For sure, as the biggest advantage of UDP over TCP is when you encounter packet losses, their result can only give a big advantage on UDP compared to TCP. But such network condition are purely theorical and never met in real life. Packet losts are the exception, not the common behavior. And as long as there is no packet loss, TCP behaves globaly as well as UDP.
> ” there must be some reason to use TCP in MMOs, and that paper seems to directly counter that argument ”
Blizzard did it for WoW (I mean using TCP). And we cannot reasonably tell that Blizzard is a company which is technically incompetent. So they had inevitably good reasons for using TCP.
Last but not least, about technical things which are not present in the paper:
- UDP is not as well routable as TCP on the net, especially behind NATs, Proxies, Firewalls, … That’s a fact and one more reason that makes some ‘real time’ application embed kind of ‘degraded mode’ to be used (and working) over TCP when UDP is not routable. Skype protocols are a good example : Skype makes use of TCP in environments that don’t accept UDP connexions, and it works almost ‘seamlessy’.
- UDP requires a LOT more technical knowledge to be used in a networked game than TCP. This is much more efforts to implement a complete unbugged network engine compared to TCP. The time you spent on this part of the project is time lost for other parts of it.
The real questions are:
- is UDP mandatory for my ‘real time networking needs’ ? I would say that in 90% of gmae projects (I mean almost all games except FPS like ones), this is not absolutely necessary. TCP will behave (very) well too.
- If UDP is not mandatory, will UDP be so much better than TCP that it could be interresting to spend much more time on the network engine instead of other parts of my project ? The answer also depends on the type of ‘real time networking’ you need, but generally no.
My 2 cents.
fair points, but in general I’m only interested in real time networking – so I always use UDP. if you want to make a non-realtime solitaire game then sure, TCP is probably fine
That’s exactly why i commented this article: saying that UDP is mandatory for real time networked games is just TOTALLY WRONG. TCP can fit in most ACTION games (and not only turn based games) and will save a lot of effort for the developper for almost the same result.
As a proof, I already mentionned several sample links of REAL-TIME GAMES with real-time actions and real-time interactions between players (omgpop.com, …). They use TCP (the only protocol allowed in flash) in their flash games: bomberman-like, mariokart-like, … which are far from being turn-based (solitaire)
So:
- NO TCP is not only for turn based games (is WoW a solitaire-like ?) ; it will fit most of real-time networked games too (again: except FPS).
- YES TCP is internally a bit worst than UDP for this purpose, but in real life it is un-noticeable for the player and it saves a lot of efforts to the developpers.
I strongly disagree. If you have a realtime game, then by definition certain information needs to arrive as quickly as possible, for example object state updates in a FPS. If you use TCP as a transport when a packet is lost you must wait for old data to be resent before you can receive the most recent state which you are interested in.
This problem can be avoided by using UDP instead of TCP and developing a simple reliability layer on top of UDP. I don’t believe that implementing a reliability layer is beyond the level of ability of a typical professional game programmer, but even if it was, there are plenty of libraries that will do it for you: Raknet, ENet, Torque etc.
You point to flash games as some sort of proof of concept, and in the same sentence mention that it is the only protocol allowed in flash. Have you considered that perhaps the only reason these games use TCP is because they have no choice?
then, why a AAA+ company like Blizzard decided to use TCP for a 10+ millions player’s game if TCP doesn’t fit realtime game requirements for their MMORPG ?
I suppose they had enough knowledge to implement a protocol over UDP. If they decided to use TCP, they must had good reasons to do so. Isn’t it ?
They probably do have a good reason, but this article is not about how to write an MMO, it’s about how to network action games.
From the introduction to this article:
“The choice you make depends entirely on what sort of game you want to network. So from this point on, and for the rest of this article series, I’m going to assume you want to network an action game. You know games like Halo, Battlefield 1942, Quake, Unreal, CounterStrike, Team Fortress and so on.”
So let’s stop arguing this point because it’s not even remotely related to the content of this article.
In conclusion:
1. If you want to deliver time sensitive data and do not want for it to be delayed waiting for resent packets, use UDP.
2. If your data is not time sensitive and you don’t mind having gaps in your packet stream waiting for packets to be resent, then by all means go right ahead and use TCP.
3. In flash you can use only TCP. Looks like flash sucks.
4. Some MMOs use TCP (WoW), while others use UDP (Eve Online). It is conceivable but by no means conclusively proven that there may be scalability and/or simplicity benefits of using TCP over UDP for MMO games, given that Blizzard is not stupid, assuming of course that you have a good client-side prediction algorithm in place to smooth out the gaps when packets are resent.
end of discussion.
Hi,
I don’t understand why you discourage the mixing of TCP and UDP flows, even I agree when the bandwidth is limited (old PSTN modems), there can be issues.
But nowadays most of users have sufficient bandwith. For example, I often watch a TV flow (using UDP) while browsing the web and/or downloading (TCP) at the same time. As long as my bandwith is sufficient, there is no problem of packet loss.
Why would it behave differently in a networked game, which never consumes lot’s of bandwith compared to nowadays connexions ?
it comes down to console developers (ie. me) having to pass TCR before ship — on the 360 you need to show that your game is capable of running at 64kit/sec up and down limited bandwidth without disconnecting the user. if you mix TCP and UDP flows then this can actually be quite tricky, because you are not completely in control of everything. it’s generally good practice if you want to get as close to the available bandwidth as possible to use UDP only for maximum control.
I would say that point #4 sums it up.
You can pretty much use either TCP over UDP if your client side prediction is good enough.
But, you have to weigh it all up, I guess.
Mr. Fiedler, I had to chuckle a bit at the “Flash sucks” comment simply because it doesn’t support UDP
To be fair, only one of the three ‘major’ cross-platform browser plugins for gaming does support UDP, and that is Unity. Silverlight and Flash only permit TCP. Of course Flash is absolutely the dominant of the three, having something stupid like 99% market penetration.
There is some work on UDP protocols for Flash (eg., Adobe Stratus,) but as far as I can see they have no intention of exposing direct UDP socket control.. yet.
Hi, thanks for the info.
I am developing an online poker game. As it is mostly turn based I guess I will use TCP.
that is a totally wise decision.
Hi,
When developing a multiplayer action game over UDP,i guess we should have a max message size that is smaller than the MTU. If this is true, for an online game played on wireless devices a safe max message size would be 512?
Thank you, for the articles and for your time!
You really just have to test it to be sure. I’ve had no problems with 256 byte packets 30x per-second. 512 should be fine, I wouldn’t go over 1k packets if I could avoid it.
Thanks.
I am curious about something. You always refer to 30 packets/second so i am guessing that all multiplayer games must be tick based(i.e on tick X everything is the same on all machines).
The problem is that on slower machines(phones) you cannot limit the fps to it;s lower value because it would be too small. A way around it is to have constant 30 calls/sec to update and up to 30 calls to render. So each render will interpolate between the next update and the last one. Another way is to use everything time-based and have variable fps between machines. I think this may be a problem implementing lock-step games… what do you think?
Thank you again for sharing your knowledge!
Hi
On UDP, can you guarantee that one recvfrom() matches exactly one sendto() ? I.e if a client sends 3 messages/frame at 30fps will they arrive in 3 recvfrom/frame? On TCP they will surely arrive concatenated by the TCP layer. The problem is code design for parsing the array received from the socket – if i expect a single UDP header(seq, ackbitfield) and more than one game headers( a server sends X*playerAction messages concatenated by me) ; or i must expect multiple udp headers.
For an action game, is it ok to have always 2 sendto/frame ? i.e. one for position(unreliable) one for actions(reliable) or the number of sendto/frame shoul be minimal?
Thanks a lot!
yes. data is sent as atomic packets. you cannot receive a partial UDP packet. each packet sent that is not lost or corrupted results in one packet to be read, of the same exact size and contents that were sent.
regarding two packets per-frame. it’s certainly “OK” but is not ideal. consider that each UDP packet has both a UDP header (8 bytes) and an IP header (20 bytes average) — if you group all of your data together in one packet per-frame, you get more payload bytes vs. packet header overhead
cheers
RE: Geo
Dedicated servers generally run at fixed tick rates, but each player is in their own time stream (fps), and thus advance each player forward independently in time with (potentially) variable dt.
Clients typically run at whatever framerate they like, the exception being if you are synchronizing via deterministic lockstep therefore each player would need to have the same DT for everything to stay in sync, also, fixed dt (or at least, a multiple of a fixed base dt) is very useful for networking physics simulation
cheers
{ 1 trackback }