Advertisement

UDP vsTCP for games

Started by March 24, 2002 07:39 PM
40 comments, last by Tylon 21 years, 5 months ago
Ok, I seem to hear everywhere that UDP is the way to go when it comes to games, and that it is so much better for any type of online game. I kinda accepted it, but can anyone tell me why ? I assume its because it is in some way faster than TCP, but are there any other reasons? Is it easier to design the game when you have ''send and forget'' packets rather than a constant stream ? While speed alone is enough to put udp above tcp, i would like to know if thats the whole story ...
Well opinions vary on this topic. Little do you konw but you may have initiated a holy war with this topic .

In my opinion...

UDP is a superior protocol for implementing online games for a number of reasons. Of those I think Scalability is probably the largest. Because of it''s features (guaranteed in order delivery) TCP has alot of overhead. It needs to keep copies of recently sent packets so that It can resend them in order if one is missed. Basically TCP will keep firing away packets until it receives an Acknowledgment from the destination that is out of order. The sender will return to the last state at which it knew the packets were delivered in order, and resend all those packets until it gets caught up with the current packets being sent. The operating system actually maintains these “windows” or cashes of recently sent packets, so each TCP connection has a much larger memory requirement associated with it then a UDP one, which cashes nothing.

You can imagine how TCP can sometimes cause some strange lag spikes on your clients as it tries to resend stuff in order. The real killer is this, say your server is routing all its TCPIP packets through a specific router and then sending them off to all your clients. And say that router is receiving messages on its fiber optic connection to your server faster then it can deliver them. The router only has so much memory and it will start throwing out packets that it can’t store, knowing that they will be resent. This causes all incoming packet to the router to be dropped. And all of a sudden the TCP on your server is resending all its old packets and it''s new ones. The router dies a horrible death and all your clients are hopelessly out of synch and disconnect. If you played AO in the early days, you are familiar with what this looks like

UDP does not have this overhead however. It operates under a send and forget method. Packets are not guaranteed to be in order, or to be delivered for that matter. The operating system is not responsible for any transmission, and furthermore, you can have all your clients send and receive data on the same server port. (With TCP/IP each connection must have it’s own port) You can implement a guaranteed delivery system for UDP where you require the receiving host to send an Acknowledgment when it receives the packet. But the Beauty of UDP is that you don’t have to send everything guaranteed, you can send the critical stuff guaranteed, and then send the not so important data un- guaranteed this give you a lot more control over your bandwidth utilizations and allows you more choices on how you want to deliver your data.

In my experience UDP packets typically are delivered and only a small percentage of them get lost. Its enough that you need to implement a method of resending packets if they are not received (if your system requires guaranteed delivery), but your not going to be constantly resending every packet.

There are some clever solutions where you can minimize the amount of work you need to do to update your clients. One such solution is to have each UDP packet contain a delta gamestate packet based on the last known gamestate of the client. As your client receives these packets it acknowledges them to the server. It doesn’t really matter if packets are lost because the newest packet will always bring the client up to the latest gamestate.

Have fun
Advertisement
wow, thanks for your help
Also do a search on this forum...we''ve discussed this often :D

Although Ironside clears it up pretty much
www.persistentrealities.com for Inline ASM for VB, VB Fibre, and other nice code samples in C++, PHP, ASP, etc.<br/>Play Yet Another Laser Game!<br/>
Of course, if you''re an indie developer whose game is probably not going to have connections ranging into the thousands, you can take advantage of the fact that with TCP you don''t have to create an in-order-receipt mechanism or a guaranteed-receipt mechanism. After all, those mechanisms are automatically included in TCP, not in UDP.

Both protocols have their uses. Neither protocol "always wins" or "always loses".

Our game, Artifact, uses TCP exclusively. Mostly that''s because we''re familiar with TCP and know how to work with it. It also seems to make a lot of sense in a client-server setup.

But, in the end, whichever way you go, you should have your *own* reasons for going that way.

DavidRM
Samu Games
It''s true TCP can be utilized to make networked games very effectively. You get alot of functionality for free, and as long as you know your scalability limits and latency tolerance then your fine. There are some interesting Caveats when using TCP/IP and Winsock however. For instance it''s a common practice to use WSAEventSelect() to create an event object that listens to incoming packet events. When it comes time to do the network tasks, the game just asks how many packets it''s received on a particular connection and then calls recvfrom() once for each packet that has queued up. This works great, except for the fact that you can only register 64 of these event objects. So your limited to 64 connections if you use this method. Which UDP this isn''t so much of an issue because all communications occur on the same socket.

There are ways around this 64 Event listener limit, some solutions include using IO Completions ports and other methods but this ends up adding to the complexity once again. If you just want to get things up and running on a network and support a reasonable amount of players, by all means use TCP/IP especially if this is your first introduction to socket level network programming. As your projects grow in their scope and the number of players you want to support you''ll probably want to start looking at UDP.
Advertisement
Recent research that I conducted showed that on Windows systems the only real limitation on server connections was the amount of RAM available. I''ve never before heard of a 64-connection limit on Winsock. Maybe I''ve just been doing it the "right" way by accident, and avoiding the problem. If that''s the case, then the added complexity issue based on this seems rather moot.

Most of our experience is on Unix/Linux where there is a very definite limit: 250. This limit is based on file descriptor objects. To get around this isn''t too difficult as it only involves simple chaining. And since this spreads the load around, it''s not a bad thing to do anyway.

In general, who you ask, and what they prefer to use, is going to tilt the range of responses you get.

There is no One Right Answer (tm), and it''s not even as simple as "Small games use TCP" and "Large games use UDP". The nature of the game itself makes quite a bit of difference. As Ironside mentioned, latency must be adjusted for, but that is the case with both protocols. Merely using UDP doesn''t improve the ping times of a bad connection. Neither TCP nor UDP will make a good connection out of a bad one. If a TCP connection would lose enough packets such that a game becomes unplayable, merely switching to UDP won''t help, as just as many packets are going to get lost. And in case you haven''t noticed yet, there are a *lot* of bad connections on the Internet.

No matter how "twitch" your game is, there are only some many times per second you can reasonably expect to send out updates. Which means that the burden is more on the prediction and ghosting techniques used by the game than on the particular protocol in use. UDP won''t make it so that you can magically update your players 100 times per second. The Internet simply can''t be counted on for latency at that fine a granularity.

Don''t fight the Internet. Learn its limitations and work with them or around them. And realize that choosing TCP or UDP is only the first of a long sequence of choices you''re going to have to make in your communications structure between client and server.


DavidRM
Samu Games
Lots of good comments. I have a couple of questions breaking off from some of theses comments.

First you say if your using like 16 or so players you should be just fine using TCP. When approximately in your opinion would you want to switch over to UDP when increasing player count? 32 players ...64 ...so on...?

I know it depends on the info your sending and such. What does everquest use and large MMORPGS? UDP?

Also i''m curious, again in your guys opionions, what type of information would you want to have so that its guranteed. Can somebody think of a list.

I suppose player name would be good. What character model their using...set up info.

any others you can think of ..
thanks

quote:
Original post by DavidRM
Recent research that I conducted showed that on Windows systems the only real limitation on server connections was the amount of RAM available. I''ve never before heard of a 64-connection limit on Winsock.


I got the 64 socket limit info from THIS thread. (last post) It may not be a factor for the Unix based implementation of sockets however.

I do know this however, the Quake network code originally started out as TCP/IP and was re-written in UDP for quake 2. The number of players supported went from 16 to 32. Now there may have been other considerations in that improvement but the protocol played a part. Quake 2 used the method we''ve been talking about, sending some information reliably via UDP and other information as a broadcast with no reliability.

In quake3, Carmack moved to the method of having each UDP packet contain a complete delta of the gamestate and not really worrying about different packet types and delivery mechanism. There was just one way to do it, bundle up all the state changes and blast them out to their respective clients. Clients acknowledge and you blast them out the changes again.

In quake3 the upper limit in a game grew from 32 players to 64 players. This speaks more to what DavidRM was saying; they found a more efficient way of propagating information to the clients. Since both quake2 and 3 used UDP as their underlying protocol what really made the difference was how intelligently the server distributed the information. These are the real problems that need to be solved when developing multiplayer systems. Figuring out the best way to order and send your data, and what data to send so that your are utilizing your bandwidth in the most efficient manner will have a much greater performance impact on your game then choosing between UDP and TCP/IP.

As far as your question about what information should be sent guaranteed. Well you always want chat messages to be delivered. And you defiantly want to inform the client when their character is loosing health in a battle ƒº There¡¦s a lot of things that you¡¦d want to send guaranteed. The tougher question I think is what information doesn¡¦t need to be guaranteed. Like for instance monster movement packets, You can build your client to predict where a monster will go in the next few seconds based off his current direction and velocity. If your client misses a few monster move update packets it will still be pretty close to representing where the monster actually is. When it finally does receive a monster move packet it will make the appropriate corrections on the client. The client may see the monster sprint to a different location¡K you just need to think of creative ways to let the client run even when it¡¦s not receiving continuous state information.
quote:
Original post by Ironside
For instance it's a common practice to use WSAEventSelect() to create an event object that listens to incoming packet events. When it comes time to do the network tasks, the game just asks how many packets it's received on a particular connection and then calls recvfrom() once for each packet that has queued up. This works great, except for the fact that you can only register 64 of these event objects. So your limited to 64 connections if you use this method.



You are limited to 64 connections PER THREAD.

[edited by - granat on March 26, 2002 2:57:43 AM]
-------------Ban KalvinB !

This topic is closed to new replies.

Advertisement