Archipelago
Archipelago is the realm service that groups nearby players into islands, reassigning them as they move around and providing the information required to connect to the actual backend that will relay their messages.
To use the service, clients must connect to their realm’s Archipelago websocket endpoint and authenticate to begin their session. They can then start sending positional updates and receiving island assignments (see the client life-cycle ).
All messages exchanged with the Archipelago service are encoded using protocol buffers, as defined in the Decentraland protocol repository .
Connecting #
To begin, clients must open a secure websocket connection (wss:
) to the /archipelago/ws
endpoint of the realm.
Once connected, clients have a time window defined by realm policy (60 seconds, by default) to send each message of the authentication flow.
Fixed Adapters
!!
!!While the larger realms run the Archipelago service, smaller ones may choose to provide a fixed backend connection string for all players. The URI, if present, can be found in the comms.fixedAdapter
property of the realm’s /about
.!!
In these cases, dynamic island assignment won’t be available, and the realm’s RPC interface should not be used for that purpose.
Authenticating #
After opening a connection to Archipelago, clients must begin by requesting and signing a challenge from the service to verify their identity.
The first message a client sends is a
ChallengeRequestMessage
with their Ethereum address (i.e. their public key). They will receive a
ChallengeResponseMessage
with a randomly generated string to sign, and must respond with a
SignedChallengeMessage
.
The
SignedChallengeMessage
carries a JSON-serialized
authentication chain
that begins with the provided address, and ends with the challenge signature.
If the signature is successfully verified by the service, the client is authenticated and will receive a
WelcomeMessage
.
Sending Heartbeat #
During their session, clients must periodically send a
Heartbeat
message to keep Archipelago updated with the necessary information to issue island assignments.
If a client stops sending
Heartbeat
messages, Archipelago (depending on its current policy) may close the connection.
Getting Island Assignments #
Shortly after the first heartbeat, Archipelago will send the client their first
IslandChangedMessage
.
The main field is conn_str
, which can be used to initialize a transport and connect to the island. Values typically look like this:
livekit:wss://comms.example.com?access_token=eyJhbGciOiJI...
The label before the first :
is the transport type, the rest is a specialized URI for it. It can include pre-authorized tokens or other parameters.
During the session, Archipelago may send a new assignment at any time, for a number of reasons:
- Position changes: the client reported moving away from others in the island.
- Island requests: the client requested being assigned to a specific island.
- Archipelago policy: the service decided to create or divide islands to better balance the population.
Clients must listen for these assignments, closing and opening transport connections as indicated, and changing the type of transport in use when required.
Client Messages #
ChallengeRequestMessage
↗ source
#
Sent by the client as the first message of a session, to start the authentication flow.
Field | Type | Value |
---|---|---|
address |
string |
The user’s address. |
The address
field must be derived from the first private key of the
authentication chain
that will be presented.
SignedChallengeMessage
↗ source
#
Sent by the client after receiving a
ChallengeResponseMessage
, to complete the authentication flow.
Field | Type | Value |
---|---|---|
auth_chain_json |
string |
A JSON-serialized authentication chain ending with the challenge signature. |
The first key in the
authentication chain
must correspond to the address sent in the original
ChallengeRequestMessage
.
Heartbeat
↗ source
#
Sent by the client at regular intervals (typically once per second), to update Archipelago on their position and/or request an island assignment.
Field | Type | Value |
---|---|---|
position |
Position |
The client’s 3D position in the world map |
desired_room |
string? |
The ID of an island the client would like to be assigned to |
The first Heartbeat
message a client sends is quickly followed by an
IslandChangedMessage
from Archipelago. Subsequent updates, however, are independent of island assignments. Clients should not expect a Heartbeat
to be responded.
When the desired_room
parameter is included, the service will attempt to honor the request, but a reassignment to that island is not guaranteed. It depends on Archipelago’s policy (e.g. limits on island population).
Server Messages #
ChallengeResponseMessage
↗ source
#
Sent by Archipelago in response to a
ChallengeRequestMessage
Field | Type | Value |
---|---|---|
challenge_to_sign |
string |
A generated string to sign and create an authentication chain |
already_connected |
bool |
Whether an existing connection for this user’s key |
WelcomeMessage
↗ source
#
Sent by Archipelago after successful authentication.
Field | Type | Value |
---|---|---|
peer_id |
string |
A unique identifier for the authenticated client (typically their address) |
IslandChangedMessage
↗ source
#
Sent by Archipelago when the client is (re)assigned to an island.
Description.
Field | Type | Value |
---|---|---|
island_id |
string |
The ID of the new island |
from_island_id |
string? |
The ID of the old island, if this is a reassignment |
conn_str |
string |
The connection string for the island transport . |
peers |
map<string, Position> |
Description. |
Clients that receive an IslandChangedMessage
should end their connection to the island backend, and connect to the one given in conn_str
.
The peers
field contains the current identities and positions of all peers in the island, so that clients can populate their initial set. After this point, they should rely on messages received via the island
transport
to get positional updates.
KickedMessage
↗ source
#
Sent by Archipelago before closing a connection.
Field | Type | Value |
---|---|---|
reason |
KickedReason |
Archipelago’s reason for closing the connection |
The standard values for the reason
field are:
KR_NEW_SESSION
: another connection authenticated with the same key.
JoinIslandMessage
↗ source
#
Sent by Archipelago when a peer is assigned to the client’s island.
Field | Type | Value |
---|---|---|
island_id |
string |
The identifier for the island |
peer_id |
string |
The unique identifier for the peer (typically their address) |
The island_id
field will match the client’s current assignment.
LeftIslandMessage
↗ source
#
Sent by Archipelago when a peer is removed from the client’s island.
Field | Type | Value |
---|---|---|
island_id |
string |
The identifier for the island |
peer_id |
string |
The unique identifier for the peer (typically their address) |
The island_id
field will match the client’s current assignment.