LogoLogo
⚠️ Outdated documentationGo to LatestHomeAPI
SDK 0.9
SDK 0.9
  • Welcome
  • Overview
    • What is coherence?
    • How does coherence work?
    • Features and Roadmap
    • Rooms and Worlds
    • Requirements
    • Release Notes
  • Get Started
    • Install coherence
    • Scene setup
    • Prefab setup
    • Baking and code generation
    • Build and run
    • Create a free account
    • Deploy Replication Server
    • Share builds
    • Troubleshooting
  • Authority and communication
    • How authority works
    • Authority transfer
    • Commands
    • Simulation frame
    • Client connections
    • Server-authoritative setup
    • GGPO
    • Animations
    • Value sync callbacks
  • Persistence
    • Overview
    • Configuring persistence
    • Storage
    • Example – a global counter
  • Optimization
    • Overview
    • Simulation frequency
    • Areas of interest
    • Level of detail
    • Interpolation
  • Connected entities
    • Overview
    • Entity references
    • Parent-child relationships
    • CoherenceNode
  • Simulators
    • Overview
    • Client vs Simulator logic
    • Build and deploy
    • Simulator load balancing
    • Room Simulators
    • Multi-Room Simulators (advanced)
    • World Simulators
    • Simulator slugs
    • Testing Simulators locally
  • Tutorial project
    • Get the Tutorial Project
    • Start Tutorial
      • 1. Transforms
      • 2. Physics
      • 3. Persistence
      • 4. Animation and variables
      • 5. AI navigation
      • 6. Network commands
      • 7. Team-based
      • 8. Connected Entities
  • Game Services
    • Game account
    • Key-value store
    • Matchmaking
  • Developer Portal
    • Overview
    • Dashboard
    • Enabling game services
    • Configure Rooms
    • Manage Worlds
  • API reference
    • coherence SDK
      • CoherenceSync
      • MonoBridge
      • LiveQuery
      • Level of detail
      • Sample UI
      • Settings window
      • Custom bindings (advanced)
      • PlayResolver
      • Rooms
      • Worlds
    • Cloud API
      • API tokens and keys
      • Game account
      • Key-value store
      • Matchmaking
    • Replication Server
    • Simulation Server
  • Schema reference
    • Overview
    • Specification
    • Field settings
    • Archetypes in schemas
  • Resources
    • Downloads
    • SDK update guide
    • Video tutorials
    • Order of execution
    • Glossary
    • CLI utilities
    • Simulator CLI arguments
    • Helper scripts
    • Troubleshooting
    • Continuous Integration setup
  • Community
    • Community
  • Additional information
    • Pricing
    • SLA
    • Unreal Engine support
    • WebGL
    • Peer-to-Peer (P2P)
Powered by GitBook
On this page
  • Overview
  • Enabling client connections
  • Connection management
  • Connection objects
  • Client messages

Was this helpful?

Export as PDF
  1. Authority and communication

Client connections

Last updated 2 years ago

Was this helpful?

Overview

The Client connection system lets you uniquely identify users connected to the same session, find any user by their ID, spawn objects whenever a new user joins the session, and send messages between those users.

To achieve this a special connection entity is automatically created by the for each connected Client, including a Simulator. Those Entities are subject to a different rule set than standard Entities. Connection entities:

  • Can't be created or destroyed by the Client - they are always Replication Server-driven

  • Are global - they are replicated across Clients regardless of the in-simulation distance or extent

Client connections shine whenever there's a need to communicate something to all the connected players. Usage examples:

  • Global chat

  • Game state changes: game started, game ended, map changed

  • Server announcements

  • Server-wide leaderboard

  • Server-wide events

Enabling client connections

The global nature of Client connection doesn't fit all game types - for example, it rarely makes sense to keep every Client informed about the presence of all players on the server in an MMORPG (think World Of Warcraft). If this is your use case, make sure Client connections are turned off by default.

To enable Client connections, check that Global Query in the is turned on (it should be by default):

Disabling Global Query on one Client doesn't affect other Clients, i.e. the connection Entity of this Client will still be visible to other Clients that have the Global Query turned on.

Connection management

Most of the Client connection functionality is accessible through the CoherenceMonoBridge.ClientConnections object:

using System.Collections.Generic;
using Coherence.Connection;
using Coherence.Toolkit;
using UnityEngine;

public class ExampleGameManager : MonoBehaviour
{
    public CoherenceMonoBridge MonoBridge;

    void Start()
    {
        // Raised whenever a new connection is made (including the local one).
        MonoBridge.ClientConnections.OnCreated += connection =>
        {
            Debug.Log($"Connection #{connection.ClientId} " +
                      $"of type {connection.Type} created.");
        };

        // Raised whenever a connection is destroyed.
        MonoBridge.ClientConnections.OnDestroyed += connection =>
        {
            Debug.Log($"Connection #{connection.ClientId} " +
                      $"of type {connection.Type} destroyed.");
        };

        // Raised when all initial connections have been synced.
        MonoBridge.ClientConnections.OnSynced += connectionManager =>
        {
            Debug.Log($"ClientConnections are now ready to be used.");
        };
    }
    
    void Update()
    {
        // IMPORTANT: All of the connection retrieving calls may return null 
        // if the connection system was not turned on, not initialized yet,
        // or simply if the connection was not found.
        
        // Specifies how many clients are in this session (room or world).
        int clientCount = MonoBridge.ClientConnections.ClientConnectionCount;
        
        // Returns connection objects for all connections in this session.
        IEnumerable<CoherenceClientConnection> allConnections
            = MonoBridge.ClientConnections.GetAll();

        // Returns all connections except for the local one.
        IEnumerable<CoherenceClientConnection> otherConnections
            = MonoBridge.ClientConnections.GetOther();

        // Returns connection object of the local user.
        CoherenceClientConnection myConnection
            = MonoBridge.ClientConnections.GetMine();

        // Returns connection object of the simulator (if one is connected).
        CoherenceClientConnection simulatorConnection
            = MonoBridge.ClientConnections.GetSimulator();

        // Retrieves a connection by its ClientID.
        CoherenceClientConnection selectedConnection
            = MonoBridge.ClientConnections.Get(myConnection.ClientId);

        // Retrieves a connection by its EntityID (warning: requires
        // connection prefab with a CoherenceSync attached).
        if (myConnection.Sync != null)
        {
            selectedConnection
                = MonoBridge.ClientConnections.Get(myConnection.Sync.EntityID);
        }

        // Specifies if this is a client or a simulator connection.
        ConnectionType connectionType = selectedConnection.Type;

        // Specifies if this is a local connection (belonging to the
        // local user).
        bool isMine = selectedConnection.IsMyConnection;

        // Returns a GameObject associated with this connection.
        // Applicable only if connection prefabs are used.
        GameObject connectionGameObject = selectedConnection.GameObject;
    }
}

Each connection is represented by a plain C# CoherenceClientConnection object. It contains all the important information about a connection - its ClientID, Type, whether it IsMyConnection, and a reference to the GameObject and Coherence Sync associated with it.

The CoherenceClientConnection.ClientID is guaranteed to not change during a connection's lifetime. However, if a Client disconnects and then connects again to the same Room/World, a new ClientID will be assigned (since a new connection was established).

Connection objects

Each Client connection can have a GameObject with CoherenceSync automatically being spawned and associated with it. Those objects, like any other objects with CoherenceSync, can be used for syncing properties or sending messages, with a little twist - they are global and thus not limited by the LiveQuery extent. That makes them perfect candidates for operations like:

  • Syncing global information - name, stats, tags, etc.

  • Sending global messages - chat, server interaction

To enable connection objects:

1. Create a client connection prefab

2. Link a connection Prefab to the MonoBridge

For the system to know which object to create for every new Client connection, we have to link our Prefab to the MonoBridge. Simply drag the prefab to the Client field in the MonoBridge inspector:

From now on every new connection will be assigned an instance of this Prefab, which can be accessed through the CoherenceClientConnection.GameObject property.

Prefab selection

Note that there's a separate field for the Simulator Connection Prefab. It can be used to spawn a completely different object for the Simulator connection that may contain Simulator-specific commands and replicated properties. If the field is left empty, no object will be created for the Simulator connection.

The Prefab selection process can be also controlled from code using the CoherenceMonoBridge.ClientConnections.ProvidePrefab callback:

using System.Collections.Generic;
using Coherence.Connection;
using Coherence.Toolkit;
using UnityEngine;

public class ExampleGameManager : MonoBehaviour
{
    public CoherenceMonoBridge MonoBridge;
    public CoherenceSync CustomConnectionPrefab;

    void Start()
    {
        MonoBridge = FindObjectOfType<CoherenceMonoBridge>();
        MonoBridge.ClientConnections.ProvidePrefab += (clientId, connectionType) =>
        {
            return CustomConnectionPrefab;
        };
    }
}

A Prefab provided through the ProvidePrefab callback takes precedence over Prefabs linked in the inspector.

Client messages

public class PlayerConnection : MonoBehaviour
{
    // My chat command
    public void OnChatMessage(string message)
    {
        Debug.Log($"Received chat message: {message}");
    }
}

Don't forget to bind the new command:

Client messages can be sent using the CoherenceClientConnection.SendClientMessage method:

using UnityEngine;
using Coherence;
using Coherence.Connection;
using Coherence.Toolkit;

public class PlayerConnection : MonoBehaviour
{
    void Start()
    {
        var monoBridge = FindObjectOfType<CoherenceMonoBridge>();
        CoherenceClientConnection myConnection = monoBridge.ClientConnections.GetMine();

        myConnection.SendClientMessage<PlayerConnection>(nameof(OnChatMessage),
            MessageTarget.Other, "Hello!");
    }

    // My chat command
    public void OnChatMessage(string message)
    {
        Debug.Log($"Received chat message: {message}");
    }
}

If the ClientID of the message recipient is known we can use the CoherenceMonoBridge.ClientConnections directly to send a client message:

private ClientID lastClientId;

private void OnConnectionCreated(CoherenceClientConnection clientConnection)
{
    if (!clientConnection.IsMyConnection)
    {
        lastClientId = clientConnection.ClientId;
    }
}

public void SendMessageToLastConnection(string message)
{
    var monoBridge = FindObjectOfType<CoherenceMonoBridge>();
    monoBridge.ClientConnections.SendMessage<PlayerConnection>("OnChatMessage",
        lastClientId, MessageTarget.AuthorityOnly, "Hello!");
}

This step is described in detail in the . In short, a Prefab with a CoherenceSync and a custom component (PlayerConnection in this example) must be created and placed in a Resources folder:

PlayerConnection prefab

Client messages are sent between the . Implementing Client messages is as simple as adding a new method to the component used by our connection Prefab and binding it in the configuration:

Prefab setup section
commands
Client connection objects
Replication Server
LiveQuery
MonoBridge
MonoBridge component
MonoBridge with linked connection prefab
Binding a client message