ADR-204: Comms Architecture for new client

More details about this document
Latest published version:
https://adr.decentraland.org/adr/ADR-204
Authors:
pentreathm
Feedback:
GitHub decentraland/adr (pull requests, new issue, open issues)
Edit this documentation:
GitHub View commits View commits on githistory.xyz

Abstract

The current Decentraland client communication protocol effectively supports user scaling but has inherent design limitations that restrict certain functionalities in Genesis City, such as content casting for in-world streaming, serverless multiplayer experiences, and being able to handle scene-hosted events with speaker moderators. This ADR explores the architectural decisions behind a new communication protocol designed to overcome these limitations.

Context, Reach & Prioritization

The new architecture, incompatible with the existing implementation, will be deployed in a forthcoming client version and become the new standard.The objective is to incorporate the following functionalities without overburdening the client implementation with additional complexities, while maintaining the ability to stream the world and visualize users in surrounding areas. This entails:

Decision

Archipelago Background

The communications system in Decentraland relies on the Archipelago protocol, which clusters users into islands based on their positions. An island is essentially a group of users, and the communication between them happens within this group. The islands are not static; they are dynamically recalculated in real time as users move.

To handle scalability, the Archipelago protocol allows islands to overlap when the user limit of an island is reached, ensuring that large groups of users in the same area are still supported. The maximum number of users per island can be adjusted to optimize client performance by balancing how many avatars the client can render without degrading rendering performance. The protocol uses several heuristics to manage island behavior—such as calculating the center of an island, assigning users to islands, creating new islands based on user distance from the center, shifting the island center as users move, and merging islands when necessary.

The Archipelago protocol scales efficiently due to its dynamic island calculations and users grouping, but a key limitation is that scenes have no direct authority over the communication channel. This prevents features like managing speaker permissions, streaming content to members of a cluster, or sharing metadata such as the states of objects within a scene. If scene-specific data were tied to the island, the island could shift its center to a different scene, leading to conflicts in data consistency or permissions, as the island's dynamic nature might affect scene control.

Solution

Maintain the current Archipelago implementation while establishing a new scene room connection specific to the active scene. The Archipelago channel should be reserved solely for receiving avatar positions, profile update notifications, and nearby chat messages with the objective to be able to interact with users beyond the limits of a scene. All communications, including voice chat, scene objects state, and streams, will be shared within the scene channel. This new model grants scene owners authority over the communication channel, allowing them to share content streams, share object states or handling speakers, providing a consistent experience for all users visiting the scene.

comms

In the illustrated scenario, Peers 1, 2, and 3 are connected to the scene room E1. Additionally, Peer 1 establishes a connection to the island I1, while Peers 2 and 3 are linked to the island I2. This example serves as a simplified illustration. Users may be far apart within the same scene, but this aims to demonstrate that if a peer is at the edge of a scene, they will be able to see other players who are not within the scene but are within viewing range. On the other hand, the scene channel will be there to share consistent data among the visitors, like a stream of video on a texture or the state of an object like a door that can be opened or closed besides also sharing information about the users visiting the scene.

The table below outlines the information that will be communicated through each channel.

Protocol Messages island scene-room
Positions/Movements
Profile Events
Voice
Cast Stream
Scene State
Nerby Chat

Design Considerations

The establishment of the connection with the island remains unchanged, as that portion of the protocol is the same. The key difference lies in the types of messages sent through the channel. To establish a connection with a scene-room, a new service called Gatekeeper will be introduced to manage token permissions for the transport layer (LiveKit). Only one scene room can be active at a time, as a user can only be present in one scene at any given moment. The scene room operates similarly to the communication service implementation used in worlds, where each scene has its own dedicated room. The Gatekeeper service will also allow scene owners to create authorizations for users, which will be reflected in the LiveKit token. This capability will enable them to moderate voice interactions and data streams within the scene effectively.

comms-services

General Connection Flow

The user logs into the platform, retrieves a realm description, and initiates a connection handshake with the backend. In parallel, the user establishes both the Archipelago connection and the scene connection to begin exchanging information with other users connected across different clusters.

sequenceDiagram
actor User
participant C as Decentraland Client
participant R as Realm Provider
participant WS as WebSocket Connector
participant N as NATS
participant A as Archipelago Core
participant L as LiveKit 
participant G as GateKeeper 
User->>C: log in
Note over A: Initialize LiveKit Transport
A->>N: subscribe: peer.*.heartbeat/disconnect
C->>R: get realm /main/about
R-->>C: realm { comms: adapter: ... }
critical Handshake
    C->>WS: Start Handshake: Authenticate /ws challenge Request
    WS-->>C: challengeResponse: messageToSign
    C->>WS: signedChallenge  
    WS->>WS: validateSignature 
    WS-->>C: Welcome
end	
par Archipelago Room
    C->>WS: Heartbeat with position 
    WS->>N: publish: peer.0x....heartbeat
    WS->>N: subscribe: peer.0x...island_changed 
    A->>N: publish: peer.0x...island_change: islandId & connStr 

    N-->>WS: islandID & connectionStr
    WS-->>C: IslandId & connectionStr
    C->>L: connect to LiveKit room Id = islandId
    L-->>C: roomConnection
    C->>L: msgs to roomId: movement / nearby chat
    L-->>L: brocast msg to roomId participants 
and Scene Room
    User->>C: move to parcel 
    C->>G: Get sceneRoom 
    G-->>C: room connectionStr
    C->>L: Connect to Scene Room (realm:sceneId): connectionStr
    L-->>C: roomConnection
    C->>L: send message: movement / playEmote / chat / voice / announceProfileV
    L-->>L: brodcast msg to roomId participats 
end

Sequence Diagram Breakdown

1. Handshake

sequenceDiagram
actor User
participant C as Decentraland Client
participant R as Realm Provider
participant WS as WebSocket Connector
User->>C: log in
C->>R: get realm /main/about
R-->>C: realm { comms: adapter: ... }
critical Handshake
    C->>WS: Start Handshake: Authenticate /ws challenge Request
    WS-->>C: challengeResponse: messageToSign
    C->>WS: signedChallenge  
    WS->>WS: validateSignature 
    WS-->>C: Welcome
end	

2. Archipelago Island

sequenceDiagram
participant C as Decentraland Client
participant R as Realm Provider
participant WS as WebSocket Connector
participant N as NATS
participant A as Archipelago Core
participant L as LiveKit 
Note over A: Initialize LiveKit Transport
  A->>N: subscribe: peer.*.heartbeat/disconnect
  C->>WS: Heartbeat with position 
    WS->>N: publish: peer.0x....heartbeat
    WS->>N: subscribe: peer.0x...island_changed 
    A->>N: publish: peer.0x...island_change: islandId & connStr 
    N-->>WS: islandID & connectionStr
    WS-->>C: IslandId & connectionStr
    C->>L: connect to LiveKit room Id = islandId
    L-->>C: roomConnection
    C->>L: msgs to roomId: movement / nearby chat
    L-->>L: brocast msg to roomId participants 

3. Scene Room

sequenceDiagram
actor User
participant C as Decentraland Client
participant G as GateKeeper 
participant L as LiveKit 

  User->>C: move to parcel 
    C->>G: Get sceneRoom 
    G-->>C: room connectionStr
    C->>L: Connect to Scene Room (realm:sceneId): connectionStr
    L-->>C: roomConnection 
    C->>L: send message: movement / playEmote / chat / voice / announceProfileV
    L-->>L: brodcast msg to roomId participats 

Protocol Messages

The protocol messages for profiles, positions, and updates have been optimized for client performance, aiming to minimize data transmission through the channels. In this new implementation, profiles are no longer sent through the island and are instead retrieved from the Catalyst network. When a user updates their profile, a notification is sent, and the updated profile is downloaded from the servers. This approach ensures that avatar impersonation is prevented, as the signed profile is retrieved from a trusted Catalyst node.

TBD

Deadline

Date: TBD

Consequences

License

Copyright and related rights waived via CC0-1.0. DRAFT Draft