> 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/arrays-and-collections.md).

# Referencia avanzada del lenguaje

CSL te ofrece unas cuantas herramientas “tipo arreglo” que cubren la mayoría de las necesidades de gameplay: arreglos fijos, slices y arreglos dinámicos. Esta página es la guía práctica para usarlos sin dispararte en el pie.

## Glosario rápido

* **Arreglo fijo**: `[N]T` — el tamaño se conoce en tiempo de compilación.
* **Slice / arreglo administrado**: `[]T` — una vista sobre los datos del arreglo (a menudo se usa para parámetros).
* **Arreglo dinámico**: `[..]T` — lista redimensionable con `conteo` y `capacidad`.

```go
fixed: [4]int = {1, 2, 3, 4};
view: []int = fixed; // vista de slice

list: [..]int;
list.append(10);
list.append(20);
```

{% hint style="info" %}
Los métodos de arreglos dinámicos usan llamadas normales con punto (por ejemplo, `list.append(x)`). Los campos también usan acceso con punto (por ejemplo, `list.count`).
{% endhint %}

## Arreglos dinámicos (`[..]T`)

Los arreglos dinámicos son el tipo de “lista por defecto” para el código de gameplay.

### Creación y adición

```go
players_seen: [..]string;
players_seen.append(player.get_user_id());
```

### Reserva de capacidad (rendimiento)

Si sabes que vas a añadir muchos elementos, reserva primero para evitar realocaciones repetidas.

```go
results: [..]Enemy;
results.reserve(128);
```

### Eliminar elementos

Por lo general eliges entre **eliminación rápida** (el orden no importa) y **eliminación ordenada** (conservar el orden).

```go
values: [..]int;
values.append(10);
values.append(20);
values.append(30);

values.unordered_remove_by_value(20); // intercambia con el último, rápido
values.ordered_remove_by_value(10);   // desplaza, mantiene el orden
```

También puedes eliminar por índice:

```go
values.unordered_remove_by_index(0);
values.ordered_remove_by_index(0);
```

### Limpiar

```go
values.clear(); // O(1): solo establece count en 0
```

## Pasar arreglos a procedimientos

Muchas APIs aceptan `[]T` (un slice/vista). Los arreglos dinámicos pueden pasarse donde se espera `[]T` .

```go
sum :: proc(arr: []int) -> int {
    total := 0;
    for v: arr {
        total += v;
    }
    return total;
}

nums: [..]int;
nums.append(1);
nums.append(2);
nums.append(3);

total := sum(nums); // [..]int -> []int implícito
```

## Patrones de iteración

### Iterar elementos

```go
for v: nums {
    log_info("v=%", {v});
}
```

### Iterar índices

Usa `..<` cuando quieres un bucle normal de "0 hasta, pero sin incluir, count":

```go
for i: 0..<inventory.capacity {
    item := inventory.get_item(i);
    if item == null continue;
    // ...
}
```

{% hint style="warning" %}
`..` los rangos son inclusivos. `..<` los rangos excluyen el límite superior.
{% endhint %}

Los bucles inversos usan `#reverse`:

```go
for i: 0..<inventory.capacity #reverse {
    item := inventory.get_item(i);
    if item == null continue;
    // ...
}
```

## Tablas hash

Usa `Hashtable(Key_Type, Value_Type)` cuando necesitas una búsqueda rápida por clave. Admite claves enteras y de cadena, junto con los métodos habituales para búsqueda, inserción, sobrescritura, eliminación e iteración.

```go
scores: Hashtable(string, s64);
scores.add("alice", 10);
scores.add_or_overwrite("bob", 25);

score, ok := scores.find("alice");
if ok {
    log_info("alice score: %", {score});
}

for value, key: scores {
    log_info("% = %", {key, value});
}
```

Usa `add` cuando las claves duplicadas deben provocar una aserción. Usa `add_or_overwrite` cuando se espera actualizar una clave existente. `try_add` devuelve `true` si la clave ya existía y deja el valor anterior sin cambios.

## Clausuras, callbacks y userdata (importante)

CSL **no** sí `tiene clausuras. Las definiciones inline` proc() { ... }

no pueden capturar variables del entorno. Cuando necesites callbacks (manejadores de UI, hooks de muerte, etc.), empareja el callback con un `campo userdata: Object` .

```go
Button_Handler :: class {
    clicks: int;
}

UI_Button :: class {
    on_click_userdata: Object;
    on_click: proc(userdata: Object);
}

setup :: proc(btn: UI_Button, handler: Button_Handler) {
    btn.on_click_userdata = handler;
    btn.on_click = proc(userdata: Object) {
        h := userdata.(Button_Handler);
        h.clicks += 1;
    };
}
```

## Referencia de la API

Cada proyecto incluye una `api_references/` carpeta que contiene la API central actual. Abre el `.csl_engine` archivo correspondiente para inspeccionar un tipo o procedimiento.
