Frequently Asked Questions

So if I use this plugin then I don't have to pay Unity for multiplayer?

Yes, with this asset you can remove the cost completely as long as you implement your own matchmaking to replace Unity's and accept that without the relays ~10% of connections will fail. We're not a big fan of failed connections, so by default the plugin falls back to using the relays if all other connection methods fail. This means that your players will always be able to connect, but you will have to pay Unity for any bandwidth used on the relays. If you don't want the relays to be used at all it is as simple as unchecking the "Connect Relay" option.

Don't we need the relays? Will my players be able to connect without them?

The relays do ensure that players can always connect, but most of the time they are not actually necessary.
Any host that is not behind a router can be connected to directly. No relays needed.
If the host is behind a router, then NAT punch-through can be used to connect. This is successful ~90% of the time according to the best numbers we can find.*
Adding port forwarding on top of that increases the success rate a bit more.
If you allow for fallback to the relays then the success rate is 100% but you will have to pay Unity for the bandwidth used by the ~10% of players that can only connect via relay.
If you don't allow for fallback to the relays then the success rate falls somewhere a bit short of 100%, but you never have to pay a dime.
*There aren't any hard numbers on this but every estimate we've found falls in this range (Peer-to-Peer Communication Across Network Address Translators, Behavior and Classification of NAT devices and implications for NAT Traversal)

What is automatic port forwarding?

Google or wikipedia can probably give you a decent technical answer, but you are here, so here is my quick and dirty version: When multiple computers are behind a router they all share a public IP address. When a client tries to connect to that shared IP the router needs some way to know which of the computers to actually connect to. Port forwarding is a way to tell the router to forward all traffic coming in on a specific port to a specific computer. There was a time when it was pretty common for users to have to do this manually from their router settings. Luckily those days are long gone and now we have automatic port forwarding, which is just what it sounds like. Instead of the user manually setting ports and ip addresses it is all handled automatically. The reason this isn't built into Unity already is that the relays don't need it. With relays everyone is connecting to Unity's server and no one is being connected to so port-forwarding is never an issue. Without the relays you need port-forwarding for players to be able to host a game behind a router and be connected to.

What is NAT Punch-through?

NAT Punch-through is...honestly pretty complicated, but here's the short version: Port forwarding doesn't work on all routers, or it may be disabled by users. NAT Punch-through is a more complicated way of accomplishing the same thing that port forwarding would normally be used for. It works by having every player connect to a third party server, known as a Facilitator. When a client tries to connect to a host, the Facilitator does some magic to find a set of ports that they can use to connect without the router blocking the connection. Once the client has connected to the host the Facilitator is taken completely out of the loop. No network traffic is sent through the Facilitator so it uses very little bandwidth / cpu. Pretty much the opposite of how the relays work.

Are the connections direct / peer-to-peer?

Yes...except for when all other connection methods fail and clients are forced to connect via relay. If relay connections are disabled than all connections will be directly peer-to-peer.

Will the Facilitator run on...?

The answer is almost definitely "yes." The Facilitator is only used to establish the initial connection between client and host. Once the connection is made all data passes directly from one peer to the other. Nothing goes through the Facilitator so it uses very little bandwidth / cpu and will run on almost any hardware. It has been tested and confirmed to work on AWS free tier and rackspace cloud hosting.

We also keep a Facilitator running at www.grabblesgame.com that you are welcome to use for testing / development. There is no guarantee of up-time though and it could disappear at any moment so please don't try and use it in a released game.

I don't have anywhere to host the Facilitator. Can I still use this plugin?

Yes! We keep a Facilitator running at www.grabblesgame.com that you are welcome to use for testing / development. There is no guarantee of up-time though and it could disappear at any moment so please don't try and use it in a released game. You will need to find somewhere to host your own Facilitator before releasing your game.

How do I host the Facilitator on AWS?

Note: This is just one way to go about it. Any decently new OS should work to host the Facilitator. Some steps (like the dist-upgrade) may be avoided by using a newer version of linux.
Credit to Doghelmer for writing this up. Thanks!

  1. Create an AWS Account here: https://console.aws.amazon.com/ec2/
  2. From your Dashboard, choose to Launch Instance.
  3. Choose Ubuntu Server 14.04 LTS (or newer) and wait for it to finish Initializing.
  4. Follow the FAQ to change the new server's security settings.
  5. Using FileZilla, upload the "Facilitator" file (no extension) included with the plugin. Here's some instructions on getting it uploaded. It should go in the /home/ubuntu directory.
  6. Get Putty and connect to the server using these instructions.
  7. In Putty, type the following series of commands: sudo apt-get install libstdc++6 sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get upgrade sudo apt-get dist-upgrade chmod u+x Facilitator
  8. Since Putty ends your session when you quit the program, you'll want to use something called Screen to create a second "window" (which does not actually appear in a second physical window on your desktop). To do this, use the commands: screen (starts the program) "ctrl+a" and then "c" (creates a new window) ./Facilitator (starts the Facilitator) "ctrl+a" and then "n" (switch to the previous window)
  9. Now you can quit out of Putty, and the Facilitator will keep running.
  10. In Unity, your NatHelper's Facilitator IP should be the "Public IP" that you see in the description when you click on your server instance in AWS.
  11. Facilitator Port should be 61111.
  12. And there ya go.

I'm hosting the Facilitator on AWS EC2 server but I can't connect?

You need to edit the settings on your default Security Group:

  1. From the EC2 Dashboard go to Security Groups under NETWORK & SECURITY on the left.
  2. At the bottom you should see some tabs. Go to the Inbound tab.
  3. Click "Edit" to add to change the inbound rules and then "Add Rule"
  4. Under type use Custom UDP Rule
  5. For the Port Range put 61111
  6. For the Source put "Anywhere"
That should do it.

How do I run at boot and automatically restart in case of a crash?

There are many ways to accomplish this in linux depending on your preferences and distro. Here is one way that works in Ubuntu and probably other Debian based distributions:
Credit to jiak1 for helping me figure this out. Thanks!

  1. Create a shell script next to the Facilitator called Facilitator.sh
  2. Run chmod +x ./Facilitator.sh to give the script execute permissions
  3. Edit the script to look like this: until /home/facilitator/Facilitator -v; do echo "Facilitator crashed with exit code $?. Respawning.." >&2 sleep 1 done This will run the Facilitator until it stops running, then print a message and run it again. Make sure to use the correct path to your Facilitator and to pass in any arguments you want. In this case I'm passing in -v to get verbose output but you could also pass in -p to set the port or -i to set the ip.
  4. Run crontab -e to add a new entry to run the above script on reboot.
  5. Add the following line: @reboot screen -S Facilitator -d -m /home/facilitator/Facilitator.sh
  6. Save and exit the crontab editor
  7. Now when your server reboots the script from above will run and the Facilitator will be launched and kept running.
  8. Since the Facilitator was started via screen you can use screen -r to see the running session and connect to it.

How long are you planning on supporting this asset?

We will continue to support the plugin for as long as people are are still using it. If we stop supporting it I (Zebadiah Long) hereby do solemnly swear to release the source code. If UNET gets replaced with something else, or routers miraculously start working properly, or the sun implodes a few millenia early we will probably discontinue support.

Will this work for mobile platforms (iOS and Android)? If not, is this planned?

No. I suspect it is possible, but there is no timeline on when I'll get around to figuring it out. Maybe never?

What about web builds / WebSockets

The library we use for puchthrough (RakNet) does not support WebSockets. So...that's a no. There are no plans to add WebSocket support at this time.

How do I replace Unity's matchmaking with something else like Steam?

At it's heart matchmaking is really simple. You just need some way to store each host's connection data and some way for the clients to get the data so they can connect. Steam lobbies are a popular choice but it's also fairly easy to roll your own system with something like php and mysql. Here's an example with steam lobbies: // Do this on the host in OnCreateMatch() after creating the steam lobby SteamMatchmaking.SetLobbyData(steamIDLobby, "matchID", createMatchResponse.networkId); SteamMatchmaking.SetLobbyData(steamIDLobby, "guid", natHelper.guid.ToString()); SteamMatchmaking.SetLobbyData(steamIDLobby, "publicIP", externalIP); SteamMatchmaking.SetLobbyData(steamIDLobby, "internalIP", internalIP); Clients can then find and join the steam lobby as normal. Once they are in a lobby they read the host's connection info from the lobby data and pass it in to StartClientAll() to connect.

What about the consoles?

I don't know man, I'm pretty sure you won't be using the relays on the consoles anyway so you probably don't need this plugin for a console only release. I'll update this if I ever figure out more.