Overview

Overview

Peer Types

There are three types of network peers that take part in a uLobby session - lobby, game servers and game clients. These connect together and communicate with each other to perform the tasks needed to create the game's lobby system.
The lobby is a normal Unity game instance that uses uLobby's lobby-side API to initialize and create the actual lobby that others can then connect to. It is similar to a server in uLink, and therefore uses a similar API.
A game server is a Unity game instance that uses uLobby's server API to identify that it is a server able to host games. Note that in uLobby's network topology, game servers are clients that connect to the lobby in the same way as game clients do. It is only in the context of the game they host that they are actual servers.
A game client is a Unity game instance that uses the client API of uLobby to identify that it is a player client interested in finding a game to join and play. It connects to the lobby just like a game server does.

Operation

To start a uLobby session, the first thing to do is to start the lobby instance. After this, game servers can be started and connected to the lobby to make them available for players. After starting the lobby and connecting game servers to it, game clients can start connecting to the lobby to find available games. Game servers can be dynamically removed and added in runtime either manually or using code, and uLobby will reflect this in the lobby.
After finding a game on a certain server for a player, the player's client can proceed to connect to the server and start playing. How the connection to the server is made is outside of uLobby's area of responsibility - it does not need to know anything about the game being played or of its network architecture. Having found a game, the game client can choose to either disconnect from the lobby entirely or to keep the connection during the game (thereby having both a connection to the lobby and the game server). uLobby provides several features that can be used while playing the game, such as chatting with people playing other games on other servers, adding them as friends and seeing when they log in to an account.

Code Overview

The core functionality of uLobby is accessed through the Lobby class in the uLobby namespace. This class is similar in structure to the Network class in Unity's built-in network and uLink, and consists of a set of static methods. It is used by each of the lobby, game servers and game clients for performing basic tasks such as connecting to the lobby system and sending RPCs.
The rest of uLobby's functionality is provided by a separate set of classes; each major piece of functionality consists of a main class with static methods for performing the primary functions, and some helper classes used by this class. For example, the account management functionality is implemented in the AccountManager class, which has static methods for registering new accounts, logging in and so forth. It also contains the class Account that represents a single account.

Database

Some of the lobby components store and load information from a database. uLobby currently only supports using uGameDB as a database, but this might change in the future to allow any type of database to be used.

Authoritative Lobby

Several of the classes in uLobby offer both a client-side and a lobby-side API. In these cases, the lobby-side API performs the actual functions, while the client-side API acts as a proxy to provide them to clients. The lobby-side API in these classes is accessed from a nestled Master class inside the main class. Some methods are available in both client-side and lobby-side versions - these have the same name in the main class and the Master class. Other methods are only available on one of the sides.
To take an example, the AccountManager.LogIn() method is used by clients to log in to a specified account. This method does little more than send a request to the lobby, which then executes the corresponding lobby-side version of the method, AccountManager.Master.LogIn(). The lobby-side method can also be called directly by code on the lobby, bypassing the need for the client to initiate the action. Regardless of which method is used, the outcome on the client will be identical.
The lobby-side version of a method is typically more general than the equivalent client method and takes extra parameters that specify for whom or what the operation is carried out. For example, the AccountManager.LogOut() client-side method takes no parameters and logs out the peer that executed it from its currently logged in account. AccountManager.Master.LogOut(), however, needs to know what peer is going to be logged out, so this must be supplied as a parameter.
The client-side API is offered as a convenience to the developer of the lobby system to make it quick and simple to implement lobby clients. However, the lobby-side API is completely sufficient on its own and developers can choose to bypass the client-side API and implement their own communication with the lobby if this is desirable. For example, you might want to implement extra checks before allowing a client to log in to an account. Instead of using AccountManager.LogIn() you could then implement your own log in method that sends an RPC to the lobby, performs the checks, and then executes AccountManager.Master.LogIn().
uLobby also supports turning off the client-side API of specific features entirely. This means the lobby will no longer blindly execute requests initiated by clients, but instead the developer must implement this manually. The main reason to do this is for security. A hacked client could otherwise be used for sending crafted RPCs that perform lobby-side functions through uLobby's client API. If you do not intend to use the client API as-is, it should be turned off to make the lobby completely authoritative.

Requests

Many lobby-side API methods return objects of type Request. This signals that the method is asynchronous and takes a while to execute, often because it needs to speak to the database to perform its function. The returned request object represents the specific request that was made and can be used for keeping track of it, waiting for it or finding out its status.
The Request class contains a few properties that inform about the status of the request. The isDone property says whether the request has completed yet. The isSuccessful property says whether the request is done and was successful. The exception property will be null as long as the request does not encounter any problems. If an error occurs during execution of a request, the request will be stopped, isSuccessful will be set to false, and exception will be set to the exception that occurred.
The WaitUntilDone() method returns a coroutine that finishes execution when the request completes (either successfully or with an exception). Using this method makes it simple to write code that needs to perform a sequence of events in a linear fashion.
Some requests return a value upon finishing execution. These requests have the generic type Request<T>, where T is the type of the return value. The Request<T>.result property contains the value returned by a successful execution of such a request. It can only be retrieved after the request has completed successfully.
The Request class contains a few events that can be subscribed to:
  • OnDone - Called when the request has completed (successfully or with an exception).
  • OnSuccessful - Called when the request has finished successfully.
  • OnException - Called when an exception occurred during execution of the request.