> 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/datos-y-persistencia/ao-serialize.md).

# @ao\_serialize

`@ao_serialize` es la anotación que colocas en los campos de struct/class para incluirlos en el sistema de serialización del motor. Añadirla te permite editar los campos del script en el editor para una personalización sencilla y también es necesaria si piensas usar serializaciones JSON/datos de guardado para structs.

```go
Enemy :: class : Component {
    // Guardado, mostrado en el inspector, incluido en los datos de la escena
    max_health: int @ao_serialize;
    patrol_radius: float @ao_serialize;

    // Solo en tiempo de ejecución — no se guarda, no aparece en el inspector
    current_target: v2;
    aggro_timer: float;
}
```

## Qué hace

Cuando marcas un campo con `@ao_serialize`, el motor hará lo siguiente:

1. **Mostrarlo en el inspector** para que puedas editarlo en las entidades en el editor.
2. **Incluirlo en la serialización JSON** (`Save.set_json` / `Save.try_get_json`).

Los campos sin `@ao_serialize` existen solo en memoria en tiempo de ejecución. Comienzan con su inicializador normal cada vez que se crea el componente, pero no se incluyen en la serialización de la escena ni en JSON.

## Tipos compatibles

`@ao_serialize` funciona con todos los tipos CSL comunes:

| Tipo                  | Ejemplo                                                                |
| --------------------- | ---------------------------------------------------------------------- |
| Enteros               | `s8`, `s16`, `s32`, `s64` / `int`                                      |
| Sin signo             | `u8`, `u16`, `u32`, `u64` / `uint`                                     |
| Flotantes             | `f32` / `float`, `f64`                                                 |
| Booleanos             | `bool`                                                                 |
| Cadenas               | `string`                                                               |
| Vectores              | `v2`, `v3`, `v4`                                                       |
| Enumeraciones         | Cualquier enum definido por el usuario                                 |
| Arreglos fijos        | `[N]T`                                                                 |
| Arreglos dinámicos    | `[..]T`                                                                |
| Structs / clases      | Tipos anidados (sus `@ao_serialize` campos se incluyen recursivamente) |
| Referencias del motor | Entidades, componentes y activos cuando se admite                      |

{% hint style="info" %}
Para structs/clases anidados, solo se serializan los campos marcados `@ao_serialize` dentro del tipo anidado. La anotación no se propaga: debes marcar cada campo individualmente.
{% endhint %}

## Uso con componentes

El uso más común es en los campos de componentes. Estos se vuelven editables en el inspector del editor y se guardan como parte de la escena.

```go
Chest :: class : Component {
    capacity: int @ao_serialize;
    loot_table: string @ao_serialize;
    is_locked: bool @ao_serialize;

    // Estado de tiempo de ejecución — no hace falta serializar
    has_been_opened: bool;
}
```

Puedes establecer `capacity`, `loot_table`, y `is_locked` por entidad en el editor. Cuando se carga la escena, esos valores se restauran automáticamente.

## Uso con el sistema de guardado

`@ao_serialize` también controla qué campos se incluyen cuando usas las API de guardado JSON. Solo los campos marcados se escriben en JSON.

```go
Player_Progress :: class {
    version: s64 = 1 @ao_serialize;
    xp: s64 @ao_serialize;
    level: s64 = 1 @ao_serialize;
    unlocked_skins: [..]string @ao_serialize;
}

// Guardar
Save.set_json(player, "progress", ref progress);

// Cargar
progress := new(Player_Progress);
if !Save.try_get_json(player, "progress", ref progress) {
    // Nuevo jugador — los valores predeterminados de la clase ya están inicializados.
}
```

Para obtener todos los detalles sobre el sistema de guardado, consulta [Sistema de guardado](/all-out-docs/docs-es/datos-y-persistencia/save.md) y [Serialización JSON](/all-out-docs/docs-es/datos-y-persistencia/json.md).

## Uso con JSON independiente

Puedes serializar cualquier tipo anotado hacia/desde una cadena JSON, independientemente del sistema de guardado:

```go
config: My_Config;
config.difficulty = 3;

json_str := JSON.serialize(ref config);
// json_str contiene solo campos @ao_serialize

loaded: My_Config;
JSON.try_deserialize(json_str, ref loaded);
```

## Valores predeterminados y cambios de esquema

Los campos de clase pueden tener valores predeterminados constantes en línea. Coloca `@ao_serialize` después del inicializador:

```go
Player_Progress :: class {
    version: s64 = 2 @ao_serialize;
    max_health: int = 100 @ao_serialize;
    unlocked_skins: [..]string @ao_serialize;
}
```

Cuando falta un campo serializado, la deserialización de la clase conserva el valor predeterminado de ese campo. Los campos desconocidos se ignoran. Los campos de struct no pueden tener valores predeterminados en línea, así que inicializa un struct antes de deserializarlo cuando necesite valores distintos de cero.

La deserialización de arrays de tamaño fijo está limitada por el tamaño del destino. Los elementos JSON extra se ignoran. Si la entrada es más corta, los elementos no tocados conservan sus valores inicializados.

## Qué NO serializar

No todos los campos deben serializarse. Deja `@ao_serialize` sin marcar los campos que sean:

* **Derivados en tiempo de ejecución** (posiciones calculadas cada fotograma, búsquedas en caché)
* **Estado temporal** (temporizadores, contadores de enfriamiento, banderas locales de fotograma)
* **Datos grandes que cambian cada fotograma** (coste innecesario de guardado)

Una buena regla general: si el valor se establece una vez (en el editor o al cargar) y rara vez cambia, sérialo. Si se recalcula cada fotograma, no lo hagas.

Marcar un campo de componente no conserva por sí solo los cambios de tiempo de ejecución entre sesiones. Usa Guardado, Economía o Inventario cuando esa persistencia sea necesaria.

## Patrones comunes

### Enums para selección de modo

```go
AI_Mode :: enum {
    IDLE;
    PATROL;
    CHASE;
}

Guard :: class : Component {
    mode: AI_Mode @ao_serialize;
    patrol_speed: float @ao_serialize;
}
```

### Structs anidados

```go
Spawn_Point :: struct {
    position: v2 @ao_serialize;
    radius: float @ao_serialize;
}

Spawner :: class : Component {
    points: [..]Spawn_Point @ao_serialize;
    spawn_interval: float @ao_serialize;
}
```

### Referencias a activos

Algunos campos hacen referencia a activos del motor (texturas, prefabs, sonidos). Estos se serializan como identificadores de activos y se resuelven automáticamente al cargar. Consulta los componentes integrados (como `Sprite_Renderer`) para ver ejemplos.
