Author Topic: (to the programmers) Why use UDP?  (Read 3174 times)

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(to the programmers) Why use UDP?
« on: December 07, 2003, 12:59:42 pm »
Hi,

I started working on a own multiplayer game and faced the choice to use either TCP or UDP.

First I started working with the TCP-protocol but than I saw your network engine. :)

I tried to unterstand your source, but just a few questions:
- When do you send those ACK-packets, always or just on high priority packets? And how do you guarantee that the ACK packet is coming through? I mean, otherwise the other connection endpoint would send the packet again and again until you ACK comes through.
- How does those multipackets work? Many unimportant pakets (like weather, which does not need to be sent immediately and can wait a few secods) are buffered and stored in a big packet sent when the buffer is full?

Sorry for my really bad English, I hope you understood my questions and could give me a brief answer. :)

ChrisM
Please excuse my bad English :)

Rulzern

  • Hydlaa Resident
  • *
  • Posts: 134
    • View Profile
(No subject)
« Reply #1 on: December 07, 2003, 03:32:58 pm »
most MMORPG\'s use UDP for lag and bandwidth issues, while FPS\'s, which generally have more bandwidth per player, is more dependant on accuracy, and have servers close to the players, can get away with TCP.

Don\'t know anything about PS\'s network code :p
Thanks a lot Venge...

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #2 on: December 07, 2003, 07:16:23 pm »
Hi,

yes, but where is the advantage of UDP if you \"emulate\" TCP with UDP using ACK-packets and so on?

ChrisM
Please excuse my bad English :)

Rulzern

  • Hydlaa Resident
  • *
  • Posts: 134
    • View Profile
(No subject)
« Reply #3 on: December 07, 2003, 07:44:24 pm »
As i said, i have no idea how PS\'s network code is built up, but UDP gets routing priveleges and stuff, so even if you do emulate TCP, the latency should (atleast in my fantasy world) be lower.
Thanks a lot Venge...

RonHiler

  • Traveller
  • *
  • Posts: 49
    • View Profile
(No subject)
« Reply #4 on: December 07, 2003, 08:43:32 pm »
TCP, generally speaking, is unsuitable for games, unless they are low bandwidth (like turn based games, such as chess).  The reason being that TCP is guaranteed delivery and ordering, which on paper sounds like a great idea, but in practice causes many problems.  If you start losing packets in a TCP system, because of the ordering, you actually cease all delivery until the next packet gets through.  In fact, TCP will actually give up resending the packet after a while and will start sending small \"test\" packets to try to establish a path again.  Once it gets the path back, only then will it try to resend the errant packet.

What it all comes down to is that TCP can actually lag by *minutes* at a time (occassionally), and it is not uncommon for it to lag by many seconds.  For real time game use, this is unacceptable.

Therefore, most real time games use UDP with thier own reliability and ordering system on top of it.  You may think this is re-inventing the wheel, but actually it is not.  With UDP and your own system, you can selectively determine which packets need to be ordered and/or reliable.

I\'ve not looked at the PS code, but in my game, for instance, chat packets are neither ordered nor reliable.  Item packets are reliable, but not ordered.  Movement packets are both ordered and reliable.  This means I can send chat data at any point without getting held up by a stray Item packet or movement packet like I would with TCP.  I imagine PS uses a similar selective system.

-Ron

Kramy

  • Hydlaa Citizen
  • *
  • Posts: 246
    • View Profile
(No subject)
« Reply #5 on: December 07, 2003, 08:44:28 pm »
The problem with UDP is if you live far from your ISP, and the lines are bad, all the packets can be lost(and not resent), making the game unplayable for those people.

That said, I used UDP on a 2D game I made where you are a square and walk around on some tiles...hmm, not much replayability there :P

I also have no idea how PS\'s network code is built up, but I have combined speed.direction.inertia.xpos.ypos etc. into one packet to lower bandwidth requirements.

tangerine

  • Hydlaa Resident
  • *
  • Posts: 192
    • View Profile
(No subject)
« Reply #6 on: December 07, 2003, 09:11:54 pm »
Quote
Originally posted by ChrisM
yes, but where is the advantage of UDP if you \"emulate\" TCP with UDP using ACK-packets and so on?


Because you use ACKs only for part of packets. For example if you send positions of people and loose a packet, there is already a newer packet going in on the wire so you don\'t need to resend the lost one. At the time you would detect and resend the lost packet again, the information it contains would already be out of date.

And this same problem exists in TCP too. TCP would also stop sending other packets because of the lost one.
« Last Edit: December 07, 2003, 09:14:19 pm by tangerine »

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #7 on: December 07, 2003, 11:50:37 pm »
Hi,

ok, thx for your very informative answers!

I think I will need to use UDP to get a more or less lagfree game... :)

Thanks!

ChrisM
Please excuse my bad English :)

tangerine

  • Hydlaa Resident
  • *
  • Posts: 192
    • View Profile
(No subject)
« Reply #8 on: December 08, 2003, 12:49:36 am »
Quote
Originally posted by RonHiler
Movement packets are both ordered and reliable.


But won\'t this stall the whole movement in case of packet loss until this is detected and the packet resent ? Why resend when following more up-to-date update will come faster and obsoletes the lost one ?

Vengeance

  • Veteran
  • *
  • Posts: 1452
    • View Profile
(No subject)
« Reply #9 on: December 08, 2003, 05:39:22 am »
RonHiler that was an excellent post and very informative.  That said, it is funny how your priorities are the opposite of ours. :-)

We have guaranteed delivery of chat packets, and non-guaranteed delivery of moving/position packets.  The reason for this is that usually within a few msec the movement packet is obsolete and superceded by a new one.

A few more points:

- ACKs are sent to keep the source computer from resending guaranteed packets.  Non-guaranteed packets are not ACKed and never resent.

- All messages can be merged and sent as one packet.  The msging layer sends whatever it wants, and these items go into a queue per client.  The networking thread wakes up every 50msec or so and merges whatever it can from a queue into 1 packet and sends it.  It does this for each client, in the case of the server.

You could wait even longer to send VERY low priority packets but we pretty much assume that every client will be getting a fairly steady stream of data concerning other game events and sliding a weather message in there doesn\'t really affect much.

Hope that helps,
- Vengeance

RonHiler

  • Traveller
  • *
  • Posts: 49
    • View Profile
(No subject)
« Reply #10 on: December 08, 2003, 06:09:12 am »
Quote
Originally posted by tangerine
But won\'t this stall the whole movement in case of packet loss until this is detected and the packet resent ? Why resend when following more up-to-date update will come faster and obsoletes the lost one ?

Hmmm, well, it\'s a bit misleading what I said.  In my game, there are movement packets and there are movement packets :)  The type of movement packets that are reliable and ordered don\'t stall movement, and in fact it is possible to get them out of order, they are just reordered by the client as they get there (by server timestamp value as well as a incremental key value).

The reason they are reliably sent is that I don\'t send actual positions (well, actually I do, but only once they are *known* positions by the server at some given time, so they are always out of date, but that\'s getting more complex than needed for this discussion :) ).  I\'ve found sending absolute positions every x ms to be a less than satisfactory method (perhaps you guys found a way to do this, but I couldn\'t make it work with any decent results, heh).  I instead send velocities and facings.  Thus, every single velocity change *has* to get to the client, there is no superceding one data packet with another, as each builds on the previous.  If one gets lost and data comes out of order, the clients use interpolation to \"guess\" on where the player is based on the data they do have until the actual missing packet(s) gets there.

I\'ve found this works really well.  There is still a good deal of \"popping\" in my game for 3rd party avatars, but that\'s for an entirely different reason (which will be fixed in A6 :) ).

Quote
Originally posted by Vengeance
That said, it is funny how your priorities are the opposite of ours. :-)

Hehe, yeah.  It\'s odd how any given game\'s authors independently come up with many of the same solutions to some problems, yet entirely different solutions in other things.

Quote

The reason for this is that usually within a few msec the movement packet is obsolete and superceded by a new one.

Yeah, I\'d do it the same way if I was sending absolute positions every certain amount of time.

Quote

- ACKs are sent to keep the source computer from resending guaranteed packets. Non-guaranteed packets are not ACKed and never resent.

Ditto.

Quote

- All messages can be merged and sent as one packet.

I don\'t do this.  I send each packet as a separate entity, even the really small ones.  Yeah, I know there is some overhead with packet sending, but I found in my game the time spent trying to pull apart messages into individual packets just wasn\'t worth the effort :)  I was spending more time checking packet lengths and pulling out the individual packets than I was saving by sending them together.  By sending them as individual messages, I can just read the first bytes to see what kind of packet was received, then rip the individual data members for that kind of packet and I can move immediately into processing.

That\'s just what I found though, YMMV.  :)

tangerine

  • Hydlaa Resident
  • *
  • Posts: 192
    • View Profile
(No subject)
« Reply #11 on: December 08, 2003, 12:21:33 pm »
Yes, sending only positions won\'t work well, because you need the velocities (or even acceleration info) for client-side prediction of positions. But why not send both positions and velocities, unreliably ? If you send positions too, you don\'t need reliable&ordered delivery because now you don\'t need all of the packets.

It seems to me that you described very well the theoretical aspect of game networking but you don\'t follow this theory in your praxis :)

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #12 on: December 08, 2003, 02:46:13 pm »
Hi,

another thanks for all your new answers! :)

I think I\'ve understood the usage of UDP packets and I\'ll think for my game it will be enough to not merge packets but send them all alone as RonHiler does.

But only one question: Do you really send absolute positions? Isn\'t this very insecure because everyone can manipulate his client to move much faster or implement a \"teleport cheat\"?
Isn\'t it better to send just acceleration und turning events and let the server move the player?

ChrisM
Please excuse my bad English :)

RonHiler

  • Traveller
  • *
  • Posts: 49
    • View Profile
(No subject)
« Reply #13 on: December 08, 2003, 04:19:40 pm »
Quote
Originally posted by tangerine
Yes, sending only positions won\'t work well, because you need the velocities (or even acceleration info) for client-side prediction of positions. But why not send both positions and velocities, unreliably ? If you send positions too, you don\'t need reliable&ordered delivery because now you don\'t need all of the packets.

Well, understand, I\'m trying not to go over my entire movement packet methodology.  It is by far the most complex server/client packet passing system in my game, heh.  So you are only getting a little bit of the picture, there are actually 5 different packet types that can go back and forth just dealing with avatar movement, and each packet type carries 8-12 peices of data with it.

So to answer your question, I do send out absolute positions from the server, and if it turns out the time stamp on this position is later than a missing velocity change packet, the client ceases to request that packet, since it is not needed.

Yes, the velocity packets are reliable and ordered.  But ordered only in the respect that they are re-ordered at the client end by timestamp, they can actually come out of order, and reliable only until they become obsolete, at which point they\'re quietly dropped :)

Which, actually now that I think about it, is a good answer to ChrisM\'s initial question of why UDP over TCP.  TCP could never do that, while with UDP, since it\'s my own custom system that I can design on a per packet basis, I can do tricky things like that to make packets \"semi-reliable\" and \"semi-ordered\".

Quote
Originally posted by ChrisM
I think I\'ve understood the usage of UDP packets and I\'ll think for my game it will be enough to not merge packets but send them all alone as RonHiler does.

Whatever you find works best for you is what you ought to use.  PS merges packets before they send them, and I don\'t.  Either way has advantages and disadvantages.  My packets have a tendancy to be pretty good size, because each one packs all the data that is needed to do a particular task.  Perhaps PS sends one bit of data per packet instead (?? I don\'t know, I\'m just guessing), and therefore it makes sense for them to merge several small packets first.

Quote

Isn\'t it better to send just acceleration und turning events and let the server move the player?

Absolutely!  Clients should never ever send out absolute positions.  When we are talking about sending out absolute positions, we mean from the server to the players, not ever the other way around.  My clients only send keystroke data to the server.  The server handles calculating their positions and facings and velocities, and returns this to all the other players.

Never trust the client!  :)
« Last Edit: December 08, 2003, 04:20:41 pm by RonHiler »

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #14 on: December 08, 2003, 04:48:10 pm »
Hi,

Quote
Absolutely! Clients should never ever send out absolute positions. When we are talking about sending out absolute positions, we mean from the server to the players, not ever the other way around. My clients only send keystroke data to the server. The server handles calculating their positions and facings and velocities, and returns this to all the other players.

That\'s exactly what I expected and hoped to hear. :)

As far as I can see it in the PS source code, the client sends absolute coordinates but the position is first valided by the server meaning the server checks whether the client could get to this position since last known position in the elapsed time between the two packets.

I now started planning my network system und my packets are also relatively huge, except of course packets like special commands but the occur not very often and it wouldn\'t be profitable to cache them and wait for another packet to pack them together...

Hmm... PS has a very complex network engine. NetBase seems to be a lowlevel base class overloaded by client and server and MsgHandler a class also overloaded by client and server to distribute incoming packets to those iNetSubscriber-inherit classes who subscribed for these events.

But I don\'t unterstand what the NetThread class for the server is... :(

ChrisM
Please excuse my bad English :)