Boss Room, released in early access in April of 2021, is Unity’s living educational tool for developers that now features even more elements of Unity Gaming Services (UGS) for hands-on learning of multiplayer game development.
Boss Room is a multiplayer sample game that features a variety of UGS in a production-ready environment for developers to learn about multiplayer game development.
Boss Room serves two primary goals:
Just last month, Boss Room was updated to release v1.1.0-pre and boasts a whole new feature set for developers looking to explore the services side of multiplayer game development.
Read on to learn more about the way Boss Room leverages Unity Gaming Services integration to create a lobby functionality that players expect from their multiplayer experiences.
In this blog, we want to avoid reiterating what the Lobby, Relay, and Authentication service documentation pages cover in great detail – such as steps to integration. Instead, we want to focus on some of the learnings and gotchas that we had when integrating services and our solutions to those challenges.
Boss Room is a multiplayer game, and as such, having a way to discover and join games is essential.
Today, we have two options for players to find each-other and to connect to the game.
The direct IP connection allows the users to connect to each other through their publicly exposed IP address. However, connecting to someone else’s computer is often not as straightforward as one would think due to computers being hidden behind NATs (network address translation devices) and routers.
Port forwarding can make it possible to create a connection, but it would still require the host to do extra work in order for other players to be able to connect. This solution also does nothing to facilitate game session discovery – players have to share the join information through out-of-game means. The upside is that this connection mode does not require internet connection and works in LAN environments.
However, Boss Room is a multiplayer experience that is meant to be also playable over the internet, with sessions that are easily discoverable and that don’t force the host players to perform port forwarding.
This is where Unity Gaming Services come into play – a combination of Authentication, Lobby, and Relay is what allows us to make it easy for players to host and join games that are playable over the internet, without the need for port forwarding or out-of-game coordination.
After integrating Authentication, Lobby, and Relay services into Boss Room, it became simpler to host and join games, cutting down on the need to do port forwarding and sharing the information needed to join a game externally.
Overall, it's now a much smoother and quicker experience, which is nice in a sample and essential in a production game.
Now let’s take a look at some of the learnings that we had!
From a gameplay perspective, Boss Room is a fully functional host-served co-op multiplayer RPG that allows for up to eight players – you can learn more about its features and gameplay here.
In order for the user to be able to interact with the rest of Unity Gaming Services, the user has to be authenticated, therefore as soon as the game is launched and the main menu scene has loaded – Authentication is kicked off.
Authentication service supports anonymous sign-in and doesn't require any additional input from the player.
An important thing to note is that the Authentication API doesn't by default distinguish multiple instances of the same project running on the same machine and ends up logging in as the same user in all those different instances. This messes up the ability to test the game locally – both ParrelSync clones and actual game builds are affected by this.
Luckily there is a simple solution – Authentication supports Profiles, which in our case was exactly what we were looking for – it amounts to effectively different users that can all be living on the same physical machine. To test locally, we need both builds and editor players to be able to switch to different Profiles.
The ProfileManager class wraps the logic for deciding what Profile you should be using, if any. In builds we rely on the command-line argument `-AuthProfile` to specify the new profile id. When iterating in the editor, we rely on ParrelSync, so this class is also capable of using ParrelSync's `CloneManager` custom arguments to decide what user profile to use.
We use `ProfileManager.Profile` to generate custom `InitializationOptions`:
The code that executes profile switch and sign-in logic itself is as follows:
After awaiting the completion of the task above, we're ready to use other services, and we have a somewhat automated local iteration workflow when using ParrelSync and custom Profiles. We recently changed this in boss room to be dataPath based to be less tied to tools, but the above solution is still valid for ParrelSync users.
Once connected, players will get into the character selection scene, where they will choose from one of the eight available heroes. When all players are ready, a short timer shows and then all Heroes are transported into the Boss Room environment where the actual gameplay occurs.
A distinction needs to be made between a UGS Lobby and our in-game "lobby", aka the character selection scene. Character selection scene in Boss Room is driven by netcode.
It is important to highlight that it is possible to pass arbitrary metadata through the Lobby service and thus a similar character selection scene could be implemented using that functionality.
Currently the Lobby service has to be polled for updates, which is not ideal for a responsive feel to character selection, however in the future, when there is an option to get real time updates from the Lobby service, it would be a good alternative way to implement something like this.
Handling player disconnections and reconnections is a necessity in a multiplayer game.
Boss Room is using a session management system which ensures that when a player disconnects, some data is kept and accurately assigned back to that player if/when they reconnect (see SessionManager.cs – OnClientDisconnect).
The way we handle restoration of user data on reconnection can be found in SessionManager.cs - SetupConnectingPlayerSessionData which is called as a part of a connection approval check that is handled by the host (see ServerGameNetPortal.s – ApprovalCheck).
Now that we have lobbies in the game, it's important to promptly remove disconnected players from them. Otherwise, the disconnected player won't be able to rejoin the lobby since they are still considered in it.
When a player disconnects from Relay, eventually Lobby and Relay service integration (that needs to be enabled before we run UTP connection) would kick out the disconnected players, however the timeout for disconnect is quite long (~2 minutes), and as such we can't rely solely on this mechanism.
To make the process of leaving lobby more reliable, there are several additional cleanup mechanisms:
Finally, the client contains checks that determine if the host has left the lobby, and if so, the client leaves the lobby too. The code for this can be found at ClientGameNetPortal.cs - OnDisconnectOrTimeout.
As our UGS portfolio and networking solution continues to grow and improve, so will the Boss Room sample. Here are ways to stay involved: