What’s State-of-the-Art in Web Game Networking?

I have some lessons learned from my experience over the past two years from researching libraries for use with browser game design. When I first started, I had specific goals in mind:

  • something that's easy to develop in
  • a networking schema that didn't cost hundreds
  • something that's cross platform, so I can develop from my native editor Unity3D

For every solution, there was always one drawback or another. This would usually result in doubling or either tripling the workload. In my opinion, all solutions are completely unusuable except for one or two depending on your situation. This article will go through why each solution is bad.

You'll notice that I'm a fan of Unity3D. While I accept all editors for who they are, I'll give a reason why at the end.

socket.io

For a while, javascript solutions seemed to have everything going for them. The API is intuitive, the JSON fun to code in, but the more I coded in it, the more I hated it. Here's why:

  • Javascript isn't designed to be an object oriented langauge. Have fun packing every class in a monolithic godlike super-module.
  • Javascript and c# don't play nice together. Eventually you have to parse JSON in c#, one thing among many other conflicts that will make you hate it. Even if you find a good library, it's a lead balloon that ends up causing more bugs than it fixes.
  • Javascript-based game engines which are designed to pair with these are disgusting. Granted, there are a few goods out there, but I found that you can't even make a modern GUI without writing every little animation function from Unity3d over again. Forget about state-of-the-art particle systems or other pretty features. Scene editing and importing is broken or time-consuming. If you're making an ".io game", then fine, use socket.io.
  • node.js is more bloated then a beached whale. Get that lead balloon off the ground and you still have to deal with about 10 different plugins just to make it equal to a simple web server. I spent 3 days trying to get to that point, and then things started breaking from compatability.
  • not cross platform
  • can't be run in editor
  • poor documentation and community

Peer.js

You want to save on networking right? You want to use a library to make that easier, right? Good idea, but wrong solution.

  • not cross platform
  • dead project
  • can't be run in editor
  • critical bugs to be fixed, like apparently not working in firefox

Long polling

No, just no! Long-polling is a hack that fixes a problem doesn't exist any more. It's costly to the CPU and doesn't scale. It basically holds a connection open using a hack so that you can send periodic updates the way you would using websockets.

Unity3D built in networking

No, just no. While it would be extremely nice to have, sadly Unity3d networking for WebGL is a second rate customer and therefore gets limited support. When they do network, they route it through their own servers and charge you hundreds or even thousands of dollars for something you can do for free. There is also no P2P support at all.

I tried for a while to try and write my own wrapper for the Unity3D high-level API. Sadly, most of the code is closed source, so you have no way of understanding the OP codes required to make it work. This would be extremely ideal, because I really enjoyed writing in this code. However, it does come at the cost of not being compressed, because the way they write their networking code is liberal on wasting data to the point where you can't have more than 16 players. The main thing I was going for was the [SyncVar] API, whereas the RPC API ended up being overly confusing and unnecessary. All the features like joining a game and assigning IDs you can easily write yourself.

Paid plugins

There's a lot of premium plugins that have Websocket and even P2P support. The main advantage is they provide an easy API to code in for the beginner, and thus you don't have to invent your own OP codes or even figure out how to connect games together. However:

  • usually at least $300/mo for the enterprise edition
  • you don't understand what's going on, and thus can't control or tweak it
  • what they're doing isn't even that hard to do
  • usually have pretty gnarly bugs that crop up which you won't know how to fix because you didn't write it
  • usually missing at least one critical feature which you won't know how to implement because you didn't write it

Native plugins

There are a few plugins out there that you install in the browser. These bypass typical browser security issues with browser networking by directly networking from the plugin like an application. Flash had this, but along with most of the other plugins, the browsers pulled support because they weren't secure. Support is going away, and secondly, they aren't cross platform, so they're hard to develop in.

Websockets

Winner number one! Websockets are widely supported, meaning you can deploy to all platforms and develop code from your editor without an 8 minute emscripten build on unity3D.

I use websockets to connect to my matchmaking server, which I wrote in a .Net Core 2.0 console app and deployed to heroku. The matchmaking server is around 400 lines of code, essentially just being a "create" function and a "get games" function.

If you wanted to make a backend game server with websockets rather than doing a P2P solution, then you would be able to write it in Unity3D code then run a headless instance of Unity3D, which is extremely good. You could also obviously make a websocket server in node.js or other language, but this approach has the following benefits:

  • your client and server code are in the same language
  • you don't have to re-write Unity3D code like physics and collision detection and then work hard to get client and server to agree on this.

To scale this, I believe you start to run more instances of the headless game instance. The main reason is that you can't seem to run multiple game scenes at the same time in a unity instance. I haven't done this myself, but it might be possible. Even given this drawback, it's still far easier than rewriting physics code or other core features.

To be completely fair, if you're making a simple game, like an io game, you wouldn't want to go through all this trouble. You likely would either write in javascript, a simple javascript library, or even another editor. Then, you would write a Websocket gameserver, and it doesn't have to be in node.js. The main reason in my opinion for choosing another editor is because Unity3D with WebGL is both heavy and slow to load. Even given this drawback, I'm personally sticking with Unity so I can make it pretty in-game and reuse the code after I get it up and running (already done).

WebRTC

Winner number two! WebRTC, like websockets, has wide support and a plugin for almost any platform. I use a plugin from the asset store that automatically works between all platforms, including WebGL and native builds. WebRTC is continuing to improve and gain adoption, unlike socket.io, peer.js, long-polling, or native plugins.

WebRTC is state-of-the-art for P2P games.

It can be tricky to get this one working. Luckily, I found the right plugin for this. I spent a while trying to compile WebRTC for C# myself but gave up. WebRTC has to deal with some tricky networking issues in order to get a true P2P connection from two browsers. Basically, the two browsers connect to a server (done automatically from the API) and then they signal each other to "break through" to each other starting at precisely the same time. They then exchange some tokens back and forth and a live connection begins. The server is usually included in the library, and there are even some free ones running out there.

Edit: I'm looking at HumbleNet right now, which looks extremely promising. It seems worth checking out. https://hacks.mozilla.org/2017/06/introducing-humblenet-a-cross-platform-networking-library-that-works-in-the-browser/

What I run

For my own solution, I use websockets to connect to a matchmaking server I wrote (explained earlier) where the clients list games including their WebRTC id. I then open a WebRTC connection from client to the client running the server (P2P). I write the game code in Unity3D and build it to Windows until I'm ready to deploy to WebGL. Doing this saves time building to WebGL.

  • I hate rewriting missing features that unity3D has, especially on the interface.
  • I like the asset store and the scene editor.
  • It can build to WebAssembly, which is extremely important. I believe that all web games in the future will be in WebAssembly.
  • it has the gold-standard of documentation and community, being extremely easy to research bugs that happen

Basically It follows the common pattern of development platforms:

1.platform #1 is really good and has everything

  1. platform #2 comes out which has an amazing feature of the future. Everybody jumps on the bandwagon
  2. platform #1 implements feature that #2 has and remains the clear platform of choice

I mostly wrote this article for self reference, but if there's enough support, I'll write an article on lessons learned from writing the code. This is more important... because it decides how fast you can code and how long before you end up with spaghetti. There's also a lot of tips I need to share, like for example, how Nagle's Algorithm can cap you at 5 updates a second.

Sponsored