Implementing Client-Hosting

Bundling the Replication Server

To bundle a Replication Server with the build of your game, go to coherence > Settings and tick the Local Replication Server > Bundle In Build checkbox.

Currently, coherence supports bundling on Windows, MacOS, and Linux. We are working on adding support for more platforms in the future.

The Bundle In Build option in Project Settings

If your game uses a custom build process where the automatic bundling doesn't work well, you can also use a manual approach.

Here's a code example:

The BundleWithStreamingAssets method will copy the Replication Server and a combined schema (which contains all active schemas) for the target platform into the streaming assets folder.

Starting a local Replication Server

To start the bundled Replication Server from within your game, you can use the Launcher and ReplicationServer classes provided by the coherence Unity SDK. It will make sure that the correct parameters are passed to the Replication Server at startup, and it will also help you manage the child process.

Here's a simple code example of how to start and stop the Replication Server using the coherence API:

It is very important to keep track of your child process (via the IReplicationServer object) and close it down properly, or else you will leave the Replication Server running on the user's machine. Note that it's only the person hosting a game that needs to start an instance of the Replication Server, players joining a game should connect normally.

In case your game crashes, and your child processes are not cleaned up, it might be useful to set a AutoShutdownTimeout so that the Replication Server (RS) will automatically shut down after certain amount of milliseconds when no Clients are connected to it. By default AutoShutdownTimeout is set to 0, which means the Replication Server will never shut down automatically.

Replication Server log output

By default, the coherence Replication Server will output its logs to the standard output. Use OnLog event in the ReplicationServer class to receive log events in your Unity application. If you configure the LogTargets in the ReplicationServerConfig object, make sure to add a LogTarget.Console target or OnLog event will not work as expected.

Relays

For players to communicate with one another over the Internet, a networking service is required. The networking service provides features such as setting up games, establishing connections, and sending data.

By default, coherence provides all of these networking services out-of-the-box. In this scenario, players all communicate with one another via a Replication Server that is hosted in the coherence Cloud, so you don't have to worry about anything.

In a Client-hosted scenario however, the Replication Server runs on the hosting player's machine. Therefore, the connectivity between clients and host must be provided via an external networking service. In the context of Client-hosting, we call such networking service a relay, since it is used to relay traffic between the Clients and the Replication Server running on the host's machine. You can also think of a relay as tunneling traffic between clients and host.

Custom relay (Advanced)

Similar to the Steam relay above, you can create your own custom relay implementation and route traffic via any networking service. The relay implementation consists of three parts, each class implementing one of three interfaces.

  • ITransport (Client) - Outgoing connection. Passes messages between the client and the networking service.

  • IRelay (Host) - Listens for incoming connections and instantiates IRelayConnections.

  • IRelayConnection (Host) - Incoming connection. Passes messages between the Replication Server and the networking service.

Let's say we want to implement a custom relay that uses an API called FoobarNetworkingService. The code here outlines the main points to implement for routing network traffic.

First, we'll create a CustomTransport class to manage the outgoing connection from the client to the host. CustomTransport implements the ITransport interface that provides a few important methods. The Open and Close methods are used to connect and disconnect to/from the networking service. The Send and Receive methods are used to send and receive messages to/from the networking service.

The CustomTransport will be instantiated when the client attempts to connect to the host, usually as a result of calling CoherenceBridge.Connect. You can control how the transport is instantiated by implementing an ITransportFactory.

Finally, to configure the client to actually use the CustomTransport, just set the transport factory on CoherenceBridge.

This is everything needed on the client-side.

You can call _SetTransportFactory(null)_ to disable the custom transport and connect as normal.

On the host-side, we need a CustomRelayConnection class to manage the incoming connection. This class implements IRelayConnection and is a mirror image of the CustomTransport. The OnConnectionOpened and OnConnectionClosed methods are called in response to CustomTransport.Open and CustomTransport.Close.

The SendMessageToClient and ReceiveMessagesFromClient methods are responsible for sending and receiving messages over the networking services, similar to CustomTransport.Send and CustomTransport.Receive.

Now we just need a CustomRelay class that listens for incoming FoobarConnections and maps them to a corresponding CustomRelayConnection.

Finally, to configure the host to actually use the CustomRelay, simply set the relay on the CoherenceBridge:

These are all the necessary steps required to configure a custom relay.

For a complete relay code example, please review the Steam Relay source code.

Last updated

Was this helpful?