# Mensajes

Los mensajes en comms son datos binarios *paquetes*, serializados usando [protocol buffers](https://github.com/protocolbuffers/protobuf). Transportan chat de texto y voz, actualizaciones posicionales, cambios de perfil y otras interacciones en tiempo real.

{% hint style="info" %}
Puedes ver el protocolo de comms en acción y experimentar con él usando el [Comms Station](https://decentraland.github.io/comms-station/).
{% endhint %}

Todas las definiciones de mensajes están disponibles en el [repositorio del protocolo](https://github.com/decentraland/protocol), y cada tipo de mensaje abajo tiene un enlace a su declaración.

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

El `El` estructura de paquete es el contenedor para todos los mensajes.

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

### Chat de Texto y Voz

Los clientes chatean transmitiendo mensajes de texto y clips de audio a todos los pares conectados (usualmente jugadores en la misma isla).

Solo dos `El` tipos están involucrados, uno para cada caso de uso. En circunstancias típicas, los clientes transmiten estos mensajes a todos los demás clientes en su isla, que es el grupo de jugadores cercanos con los que pueden interactuar.

***

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

Envía un mensaje de chat de texto a otros clientes.

| Campo       | Tipo     | Valor                             |
| ----------- | -------- | --------------------------------- |
| `message`   | `string` | Texto del mensaje                 |
| `timestamp` | `double` | Marca de tiempo UTC del remitente |

***

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

Envía una muestra de voz codificada a otros clientes.

| Campo             | Tipo     | Valor                                                 |
| ----------------- | -------- | ----------------------------------------------------- |
| `encoded_samples` | `bytes`  | Datos de audio codificados                            |
| `codec`           | `enum`   | Solo `VC_OPUS` (no se admiten otros codecs por ahora) |
| `index`           | `uint32` | Un contador incremental establecido por el remitente  |

El `codec` el campo es un `enum` valor. No se admiten codecs personalizados.

### Movimiento

Los clientes que controlan avatares envían y reciben actualizaciones posicionales dentro de su isla, para sincronizar movimiento y postura entre jugadores.

***

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

Actualiza a otros clientes sobre la posición y orientación de un avatar.

| Campo                                                                                                               | Tipo     | Valor                                                |
| ------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------- |
| <p><code>position\_x</code><br><code>position\_y</code><br><code>position\_z</code></p>                             | `float`  | Posición del avatar en el mapa del mundo             |
| <p><code>rotation\_x</code><br><code>rotation\_y</code><br><code>rotation\_z</code><br><code>rotation\_w</code></p> | `float`  | Cuaternión de rotación del avatar                    |
| `index`                                                                                                             | `uint32` | Un contador incremental establecido por el remitente |

Normalmente los clientes envían `position` actualizaciones con baja frecuencia (como una vez cada 1 o 2 segundos), y cambian a alta frecuencia (varias veces por segundo) cuando se mueven o interactúan.

{% hint style="info" %}
Al enviar actualizaciones posicionales, la velocidad suele ser mejor que la fiabilidad. El rendimiento percibido es mejor cuando la entrega es más rápida, incluso si un `position` mensaje se pierde ocasionalmente o llega desordenado. Algunos transportes (por ejemplo, [LiveKit](https://github.com/decentraland/docs/blob/main/contributor/communications/transport-types/livekit/README.md)) pueden cambiar entre modos rápidos y fiables por mensaje.
{% endhint %}

Se recomiendan las transmisiones de baja frecuencia como una solución simple para entregar actualizaciones a clientes que momentáneamente perdieron conectividad o no alcanzaron a recibir un mensaje mientras se unían a la isla.

El `index` el campo es un contador incremental, establecido por el remitente para que los receptores puedan ordenar las actualizaciones que llegan fuera de orden.

### Compartir Perfil

Los clientes dentro de una isla pueden solicitar la información de avatar de otros jugadores, con el fin de renderizar sus avatares, mostrar sus nombres e imágenes, etc.

Como los cambios de perfil son raros (comparados con las actualizaciones posicionales, por ejemplo), el sistema está diseñado para simplificar la tarea de mantener una caché local de perfiles, y solo obtener perfiles cuando sea necesario.

Hay 3 [`El`](#Packet) tipos involucrados: un [`ProfileRequest`](#ProfileRequest)/[`ProfileResponse`](#ProfileResponse) par usado por los clientes para compartir perfiles bajo demanda, y el [`AnnounceProfileVersion`](#AnnounceProfileVersion) mensaje para decir a los pares cuál es la última versión, para que puedan decidir si solicitarla.

Normalmente los clientes transmiten `AnnounceProfileVersion` mensajes periódicamente, además de inmediatamente cuando su perfil cambia.

{% @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`** [**↗ fuente**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc4/comms.proto#L34)

Señala a otros clientes que hay un [entidad de perfil](https://github.com/decentraland/docs/blob/main/contributor/content/entity-types/profiles/README.md) que pueden solicitar.

| Campo             | Tipo     | Valor                                                    |
| ----------------- | -------- | -------------------------------------------------------- |
| `profile_version` | `uint32` | Un número de versión incrementado con cada modificación. |

Los receptores que almacenan en caché perfiles pueden usar el `profile_version` número para decidir si su copia local está actualizada, o si necesitan enviar un [`ProfileRequest`](#ProfileRequest).

***

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

Solicita un perfil de una versión especificada a un par en particular.

| Campo             | Tipo     | Valor                                   |
| ----------------- | -------- | --------------------------------------- |
| `address`         | string   | La dirección identificadora del perfil. |
| `profile_version` | `uint32` | La versión de perfil deseada.           |

Los receptores pueden responder con [`ProfileResponse`](#ProfileResponse) mensajes para proporcionar el perfil solicitado.

***

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

Envía un perfil en respuesta a un [`ProfileRequest`](#ProfileRequest).

| Campo                | Tipo     | Valor                                                                           |
| -------------------- | -------- | ------------------------------------------------------------------------------- |
| `serialized_profile` | string   | Entidad de perfil serializada en JSON.                                          |
| `base_url`           | `uint32` | URL base para un endpoint de sistema de archivos, recomendada por el remitente. |

El `serialized_profile` el campo contiene la serialización JSON de una [entidad de perfil](https://github.com/decentraland/docs/blob/main/contributor/content/entity-types/profiles/README.md).

Si el remitente quiere recomendar un servidor de contenido para descargar entidades referenciadas en su perfil (como wearables), puede establecer el campo `base_url` como una sugerencia. Los clientes son libres de usar o ignorar esta URL.
