> 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/networking-fundamentals.md).

# Fundamentos de redes

All Out es ante todo multijugador, pero CSL está diseñado para que puedas escribir la jugabilidad casi como si fuera para un jugador.

CSL ejecuta esa jugabilidad en el cliente para una respuesta inmediata y en el servidor para la autoridad. El cliente se reconcilia periódicamente con el estado de la escena autorizado por el servidor. No escribes RPC ni código separado de aparición en red.

## Escribe una sola ruta de jugabilidad

El daño, las recompensas, la aparición, el movimiento, las decisiones aleatorias y las llamadas de sonido deben ejecutarse en la ruta de jugabilidad compartida.

{% hint style="warning" %}
No protejas la jugabilidad con `Game.is_server()`. Desactiva la predicción y puede hacer que el estado del cliente y del servidor diverja.
{% endhint %}

Mantén el estado por jugador en `Player` o en otro objeto propiedad de ese jugador. Usa el estado de toda la escena solo cuando sea realmente compartido.

## Comprobaciones de ejecución del jugador

`Player_Base` tiene dos comprobaciones de ejecución:

| Comprobación           | Usa                                                                                            |
| ---------------------- | ---------------------------------------------------------------------------------------------- |
| `is_local_or_server()` | La interfaz de usuario del jugador y la entrada que produce. Úsala desde la `ao_late_update`.  |
| `is_local()`           | Anulaciones visuales específicas del jugador, como ocultar un objeto solo para su propietario. |

Toda la IU del jugador, incluida la IU cosmética, va bajo `is_local_or_server()`. Nunca almacenes el estado de la jugabilidad o de la IU solo bajo `is_local()`; la siguiente sincronización del servidor lo reemplaza.

```go
Player :: class : Player_Base {
    inventory_open: bool;

    ao_late_update :: method(dt: float) {
        if is_local_or_server() {
            rect := UI.get_safe_screen_rect()
                .top_right_rect()
                .grow(35, 90, 35, 90)
                .offset(-100, -45);
            bs := UI.default_button_settings();
            ts := UI.default_text_settings();

            if UI.button(rect, bs, ts, "Items").clicked {
                inventory_open = !inventory_open;
            }
        }

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

Si una anulación visual local cambia por la reconciliación, recálculala a partir del estado sincronizado en `ao_on_state_sync()` o aplícala en cada fotograma.

## Sonido

Llama a `SFX.play` desde la misma ruta de jugabilidad compartida que el evento. El motor deduplica la reproducción predicha cuando llega el resultado del servidor. Para reproducir un sonido para un solo jugador, establece `SFX_Desc.specific_to_player`; no encierres la llamada en `is_local()`.

## Evita cambios de estado en cada fotograma

Cada campo de jugabilidad que cambia puede contribuir a una diferencia de estado de red. No almacenes una cuenta regresiva restando `dt` de ella en cada fotograma cuando el mismo estado puede representarse mediante una hora fija.

Almacena una vez el tiempo de transición y deriva la duración restante:

```go
Round_Timer :: class : Component {
    round_ends_at: float;

    begin_round :: method(duration: float) {
        round_ends_at = get_time() + duration;
    }

    remaining :: method() -> float {
        return max(0.0, round_ends_at - get_time());
    }

    ao_update :: method(dt: float) {
        if round_ends_at != 0.0 && get_time() >= round_ends_at {
            round_ends_at = 0.0;
            finish_round();
        }
    }
}
```

Esto sincroniza la fecha límite cuando cambia en lugar de sincronizar un nuevo valor de temporizador en cada fotograma. El mismo patrón funciona para tiempos de reutilización, efectos temporales y cambios de estado programados.

## Diagnóstico de desajustes

Busca:

* Jugabilidad oculta detrás de `is_local()` o `Game.is_server()`.
* Valores por jugador almacenados en globales.
* Datos solo locales usados para sembrar la aleatoriedad de la jugabilidad.
* Estado cambiado en cada fotograma cuando una marca de tiempo fija podría representarlo.

## Documentos relacionados

* [Añadir lógica de jugador](/all-out-docs/docs-es/programacion/player-model.md)
* [Ciclo de vida del juego/fotograma](/all-out-docs/docs-es/programacion/game-frame-lifecycle.md)
