Search Unity

Should we use UDP or TCP

Discussion in 'Multiplayer' started by Christian-Tucker, Jul 16, 2014.

  1. Christian-Tucker

    Christian-Tucker

    Joined:
    Aug 18, 2013
    Posts:
    376
    I've been doing a lot of research on TCP/UDP/RUDP lately and most of it is because my friend who is a Unity freak is near-completion of this MoBA(Multiplayer online Battle Arena) single-player prototype and has asked me to work on the server-side of the networking while he writes the Client-API. I told him that I was up to the challenge, mostly for a learning experience, but helping him out was definitely on my mind. I'm fairly familiar with standard IO TCP Networking, however the problem with that is the Standard IO is blocking, so I would have to study on some NIO Libraries, (Looking at you, Netty). However, some-people have stated that I would be better off using UDP/RUDP.

    The problem I've found during my studies with UDP/RUDP is the way that messages will occur. Considering we're going to be working on an authoritative server approach, it's fairly important that things like movement/item activation arrive. In the order that you activate them. For instance, if a player uses an healing item, then an ability that takes 1.5 seconds to cast. If the ability is casted before the item is consumed for some reason (Typically because of UDP Packets not being ordered) it could cause death, and players screaming "Glitches, Fix them." -- This would lead me to stare at the TCP Connections; However then I would be dealing with Latency problems from my studies. However anything under 200 Latency should be fine for this type of game, and we're not really expecting people from across the world to play without the expectation of a little lag.

    So this brings me down to the question... For this particular application:
    • Handles all users connected - Users not in game don't transfer any data besides for chat, if being used.
    • Players in a game (Instanced, each game will have its own game-thread) will be moving around constantly in a 2D Environment (3D world using 2 axis')
    • Ordered arrival of packets is required
    • Losing Data is a Critical problem.

    The only reason I'm really asking this question is because of the use of Reliable UDP which crosses out the "Losing data" issue, from my understanding, which makes this a question worth asking.
     
  2. Erik-Juhl

    Erik-Juhl

    Unity Technologies

    Joined:
    Jul 11, 2012
    Posts:
    59
    The main reason people would choose UDP/RUDP over TCP is because of how TCP handles out of order packets. You may only care about the most recently received packet and want that as soon as it arrives. In TCP, if your most recently received packet is not the next one in sequence, TCP will not deliver it to you until everything else has been received.

    If you need to guarantee sequence and delivery then just use TCP. If you need to guarantee sequence and delivery plus get the most recent packets as soon as they arrive, then use RUDP.
     
    rigidbuddy likes this.
  3. Christian-Tucker

    Christian-Tucker

    Joined:
    Aug 18, 2013
    Posts:
    376
    Alright, Great! Thanks for the reply. I've been working on an Asynchronous TCP Sever which I'm trying to abstract out as much as possible. Hopefully it can make it to the 'Unity networking solution' list when it's completed in a few months. The fun part right now is generating models from a Unity ApplicationLevel and reading them from the Java based server. I might save myself some work by writing it in C#, but oh-well.
     
  4. Raiden-Freeman

    Raiden-Freeman

    Joined:
    May 7, 2013
    Posts:
    15
    For a MOBA, as well as every real time game, UDP is pretty much your only option. TCP has so much overhead, that the game will be unresponsive.

    Prefer UDP, and make sure that you don't care about lost or out of order packets. This can be done, simply by transmitting every time, all the necessary information, which is the player's input and the client's status.

    Example: Let's say you're making League of Legends.
    You start the game, you're at the fountain. Your player clicks on 70,70. Create a message that says that the player wants to move to 70,70. If the client receives an ok from the server, do it (if you have movement prediction, which is not preferable since it gives false info, you can start moving as soon as you click, expecting that the server got the message).

    Now let's say that the player clicks and one packet is lost, or out of order, or in general the message is unreadable. You don't really care, as soon as the player notices that nothing is happenning he will provide input again and you can hope that this time the message will not be lost. In general I think that it's implemented in a way that the server constantly sends and recieves info from and to each client. Some times this info is nothing, and it's just use to estimate the propagation delay (ping) others, you can send data to "resync" the game state, like saying I'm at X,Y with Z hp, and the server replying, no you're at X,Y with Z-5 HP, and others you can also send player input.

    In my opinion you shouldn't use an acknowledgement (like the ok message I mentioned earlier), because you're just emulating TCP, and you're probably doing it sub optimally. You should just not care at all about each side recieving the message, because you're going to send new info in milliseconds, so even if it's lost, it will be refreshed with new info on the game state / player input in such a small time, that it will be unnoticable to the player.

    (Doing it with an ok message for starters is good, so that you can step by step get acclimatised with messages/networking/etc)


    In LoL I guess that they're sending each frame to every client a message like this:
    Player 1 @ (50,120) hp:1000/2000, status: Normal
    Player 2 @ (...)
    Player 3 @ (...)
    Player 4 @ (...)
    Player 5 @ (...)
    Player 7 @ (250,100), HP:500/2500, status:Stunned

    Given that you can't see (fog) players 6,8,9,10 you get no info on them (to prevent cheating like maphacks).

    The info that you get, is based on what the server anticipates that your team's vision is. For example, let's say that you're at 10,10 with a vision radius of 10, you can see everything from 0,0 to 20,20. If you move to 12,12 and the message is lost while going to the server, it should reply with [...]Player 3 @ (10,10)[...] so that you can know that the message was lost, and you don't get any new info that you shouldn't have anyway. Also if an enemy stands at 22,20, you can't see him in this frame, because the server doesn't know that you moved, so it will not send you that info.
     
    Last edited: Jul 19, 2014
    boxhammer likes this.