> 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/types-and-structures.md).

# Conceptos básicos del lenguaje

Esta página es el lado de “modelado de datos” de CSL: primitivas, structs/clases y los patrones que usarás para representar el estado del juego de forma limpia.

{% hint style="info" %}
Si eres nuevo, empieza con [Primeros pasos con CSL](/all-out-docs/docs-es/programacion/syntax.md). Esta página asume que ya sabes declarar variables y escribir `proc`/`método`.
{% endhint %}

## Tipos primitivos

### Números y booleanos

* Enteros con signo: `s8`, `s16`, `s32`, `s64` (alias: `int` == `s64`)
* Enteros sin signo: `u8`, `u16`, `u32`, `u64` (alias: `uint` == `u64`)
* Flotantes: `f32` (alias: `float`), `f64`
* Booleanos: `bool`

```go
health: int = 100;
speed: float = 6.5;
is_dead: bool = false;
```

CSL amplía los números cuando es seguro: los enteros con signo más pequeños pueden convertirse en enteros con signo más amplios, los enteros sin signo más pequeños pueden convertirse en enteros sin signo más amplios, los enteros sin signo pueden convertirse en enteros con signo más amplios cuando el destino puede contener todo el rango, y `f32` pueden convertirse en `f64`.

### Cadenas

`string` se usa constantemente para IDs, nombres y formato.

```go
item_id := "sword";
log_info("picked up %", {item_id});
```

### Vectores

`v2`, `v3`, `v4` son tipos matemáticos/de datos integrados:

```go
pos: v2 = {10, 20};
color: v4 = {1, 0, 0, 1};
```

## Enumeraciones

Las enumeraciones son geniales para campos legibles de “modo/estado”:

```go
Game_Phase :: enum {
    LOBBY;
    RUNNING;
    POST_GAME;
}

phase := Game_Phase.LOBBY;

if phase == .RUNNING {
    // ...
}
```

{% hint style="info" %}
Los valores de las enumeraciones suelen referenciarse con la abreviatura `.VALUE` cuando el compilador puede inferir el tipo de enumeración.
{% endhint %}

## Structs (tipos por valor)

Usa structs para “datos simples” que quieras copiar fácilmente (configuración, pequeños blobs de estado, descriptores).

```go
Damage_Desc :: struct {
    amount: int;
    knockback: v2;
}

hit := Damage_Desc{amount=10, knockback={2, 1}};
```

Los structs pueden heredar de otros structs. Los literales compuestos incluyen primero los campos heredados:

```go
Base_Stats :: struct {
    health: int;
}

Enemy_Stats :: struct : Base_Stats {
    speed: float;
}

stats: Enemy_Stats = {100, 4.5};
```

### Cuándo usar un struct

* Un objeto descriptor/configuración (`*_Desc`)
* Estado pequeño e independiente que quieres copiar por valor
* Datos que quieres incrustar dentro de otro tipo

### Cuándo no usar un struct

* Estado mutable grande compartido entre varios sistemas (usa una clase)
* Objetos de “identidad” (jugadores, objetos, objetos de larga duración) (usa una clase)

## Clases (tipos por referencia)

Las clases son tipos por referencia. Crea instancias con `new(...)`.

```go
Enemy :: class {
    health: int = 50;
    target: v2 = {0, 0};
}

e := new(Enemy);
```

### Herencia

Puedes heredar de otros structs/clases:

```go
Weapon_Definition :: class {
    id: string;
    name: string;
}

Gun_Definition :: class : Weapon_Definition {
    fire_rate: float;
}
```

Las clases derivadas heredan los valores predeterminados de los campos. Pueden sobrescribir los valores predeterminados heredados con `field = value` en el cuerpo de la clase:

```go
Weapon_Definition :: class {
    damage: int = 10;
}

Rocket_Definition :: class : Weapon_Definition {
    damage = 100;
    splash_radius: float = 3.0;
}
```

{% hint style="warning" %}
Usa la herencia cuando exista una relación real de “es-un”. Para la mayoría de los datos de jugabilidad, la composición (campos) es más simple y más fácil de mantener.
{% endhint %}

## Arreglos, slices y arreglos dinámicos

Verás tres formas comunes:

* **Arreglos fijos**: `[N]T` (tamaño en tiempo de compilación)
* **Slices / arreglos administrados**: `[]T` (una vista de un arreglo)
* **Arreglos dinámicos**: `[..]T` (lista redimensionable)

Ejemplo:

```go
spawn_points: [4]v2 = {{0,0}, {5,0}, {0,5}, {5,5}};

alive_enemy_ids: [..]int;
alive_enemy_ids.append(123);
alive_enemy_ids.append(456);
```

Para una guía completa, consulta [Arreglos y colecciones](/all-out-docs/docs-es/programacion/arrays-and-collections.md).

## Paso por referencia (`ref`)

Si un procedimiento necesita modificar un valor, usa `ref`:

```go
apply_damage :: proc(health: ref int, amount: int) {
    health -= amount;
}

hp := 100;
apply_damage(ref hp, 10);
```

Esto es especialmente útil para APIs de estilo “layout” que recortan/reducen progresivamente un rect:

```go
draw_panel :: proc(rect: ref Rect) {
    header := rect.cut_top(50);
    draw_header(header);
    // rect is now the remaining area for content
}
```

## Conversión de tipos

Usa `expr.(T)` o `cast(T)expr`:

```go
f := 12.7;
i := f.(int);       // 12
f2 := cast(float)i; // 12.0
```

Cuando el tipo de destino ya se conoce, `expr.()` y `cast expr` infieren el tipo de destino.

## Polimorfismo de tipos (procs de estilo genérico)

CSL admite procedimientos polimórficos usando `$` para deducir tipos en el sitio de llamada:

```go
min :: proc(a: $T, b: T) -> T {
    if a < b return a;
    return b;
}

a := min(10, 20);       // T == int
b := min(1.25, 3.5);    // T == float
```

## Tipos como valores (`typeid`)

`typeid` es un valor que representa un tipo en tiempo de ejecución y/o para llamadas polimórficas:

```go
default_of :: proc($T: typeid) -> T {
    t: T;
    return t;
}

zero := default_of(int);
empty := default_of(string);
```

`value.#type` devuelve el tipo en tiempo de ejecución de un valor de clase. Úsalo antes de hacer downcasting desde una clase base cuando el tipo derivado exacto importe.

## Directrices prácticas de modelado

* **El estado por jugador vive en `Player`.** Si debe diferir entre jugadores, no debería ser global.
* **Prefiere structs pequeños para descriptores** y almacena el estado en tiempo de ejecución en clases/componentes.
* **Ejecuta la jugabilidad en la ruta predicha compartida.** No calcules el estado de jugabilidad solo bajo `is_local()` o protégelo con `Game.is_server()`.

Para patrones específicos de jugador, consulta [Añadir lógica de jugador](/all-out-docs/docs-es/programacion/player-model.md). Para la parte ECS del mundo, consulta [Entidades y componentes](/all-out-docs/docs-es/programacion/entities-and-components.md).
