7
\$\begingroup\$

I'm working on a networked multiplayer game, initially for iOS.

Even with TCP_NODELAY there are large fluctuations in latency. I can't be sure of the reason, but I would not be surprised if it was resends on packet loss due to flaky connections.

Having done no real life server work with UDP as opposed to TCP (which I have lots of experience with), I wonder if there are any significant gains to trying a UDP-based architecture.

Client packets are typically only a few bytes, sent rarely, except when moving, when the player might issue 2-8 commands/s. Server packets are slightly larger and mostly sent as response to a client command.

Connections need to be reliable and ordered.

ADDITIONAL INFO

Very early on I did some exploratory tests with TCP versus UDP. I would run connections Phone -> 3G -> External static IP of router -> Wifi -> Development computer and Phone -> Wifi -> Router -> Wifi -> Development computer.

What I wanted to improve was mainly the very uneven lag one would experience moving around on the map with a non-local connection.

Obviously starting animations can help, but there are (rare but valid) reasons why a move command might be rejected that the client have no way to predict. In addition, much data is hidden from the client, which again gives very little room for predictive responses.

Anyway, my results was the UDP and TCP gave pretty much the same average latency when sending data.

What I didn't look at was the actual spread - for example the maximum TCP latency in face of packet loss. I would have have needed to do some packet recovery mechanism in UDP to figure out if UDP could do better.

So again the results I see today with TCP is that usually it works fine, then suddenly a slowdown and a burst of movement as all the other buffered packets are more or less executed at the same time.

\$\endgroup\$
  • \$\begingroup\$ TCP is generally to slow for gaming I find since the overhead just kills performance to guarantee you get what you want. UDP on the other hand is so much faster and some times you can afford to lose a few packets in a multiplayer game as long as you can make up for it. \$\endgroup\$ – OmniOwl Jul 24 '13 at 22:34
  • 2
    \$\begingroup\$ gafferongames.com/networking-for-game-programmers/udp-vs-tcp - Always a good read for anything. That is, if you haven't checked it out! \$\endgroup\$ – Luke San Antonio Bialecki Jul 24 '13 at 22:35
  • 7
    \$\begingroup\$ TCP is used by a large number of games these days. Can you verify that TCP is the cause of your latency rather than just guessing? Is there any good reason you need a whole connection to be reliable and ordered and not just specific streams/messages? Are you experiencing this in a test emulator/environment or in deployment? Wired or wireless? LAN or Internet? You have a problem, a random guess at the root cause, and a vague question about "what's best?" \$\endgroup\$ – Sean Middleditch Jul 24 '13 at 23:13
  • \$\begingroup\$ @SeanMiddleditch fair enough, I added some details. I know if the TCP behaviour is the cause, but I'm fairly confident I have some packet loss (easy to get in my setup), and looking at how TCP works and the cost of a roundtrip, I could easily see how the observed behaviour could arise. I'm not sure a custom UDP scheme could work, but nor do I know if it's worth investigating. I suppose there are occasions where it's possible to allow for unreliable transfers in some occasions (e.g. the player walks north 3 times -> it's ok to just walk north 2 times). \$\endgroup\$ – Nuoji Jul 25 '13 at 8:33
7
\$\begingroup\$

It turns out that this is due to how powersavings in mobile phones work.

For my iPhone, sending a steady stream of UDP pings every 200 ms will keep the interface open, and give me a RTT of 80-100 ms. Reducing the ping frequency will drastically increase the RTT, to an average of about 400 ms. Further reducing frequency causes the RTT to occasionally go even higher.

TCP is a bit different, because the OS is more aware of the open connection. What I've noticed is that TCP can suffer greatly on poor connections (regardless if we're talking wifi or 3G), because of its "packet loss = I'm using too much bandwidth" behaviour.

In my case, it's possible to build a fairly simple "reliable UDP" that's superior to TCP - for my game - by having the client send a packet every 200 ms and repeatedly send packets that haven't been acknowledged.

in particular this works a bit like the Q3 code, in that when you get packet with sequence number n, you can then discard any packets n - 1 or earlier without losing any data (because packet with seq number n will contain all previously unacked commands)

If packet n is lost, there's still a packet n + 1 arriving in 200 ms with that data.

This costs the occasional unnecessary resend (when an ack takes more than 200 ms to arrive), but latency is down to max ("network interruption time" + ping interval).

This would not work well if packets were fairly large, so that a resend of a packet would cause the next packet to fragment. There are many other implicit assumptions as well, so I wouldn't recommend this to anyone as a general solution.

Put my point is that UDP allows the flexibility to come up with a scheme that can be tailored to your particular game. If that outweighs the inconvenience of designing the UDP protocol will depend on the particulars of the game.

\$\endgroup\$
  • 1
    \$\begingroup\$ Using UDP on a poor connection the player will suffer a lot also. His input will randomly get to the server and his game state updates will arrive randomly. Plus, to make the game work on UDP the developer will need to reinvent half of TCP, poorly. \$\endgroup\$ – Zan Lynx Aug 8 '13 at 2:42
  • \$\begingroup\$ It all depends on the application. UDP performs no magic, but it allows you to game specific mitigation strategies impossible with TCP. \$\endgroup\$ – Nuoji Aug 8 '13 at 15:21
  • \$\begingroup\$ That is some interesting info about UDP on iPhones (and probably other handheld devices). Do you have any links where I can read more? \$\endgroup\$ – John McDonald Aug 8 '13 at 16:21
  • 2
    \$\begingroup\$ @Zan Lynx, Using TCP over a poor connection is even worse than UDP. With UDP you can create an algorithm to handle dropped packets via interpolation, delays, etc (look at Source Multiplayer Networking). TCP over a poor connection means the whole game will stall repeatedly while lost packets are resent, which will happen very often on a poor connection. TCP is good for solid connections with enough bandwidth to support the data load (example: LAN, Broadband). UDP with a bit of extra work will always perform on bad connections. This was done with Doom/Quake and many other older games. \$\endgroup\$ – Jyro117 Aug 8 '13 at 19:13
  • 1
    \$\begingroup\$ @Zan Lynx: It absolutely did take a number of versions before a good network protocol was determined. I just wanted to point out that using UDP isn't a bad thing, in the end it will always depend on many factors related to the game/environment. \$\endgroup\$ – Jyro117 Aug 8 '13 at 20:09
-1
\$\begingroup\$

There seems to be quite a considerable amount of misinformation in the comments and answers above, including referencing papers that are no longer relevant.

You should be utilizing both UDP and TCP in your game and the reasoning is really quite simple:

You should use TCP for reliable transmission of time insensitive actions such as basic heartbeat and other blocking transactions (HTTP really). Some quick notes:

  1. Beware of Nagle's Algorithm, where the network stack will attempt to buffer small TCP packets in an attempt to reduce the ratio of data to IP overhead. You can usually disable this functionality.
  2. When network congestion occurs TCP will attempt to slow the connection down by temporarily reducing the window size and increasing it again back to normal over time. This does not actually affect UDP transmission anymore.

UDP should be used for time sensitive data transmission such as most active parts of an online game (movement, etc).

You could of course also just use UDP and build reliability around it to attempt to get the best of both worlds. But it will cost you time and complexity and in the end the best solutions best good use of prediction and user interaction transparent to network problems.

\$\endgroup\$
  • \$\begingroup\$ If it makes sense to TCP, UDP or a mix depends entirely on how the game works. Making any assumption as to what one should use without regard to the specific requirements isn't better than making a random guess. Developing a "reliable" UDP solution isn't worse complexity-wise to building a solid, scalable server-client solution with TCP. For instance, client-prediction is fine, but not it's not always possible in every single type of game. \$\endgroup\$ – Nuoji Aug 8 '13 at 15:30
  • \$\begingroup\$ To read a bit more on "You should be utilizing both UDP and TCP", please have a look at "Wait? Why can’t I use both UDP and TCP?" chapter of gafferongames.com/networking-for-game-programmers/udp-vs-tcp \$\endgroup\$ – serg.nechaev Feb 23 '15 at 3:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.