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.
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:
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.
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.
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 | ✅ | ✅ |
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.
commsAdapter
section of the realm
description and in accordance with
ADR-180 Communication protocol.
Connected users send their positions through this channel and receive an Archipelago island
ID to which they will be connected and the required settings to connect to the LiveKit room
(transport) where the island messages will be exchanged with the cluster of users.
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
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
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
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
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
Date: TBD