The Spaceteam Networking Post

Many people have asked about the networking in Spaceteam, so it’s about time I wrote an official blog post. However, I’m currently rebuilding the entire game including the networking layer in Unity so I’ll write about both the Old System and the New System.

I’m also sharing a link to an early version of the New System, called “CaptainsMess“, as a Unity asset package. It’s not finished yet but Wifi connections work well enough for me to finish the rest of the game.

Please check it out and help me test and improve it!

CaptainsMess on GitHub: https://github.com/hengineer/CaptainsMess


The Old System (Spaceteam versions up to 1.8.x)

I wrote the original game for iOS using Objective-C and the Cocos2d game engine. It was later ported to Android by a company called Apportable. They have a cross-compiling SDK that generates Android apps from Objective-C code so there is no easily-accessible “Android source” to share. Apportable did make some of their Bluetooth code available though, which you can find here: https://github.com/apportable/Bluetooth

On iOS I used Bonjour (also known as ZeroConf) to discover other devices, which works over Wifi and Bluetooth. I wanted to make it as easy as possible to connect (users shouldn’t need to know or care *how* the game is connecting, they just want to play together!)

I learned a lot from the BeamIt! source code and also the “WiTap” sample code from Apple.

On iOS I used the NSNetServices API but I also used a third-party library called HHServices for additional Bluetooth support. I know that Zeroconf is an open protocol so I’m guessing there are probably implementations for Android.

When you choose “Play” the devices all start off as a clients and look for an available server. If they find one they try to connect to it. If they can’t find one within 3 seconds, they start advertising themselves as a server as well. When one of the connections completes successfully (client or server) the other one is cancelled. Eventually everyone gets connected. Sometimes this leads to more than one group (eg. 2 groups of 2, instead of one group of 4), but in practice this is pretty easy to fix by some players leaving and re-joining one at a time,

Once the devices are connected I use another third-party library called CocoaAsyncSocket to send messages and exchange data between phones. Again, I’m sure there are similar libraries for Android.

Other notes:


The New System (Spaceteam 2.0+)

I’m trying to replicate this system in Unity using as much out-of-the-box support as I can. My first attempt uses the Unity Networking HLAPI (High-Level API) introduced in Unity 5.1, specifically the NetworkLobbyManager and NetworkDiscovery classes. Unity’s source code for the HLAPI has been a great reference and is available here: https://bitbucket.org/Unity-Technologies/networking

I have my own subclass of NetworkLobbyManager and two NetworkDiscovery objects: one to broadcast and one to search.

When you choose “Play” the discovery server starts broadcasting its information and the discovery client starts searching.

The broadcast data holds information about the server, eg:

(version) : (unique peer id) : (is the server open?) : (number of players)

When this information changes, the server has to be restarted with new broadcast data and is treated as a “new” server, so the clients get another chance to decide whether to join it.

If the client finds an open server with at least 1 other player, it tries to join.

Otherwise, if nothing appropriate is found after 3 seconds, but there are enough solitary broadcasters to create a lobby then a decision is made for one of them to start a new (open) server. It’s important that the candidate is chosen unambiguously or they would split into multiple lobbies with one occupant each.

Currently the server candidate is picked naively using the lowest peer ID but this could easily be changed to favour the “best” device by comparing processor speed or something. Seems like a good idea but I’m not sure if it really matters yet.

Once players are connected to a lobby, the library then manages ready states and a countdown timer before sending a message to start the game.

So far only Wifi is supported but I’m planning to add Bluetooth support by integrating one or more 3rd-party Bluetooth libraries such as:

If you’ve used these libraries before I’d love to hear your experiences with them.

I may have to drop down to the Low-Level Network API in order to integrate them properly.

Some issues I ran into during development:

Anyway here’s the link to the first public version. Feedback and improvements are welcomed and encouraged!

https://github.com/hengineer/CaptainsMess" class="pos-absolute top-50 left-0 t-tY-50 | p-4 ml-1 | td-none | brad-4 bc-neutral-100 bwidth-1 bstyle-dashed bcolor-neutral-500 __hover-1 __soft-shadow" ml-3="xs,sm"> CaptainsMess on GitHub: https://github.com/hengineer/CaptainsMess

Space out!

Henry