# Mensagens

Mensagens em comms são dados binários *pacotes*, serializados usando [protocol buffers](https://github.com/protocolbuffers/protobuf). Eles transportam chat de texto e voz, atualizações posicionais, alterações de perfil e outras interações em tempo real.

{% hint style="info" %}
Você pode ver o protocolo de comms em ação e experimentá-lo usando o código aberto [Comms Station](https://decentraland.github.io/comms-station/).
{% endhint %}

Todas as definições de mensagem estão disponíveis em [repositório do protocolo](https://github.com/decentraland/protocol), e cada tipo de mensagem abaixo tem um link para sua declaração.

**`Pacote`** [**↗ source**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc4/comms.proto#L8)

O `Pacote` estrutura é o contêiner para todas as mensagens.

| Campo     | Tipo   | Valor                                                                                                                                                                                                |
| --------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message` | `enum` | <p>Um de <code>Chat</code>, <code>Voice</code>, <code>position</code>, <code>AnnounceProfileVersion</code>,<br><code>ProfileRequest</code>, <code>ProfileResponse</code>, ou <code>Scene</code>.</p> |

### Chat de Texto e Voz

Os clientes conversam transmitindo mensagens de texto e clipes de áudio para todos os pares conectados (normalmente jogadores na mesma ilha).

Apenas dois `Pacote` tipos estão envolvidos, um para cada caso de uso. Em circunstâncias típicas, os clientes transmitem essas mensagens para todos os outros clientes na sua ilha, que é o grupo de jogadores próximos com os quais podem interagir.

***

**`Chat`** [**↗ source**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc4/comms.proto#L56)

Envia uma mensagem de chat de texto para outros clientes.

| Campo       | Tipo     | Valor                      |
| ----------- | -------- | -------------------------- |
| `message`   | `string` | Texto da mensagem          |
| `timestamp` | `double` | Timestamp UTC do remetente |

***

**`Voice`** [**↗ source**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc4/comms.proto#L66)

Envia uma amostra de voz codificada para outros clientes.

| Campo             | Tipo     | Valor                                                          |
| ----------------- | -------- | -------------------------------------------------------------- |
| `encoded_samples` | `bytes`  | Dados de áudio codificados                                     |
| `codec`           | `enum`   | Apenas `VC_OPUS` (nenhum outro codec é suportado por enquanto) |
| `index`           | `uint32` | Um contador incremental definido pelo remetente                |

O `codec` campo é um `enum` valor. Codecs personalizados não são suportados.

### Movimento

Clientes que controlam avatares enviam e recebem atualizações posicionais dentro da sua ilha, para sincronizar movimento e postura entre os jogadores.

***

**`position`** [**↗ source**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc4/comms.proto#L20)

Atualiza outros clientes sobre a posição e orientação de um avatar.

| Campo                                                                                                               | Tipo     | Valor                                           |
| ------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------- |
| <p><code>position\_x</code><br><code>position\_y</code><br><code>position\_z</code></p>                             | `float`  | Posição do avatar no mapa mundial               |
| <p><code>rotation\_x</code><br><code>rotation\_y</code><br><code>rotation\_z</code><br><code>rotation\_w</code></p> | `float`  | Quaternion de rotação do avatar                 |
| `index`                                                                                                             | `uint32` | Um contador incremental definido pelo remetente |

Os clientes normalmente enviam `position` atualizações com baixa frequência (como uma vez a cada 1 ou 2 segundos), e mudam para alta frequência (várias vezes por segundo) quando se movem ou interagem.

{% hint style="info" %}
Ao enviar atualizações posicionais, velocidade geralmente é mais importante que confiabilidade. A experiência percebida é melhor quando a entrega é mais rápida, mesmo se uma `position` mensagem ocasionalmente for perdida ou reordenada. Alguns transportes (por exemplo [LiveKit](https://github.com/decentraland/docs/blob/main/contributor/communications/transport-types/livekit/README.md)) podem alternar entre modos rápido e confiável por mensagem.
{% endhint %}

As transmissões de baixa frequência são recomendadas como uma solução simples para entregar atualizações a clientes que momentaneamente perderam conectividade ou não conseguiram captar uma mensagem enquanto entravam na ilha.

O `index` campo é um contador incremental, definido pelo remetente para que os receptores possam ordenar atualizações que chegam fora de ordem.

### Compartilhamento de Perfil

Clientes dentro de uma ilha podem solicitar as informações de avatar de outros jogadores, a fim de renderizar seus avatares, exibir seus nomes e imagens, etc.

Como alterações de perfil são raras (comparadas com atualizações posicionais, por exemplo), o sistema é projetado para simplificar a tarefa de manter um cache local de perfis, e somente buscar perfis quando necessário.

Há 3 [`Pacote`](#Packet) tipos envolvidos: um [`ProfileRequest`](#ProfileRequest)/[`ProfileResponse`](#ProfileResponse) par usado pelos clientes para compartilhar perfis sob demanda, e a [`AnnounceProfileVersion`](#AnnounceProfileVersion) mensagem para informar aos pares qual é a versão mais recente, para que possam decidir se devem solicitá-la.

Os clientes normalmente transmitem `AnnounceProfileVersion` mensagens periodicamente, além de imediatamente quando seu perfil muda.

{% @mermaid/diagram content="sequenceDiagram
participant Client1 as Client 1
participant Client2 as Client 2
participant Client3 as Client 3

```
Note over Client1: Broadcast profile version
Client1->>Client1: AnnounceProfileVersion(v1)
Client1->>Client1: AnnounceProfileVersion(v1)

Note over Client3: Request profile
Client3->>Client1: ProfileRequest(@client 1)
Client1->>Client3: ProfileResponse(v1)

Client1->>Client1: AnnounceProfileVersion(v1)

Note over Client1: Profile updated
Client1->>Client1: AnnounceProfileVersion(v2)

Note over Client2,Client3: Multiple clients request
Client2->>Client1: ProfileRequest(@client 1)
Client3->>Client1: ProfileRequest(@client 1)
Client1->>Client2: ProfileResponse(v2)
Client1->>Client3: ProfileResponse(v2)" %}
```

***

**`AnnounceProfileVersion`** [**↗ source**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc4/comms.proto#L34)

Sinaliza outros clientes que há um [entidade de perfil](https://github.com/decentraland/docs/blob/main/contributor/content/entity-types/profiles/README.md) que eles podem solicitar.

| Campo             | Tipo     | Valor                                                |
| ----------------- | -------- | ---------------------------------------------------- |
| `profile_version` | `uint32` | Um número de versão incrementado a cada modificação. |

Receptores que fazem cache de perfis podem usar o número `profile_version` para decidir se sua cópia local está atualizada, ou se precisam enviar um [`ProfileRequest`](#ProfileRequest).

***

**`ProfileRequest`** [**↗ source**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc4/comms.proto#L41)

Solicita um perfil de uma versão especificada de um par em particular.

| Campo             | Tipo     | Valor                               |
| ----------------- | -------- | ----------------------------------- |
| `address`         | string   | O endereço identificador do perfil. |
| `profile_version` | `uint32` | A versão do perfil desejada.        |

Receptores podem responder com [`ProfileResponse`](#ProfileResponse) mensagens para fornecer o perfil solicitado.

***

**`ProfileResponse`** [**↗ source**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc4/comms.proto#L46)

Envia um perfil em resposta a um [`ProfileRequest`](#ProfileRequest).

| Campo                | Tipo     | Valor                                                                         |
| -------------------- | -------- | ----------------------------------------------------------------------------- |
| `serialized_profile` | string   | Entidade de perfil serializada em JSON.                                       |
| `base_url`           | `uint32` | URL base para um endpoint de sistema de arquivos, recomendado pelo remetente. |

O `serialized_profile` campo contém a serialização JSON de uma [entidade de perfil](https://github.com/decentraland/docs/blob/main/contributor/content/entity-types/profiles/README.md).

Se o remetente quiser recomendar um servidor de conteúdo para baixar entidades referenciadas em seu perfil (como wearables), ele pode definir o campo `base_url` como uma sugestão. Os clientes são livres para usar ou ignorar essa URL.
