> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/all-out-docs/docs-es/conceptos-basicos-del-motor/social-features.md).

# Funciones sociales

### Leyendo el chat

Usa `core_globals.server_on_chat_message_received` cuando el código del juego necesita reaccionar a los mensajes normales del chat en el servidor:

```go
ao_before_scene_load :: proc() {
    core_globals.server_on_chat_message_received = on_chat_message;
}

on_chat_message :: proc(player: Player, message: string) {
    log_info("% said %", {player.get_username(), message});
}
```

### Referencia de la API de chat

```go
Chat :: struct {
    Mode :: enum {
        DEFAULT;
        BUBBLE_ONLY;
    }

    set_mode :: proc(mode: Mode);
    server_send_message :: proc(message: string, player: Player = null);
    is_open :: proc() -> bool;
}
```

`Chat.server_send_message` es para código del lado del servidor, como los controladores de comandos de chat. Pasa `jugador` para dirigirte a un jugador, o déjalo `null` para enviarlo de forma general. Usa `Chat.set_mode(.BUBBLE_ONLY)` en el cliente local para juegos que quieran chat en burbujas sin el panel de chat estándar.

### Comandos de chat

Los comandos de chat son sobre todo una **herramienta para desarrolladores/administradores** para pruebas y operaciones en vivo:

* Iniciar rondas antes de tiempo / saltar oleadas
* Otorgar conjuntos de objetos de prueba o moneda
* Activar eventos del juego para depuración

Para crear un comando, escribe una `proc` y anótalo con `@chat_command`.

Los jugadores pueden escribir comandos en el chat anteponiendo `/`:

* `/start_round`
* `/grant_test_loadout`
* `/trigger_event meteor_shower`

{% hint style="info" %}
Los comandos de chat se ejecutan en el servidor. Usa `Notifier.notify(player, "...")` para enviar retroalimentación de vuelta a un solo jugador.
{% endhint %}

{% hint style="warning" %}
No todos los jugadores tendrán el chat de texto habilitado (el control parental y los silencios de moderación pueden desactivar el cuadro de texto), así que no deberías depender de los comandos de chat para sistemas de juego críticos.
{% endhint %}

#### Comandos comunes de desarrollo/administración

```go
// Iniciar una ronda antes de tiempo (solo administradores)
start_round :: proc(player: Player) {
    g_round_manager.start_round();
    Notifier.notify(player, "La ronda ha comenzado.");
} @chat_command

// Date un equipamiento de prueba (solo administradores)
grant_test_loadout :: proc(player: Player) {
    // Ejemplo: usa aquí tu propia lógica para otorgar objetos
    // item := Items.create_item_instance(sword_defn);
    // Items.move_item_to_inventory(item, player.default_inventory);
    Notifier.notify(player, "Se ha otorgado el equipamiento de prueba.");
} @chat_command

// Activar un evento por nombre (solo administradores, con un argumento opcional)
trigger_event :: proc(player: Player, event_name: string = "meteor_shower") {
    g_event_system.trigger(event_name);
    Notifier.notify(player, "Evento activado: %", {event_name});
} @chat_command
```

#### Permisos

Usa anotaciones de permisos para controlar quién puede ejecutar un comando:

| Anotación          | Quién puede usarlo                                |
| ------------------ | ------------------------------------------------- |
| `@any`             | Todos los jugadores                               |
| `@vip`             | Jugadores VIP y administradores                   |
| `@youtuber`        | Jugadores youtuber y administradores              |
| `@owner`           | Propietario del juego y administradores           |
| `@owner_or_editor` | Propietario del juego, editores y administradores |
| (ninguna)          | Solo administradores                              |

```go
// Los VIP y los administradores pueden usar esto
skip_wave :: proc(player: Player) {
    g_wave_manager.skip_to_next_wave();
    Notifier.notify(player, "Oleada omitida.");
} @chat_command @vip
```

{% hint style="info" %}
Al iniciar desde el editor, se permiten comandos de chat para iterar/probar más rápido.
{% endhint %}

#### Argumentos y parámetros opcionales

El primer parámetro siempre debe ser `Player`. Después de eso, puedes añadir argumentos (y asignarles valores predeterminados para hacerlos opcionales).

Por defecto, los comandos son **solo para administradores**.

Los tipos de argumento compatibles son `string`, tipos enteros, tipos de punto flotante, `bool`, y `Player`.

```go
// Solo administradores (predeterminado)
give_currency :: proc(player: Player, amount: s64 = 100) {
    if amount < 0 {
        Notifier.notify(player, "La cantidad debe ser cero o mayor.");
        return;
    }

    Economy.deposit_currency(player, "Coins", amount);
    Notifier.notify(player, "Te di % monedas.", {amount});
} @chat_command
```

Los administradores pueden ejecutar:

* `/give_currency` → da 100 monedas
* `/give_currency 500` → da 500 monedas

#### Cadenas con espacios

Encierra las cadenas entre comillas si contienen espacios:

```go
say :: proc(player: Player, message: string) {
    // Tu propia función de difusión/mensaje del juego aquí
    log_info("% says: %", {player.get_username(), message});
} @chat_command @any
```

Ejemplo:

```
/say "¡Hola a todos!"
```

#### Obtener el uso del comando

Los jugadores pueden añadir `?` a un comando para ver la información de los parámetros:

```
/spawn_enemy?
```

### Activación del chat de voz

Los jugadores controlan el chat de voz mediante la configuración de su cuenta y dispositivo. Los juegos no pueden activarlo por la fuerza ni eludir el permiso del micrófono, el control parental ni las restricciones de moderación.

La voz es posicional. El rango audible predeterminado es de 10 unidades del mundo:

```go
Voice :: struct {
    set_range :: proc(range: float);
    get_range :: proc() -> float;
}
```

Establece un rango positivo al iniciar la escena:

```go
ao_start :: proc() {
    Voice.set_range(14);
}
```

`Voice.set_range` cambia el rango de toda la escena. Los valores no positivos se ignoran.

### Canales de comunicación

Cada jugador tiene máscaras de habla y escucha que se aplican tanto al chat de voz como al de texto. Dos jugadores pueden comunicarse cuando la máscara de habla del emisor se solapa con la máscara de escucha del receptor.

```go
TEAM_RED  :: 1.(u64) << 0;
TEAM_BLUE :: 1.(u64) << 1;

put_on_red_team :: proc(player: Player) {
    player.comms_channel_speak_mask = TEAM_RED;
    player.comms_channel_listen_mask = TEAM_RED;
}
```

Los jugadores escuchan y hablan en todos los canales de forma predeterminada.

### Moderación

All Out supervisa automáticamente el chat de texto y de voz para detectar comportamientos que violen nuestras [directrices de la comunidad](https://help.allout.game/hc/en-us/articles/27854798873243-Code-Of-Conduct) y desactivará las funciones sociales para las primeras infracciones o aplicará suspensiones a los reincidentes.

Si ves conductas inapropiadas repetidas o conductas que se cuelan por nuestra detección automática, informa al jugador usando el sistema de denuncias del juego o desde su perfil.

Si un jugador ha sido suspendido por error, indícale que vaya a [contáctanos](https://help.allout.game/) para revertir la acción.
