Search Unity

Android + iOS multiplayer without using Unitys Relay servers?

Discussion in 'Multiplayer' started by Prodigga, Mar 1, 2017.

  1. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,123
    What are the options here?

    Let me first say that the new networking tools are great. It is remarkablely easy to setup a multiplayer game. Syncvars, commands, RPC calls and everything else makes development so accessible, it is truly amazing work!

    However... Unity Relay servers are complete crap - in Melbourne, Australia, our games have 350 ping. The nearest server being Singapore.

    There is only 3 server locations - Singapore, Europe and America. This is no where near enough coverage, and it means that many of our players will be experiencing unplayable latency. I honestly do not understand how the Unity team thought this would be a viable option at all? x_x Me and a friend play together on our 4G connection sitting right next to one another and we are hit with 350 ping. This just won't work. For comparison, I have 100 ping in World of Tanks blitz on my mobile connection.

    So, the other option which would solve a lot of issues is to connect clients directly to one another - peer to peer. (And ensuring people are only matched against players in the same region). This is easy to do when the clients are on the same network, or if neither of them are behind a router. But if they are behind a router and on different networks (almost everyone), we need to perform NAT punchthrough and figure out how to get the clients to connect to one another.

    I don't mind paying for a service - from what I understand, some NAT punchthrough techniques require a server to sit in between the 2 clients to facilitate the punchthrough (after which the clients can connect p2p).

    The problem is, all the libraries I've found to do this do not work with Unity and/or Unity Android+iOS. (Open.NAT, Mono.Net, Nat Traversal (unity plugin))

    Seems like there is no 'hassle free' way to make a multiplayer game on Android + iOS with Unity. I would have to write my own NAT punchthrough library from scratch. I mean, the process seems straight forward enough, but there is hundreds of different types of routers in the wild with hundreds of things that could go wrong - it would be unreasonable to think that I could write my own robust library.

    Any suggestions/ideas?

    To summarise, I would like 2 mobile clients to connect to one another peer to peer and make use of UNets HLAPI.
     
  2. donnysobonny

    donnysobonny

    Joined:
    Jan 24, 2013
    Posts:
    220
    This post will help give you some information on the topic of relay servers: https://forum.unity3d.com/threads/unet-relay-server-teribble-latency.457408/#post-2967477

    In short, I came to the conclusion fairly early on that unity's relay servers, being free, are simply not designed for anything more than a simple indie game and/or testing. I personally use google cloud for anything related to production servers (and in some cases even for test/development servers). The performance and pricing of the google cloud is (in my opinion) far better than any other.

    Alternatively, some have mentioned the use of Photon's new Thunder service, which is ultimately a replacement of unet's super-high-level features (such as matchmaking and relay servers). Since photon thunder is a paid service, you can naturally expect better performance and support. Although I don't use their services anymore (I personally prefer to build my infrastructures from scratch to eliminate reliance on third parties), I have experience with them and can definitely vouch for them.

    Hopefully this helps, good luck with your game!
     
  3. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,123
    Hey Donny, thanks for the reply. I'm not against building my own infustructure, though I'm curious, does your Google cloud services just replica the functionality of the Unity relay servers? IE you still use unity HLAPI for gameplay networking, but the traffic is funneled through your own servers instead? If so, any advice on where to get started would be great!
     
  4. donnysobonny

    donnysobonny

    Joined:
    Jan 24, 2013
    Posts:
    220
    I definitely advise to take my response here with a pinch of salt, unless of course you have experience in server/network programming because as a whole, I would say that network programming (at least, efficient network programming) is the second most complex sector in technology, just behind multi-threaded programming. I personally have a fair number of years experience in this now, without which I probably wouldn't consider building my own solution from scratch.

    However, if you're keen, I absolutely recommend it. After-all, there is no better way to learn, and it's how I did it!

    So, as for the HLAPI vs LLAPI:
    • A lot of unity's core design is based on making game development accessible to as many people as possible. As you work with it more, you'll notice features such as the mechanim/drag & drop animation high-level features that add "convenience" at the obvious cost of performance. There is absolutely nothing wrong with this. Sometimes we need convenience more than performance, however, the HLAPI is an example of a convenient feature.
    • The LLAPI is truly low-level, in that the LLAPI on it's own provides a very low foundation of features, just enough to get you started and solve some common issues in networking (NAT punchthrough, multi-threading the sending/receiving of messages, pooling, buffering, throttling etc), allowing you to focus on your own custom networking solution. So ultimately, there's no "hmph... so I have do it like that?", as you get with the HLAPI
    Multiplayer games tend to be expensive as hell to maintain, especially as things grow. So earlier when I mentioned "efficient networking", what I was referring to was making your networking code/concepts/infrastructure as lean as possible to keep your growing costs as low as possible. So, the HLAPI in general can only take you so far here, where as building a solution with the LLAPI (or building a solution that gives you more control over how good your performance is) is obviously going to give you more control over the resulting cost to maintain the game.

    Moving onto talking about my solution, I use a simple framework that I built on top of unet. One of the projects that use it requires websockets, since the game will be built to WebGL. I talk about this here: https://forum.unity3d.com/threads/client-side-websocket-support-with-the-llapi.457081/#post-2966247, but ultimately, the LLAPI currently does not support websockets on the client side (despite the documentation stating that it does). So, unfortunately I cannot rely entirely on the LLAPI. As a result, my solution uses two HLAPI elements: the NetworkClient class (to handle the client side) and the NetworkServerSimple class (to handle the server side). This still allows me to build a low-level solution without inheriting the necessary "convenience" features of the HLAPI, while gaining support for websockets.

    I could end up going into far too much detail here. So to answer your question more directly: my framework ultimately expects you to build applications from unity, that implement either a client side, server side, or both within the unity application. For testing/development, I build and run these applications on my local testing rig. For production, I build and run these applications as headless linux builds on google cloud server instances.

    If any of the above doesn't quite make sense, or if you have any further questions let me know. Otherwise, good luck!
     
  5. donnysobonny

    donnysobonny

    Joined:
    Jan 24, 2013
    Posts:
    220
    Actually, to answer this in further detail, I don't use things like the NetworkBehaviour (and all of the functionality it comes with), RPCs, syncvars etc. These are all of the high-level type features that I avoid, because I know what goes on under the hood to make these things work. Again, these are features that are implemented for convenience, because they make it quicker and easier to implement a multiplayer game, at the cost of performance.

    Personally, my client-server solution uses the operation/event concept:
    • the client can send operation requests to the server
    • the server can respond to operation requests, and can send events to clients
    In addition to the above:
    • messages sent over the network have an overhead of 2 bytes. One to identify whether it is an operation request, operation response, or an event; and another to specify the type of operation/event. Messages sent over the network using the usual HLAPI features have a much higher overhead than this. In some test that I did using the HLAPI features, I saw overheads of up to 100 bytes!
    • my solution does not allow the ability to send classes and/or constructed/deconstructed objects over the network. People that are used to the HLAPI would be turned off by this, because using the HLAPI, you are encouraged to send instances of classes over the network, however this is massively inefficient because it makes it very difficult to delta-compress the messages being sent (only send properties of an object that change between network updates), and also causes the system to use some fairly expensive processing methods to serialize the classes to/from byte arrays.
    • instead of the above, my solution allows you to send a single Dictionary<byte, object> collection, where the "object" part can be any simple type (string, int, float etc), some simple list types (List<int>, List<string> or List<Dictionary<byte, object>> currently), or another Dictionary<byte, object> for nested collections. I wrote a simple serializer that very efficiently converts the supported types to byte arrays and back.
    So ultimately, I don't really use any of the HLAPI functionality, but I can mimic everything that the HLAPI does if I need any of it. However, the way I would do it in my solution would be less convenient (because it would be harder to use), but more efficient in terms of performance.
     
    King_of_Unity likes this.