> 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/programacion/player-model.md).

# Añadiendo lógica del jugador

En All Out, el jugador es un objeto de jugabilidad de primera clase. Tu `Player :: clase : Player_Base` es donde pones **el estado por jugador** (salud, equipamientos, tiempos de reutilización, alternadores de la interfaz, progresión, etc).

{% hint style="warning" %}
Asume que hay varios jugadores conectados. Evita el estado global que se rompería cuando haya más de un jugador.
{% endhint %}

## Estado por jugador

Almacena el estado de jugabilidad en el jugador o en objetos propiedad del jugador.

```go
Player :: class : Player_Base {
    health: int;
    inventory_open: bool;
}
```

## Servidor + cliente: ¿qué se ejecuta dónde?

All Out sincroniza automáticamente el estado de jugabilidad del servidor a los clientes. Los métodos de jugabilidad se ejecutan tanto en el cliente que predice como en el servidor, así que no los protejas con `Game.is_server()`.

Dos comprobaciones comunes:

* `is_local_or_server()`: toda la interfaz del jugador y la entrada que produce
* `is_local()`: solo anulaciones visuales específicas del jugador

```go
Player :: class : Player_Base {
    ao_late_update :: method(dt: float) {
        if is_local_or_server() {
            // Dibuja toda la interfaz del jugador y maneja su entrada aquí.
        }

        if is_local() {
            // Aplica aquí la visibilidad específica del jugador, pero no cambies campos.
        }
    }
}
```

{% hint style="info" %}
Dibuja toda la UI del jugador desde `Player.ao_late_update` bajo `is_local_or_server()`. Los campos cambiados solo dentro de `is_local()` se reemplazan durante la reconciliación.
{% endhint %}

## Identidad del jugador y datos del perfil

`Player_Base` expone campos de identidad que usarás a menudo:

* `p.get_username() -> string`
* `p.get_user_id() -> string`
* `p.avatar_color`
* `p.device_kind` (`.PHONE`, `.TABLET`, `.PC`)
* `p.is_admin()`, `p.is_vip()`, `p.is_moderator()`, `p.is_youtuber()`
* `p.is_chat_open()` y ayudantes de rectángulos de la interfaz como `p.get_chat_rect()`

```go
Player :: class : Player_Base {
    ao_start :: method() {
        log_info("jugador se unió: % (%)", {this.get_username(), this.get_user_id()});
    }
}
```

## Persistencia: dónde almacenar el progreso del jugador

* **Economy**: monedas (coins/gems/xp) con persistencia automática + edición en el portal del creador\nVer [Economy](/all-out-docs/docs-es/datos-y-persistencia/economy.md).
* **Guardado**: persistencia general de pares clave/valor (configuración, estado de misiones, listas de desbloqueo, etc)\nVer [Sistema de guardado](/all-out-docs/docs-es/datos-y-persistencia/save.md).
* **Inventory**: pilas/instancias de objetos en el inventario de un jugador (opcionalmente guardadas automáticamente)\nVer [Inventory](/all-out-docs/docs-es/conceptos-basicos-del-motor/inventory.md).

## Patrón común: cargar los valores guardados en `ao_start`

```go
Player :: class : Player_Base {
    xp: s64;
    selected_skin: string;

    ao_start :: method() {
        xp = Save.get_int(this, "xp", 0);
        selected_skin = Save.get_string(this, "selected_skin", "default");
    }
}
```

## Buenas prácticas

* **Mantén el estado por jugador en `Player`.** Evita las variables globales para cualquier cosa específica del jugador.
* **Ejecuta la jugabilidad en la ruta predicha compartida.** Dibuja la interfaz del jugador en `is_local_or_server()` y reserva `is_local()` para anulaciones visuales específicas del jugador.
* **Prefiere las API de persistencia integradas** en lugar de crear las tuyas propias (Economy/Save/Inventory).

## Referencia de Player\_Base

Ver `api_references/core/ao/core.csl_engine` en la carpeta del proyecto para la `Player_Base` API completa.
