Altruist Router

The core of Altruist's routing system revolves around the IAltruistRouter interface, which provides access to various routing functionalities. The router allows for sending messages to clients, rooms, and broadcasting messages, as well as synchronizing data across clients efficiently.

Note:

To access the router, leverage the Router property from inside a portal

Router Components

ComponentDescriptionRouter Method
ClientSenderResponsible for sending messages to individual clients.Client
RoomSenderResponsible for sending messages to all clients within a specific room.Room
BroadcastSenderResponsible for broadcasting messages to all clients except the sender.Broadcast
ClientSynchronizatorHandles the synchronization of entities across clients.Synchronize

Each of these components is available through the IAltruistRouter interface, which provides methods for interacting with each:

  • Client: Access to the ClientSender for sending messages to individual clients.
  • Room: Access to the RoomSender for sending messages to rooms.
  • Broadcast: Access to the BroadcastSender for sending messages to all connected clients.
  • Synchronize: Access to the ClientSynchronizator for synchronizing data across clients.

1. Sending Messages to Clients

The ClientSender class is responsible for sending messages to individual clients. It utilizes the IConnectionStore to retrieve the client's connection and then sends the message using the ISocket interface.

await Router.Client.SendAsync(clientId, message);

2. Sending Messages to Rooms

The RoomSender class allows you to send messages to all clients connected to a specific room. This is particularly useful in multiplayer scenarios where players are grouped into rooms or channels.

_ = Router.Room.SendAsync(roomId, message);

3. Broadcasting Messages to All Clients

The BroadcastSender class allows you to send messages to all connected clients, excluding any client (e.g. the sender). This is ideal for situations where you want to broadcast server-side updates or events to every client in real time.

_ = Router.Broadcast.SendAsync(message);

To Exclude a Client From Broadcast

_ = Router.Broadcast.SendAsync(message, excludedClientId);

4. Synchronizing Entities Across Clients

The ClientSynchronizator component enables synchronization of ISynchronizedEntity instances across clients. Entities that implement the ISynchronizedEntity interface can be synchronized with their current state and sent to all clients for consistency.

The synchronization process involves detecting which properties of the entity have changed, and then sending only the updated properties to minimize the amount of data transmitted. This is critical in real-time scenarios where minimizing network load is essential.

_ = Router.Synchronize.SendAsync(someEntity);

In this example, the state of someEntity is synchronized across all clients. Only the properties that have changed will be sent.

Entity Synchronization

The synchronization process is powered by the ClientSynchronizator class, which ensures that ISynchronizedEntity objects are kept consistent across all connected clients. When an entity is synchronized, the following steps occur:

  1. Change Detection: The process efficiently compares the current state of the entity with its previous state to identify any changed properties.

  2. Sync Data Creation: A SyncPacket is created, containing only the changed properties of the entity.

  3. Sending the Data: The sync data is broadcast to all clients using the BroadcastSender.

By using this approach, Altruist reduces the amount of data sent between the server and clients, improving performance while ensuring that all clients remain synchronized with the latest game state.

Steps to Create a Synchronized Entity

  1. Define an Entity Class: This class must implement the ISynchronizedEntity interface.

  2. Mark Fields for Synchronization: Use [Synced] on the fields that need synchronization.

using MessagePack;
using System;

public class SimplePlayerEntity : ISynchronizedEntity
{
    // The Id will be sent every time
    [Synced(0, SyncAlways: true)]
    public string Id { get; set; }

    // Synchronizing the position of the player
    [Synced(1)] 
    public float[] Position { get; set; }

    // Synchronizing the player's health
    [Synced(2)]
    public int Health { get; set; }

    public SimplePlayerEntity(string id)
    {
        Id = id;
        Position = new float[] { 0, 0 };
        Health = 100;
    }
}
  1. Attributes:
  • [Synced(X)]: Marks fields that should be synchronized with the clients. The integer X indicates the sync property order, used for efficient change detection, must be incremental and unique. Properties marked with SyncAlways = true, will always be sent over the network regardless of change detection.
  1. Constructor: Initializes the SimplePlayerEntity with a default position and health.