When I started Network Traders a year ago, I was intrigued by Unity’s new networking layer, which was then still the MLAPI. After some testing, I realised that it was just not the right tool for my application. So when does it make sense to use Netcode and what might be an alternative for your project if it doesn’t?
Unity has already made several attempts at providing its own network package. The last one, UNet, came with its own set of snags, and was deprecated a while ago. It has been replaced by Netcode in late 2020, which is a continuation of the third-party library MLAPI.
But Unity always had a very specific application in mind, which is to support devs at making real-time multiplayer games. It offers features like synchronising game objects, authoritative server architecture, and prediction. For performance reasons, it is based on UDP rather than TCP.
I needed none of these features for Network Traders. The original idea was to connect devices directly and exchange specific packages of data. This does not require syncing objects, as they do not coexist on both devices, nor does it need an authoritative server, or movement prediction. Even UDP is rather a hindrance, as there is time in abundance but data loss is critical.
Low-Level Netcode Alternatives
Therefore, I soon stopped trying to bend Netcode to my needs. It provides lots of high-level features, but I was looking for a low-level networking library. Interestingly, Netcode does not care about which networking library it uses, so there is a whole list of alternative transport protocols. From these, I chose to try Ruffles, which was the original transport layer of MLAPI. It is a UDP protocol, so, as I said above, not really what I needed. But it was well suited for broadcasting in a local network in order to identify other devices. So I stuck with it for a while.
However, for exchanging data I wanted a more reliably and easy-to-use TCP protocol. Mirror Networking is another high-level API supporting different transport layers. One of them is Telepathy, the original Mirror transport, made for Unity using TCP. It was what I was looking for, although I fell into one trap I would like to warn you about.
Mirror provides an authoritative server which defines what state of the clients is correct. When a client disconnects, the server is not really interested in the client’s state anymore, and any message still in the queue may be lost. In case of a peer-to-peer connection where every message is important this is disastrous. If you think about using Telepathy in that way, check out my more detailed explanation here and follow the link to my fix on GitHub.
Finally, I also had to connect the client with my data server, which is not a Unity application. So I began with an implementation of asynchronous server sockets based on the example code by Aaron Luna. If you now think, “why would he use three different networking implementations?”, you are perfectly right to wonder. In the end, I dumped it to just use Telepathy on the server as well.
How about you?
In the case of networking, Unity itself provides few alternatives if you do not need exactly what Netcode is meant for, because you just happen to not write an online first-person shooter. What networking layers are you using, and what are your experiences? Did you try Unity’s new Netcode? I would be happy if you left a comment below.