> 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

Selecciona campos para la escena, el Inspector y la serialización JSON.

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

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

    // 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 `campos @ao_serialize`, el motor:

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 `campos @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 escena ni en la serialización JSON.

## Tipos compatibles

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

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

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

## Uso con componentes

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

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

    // Estado 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

`campos @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 {
    @ao_serialize version: s64 = 1;
    @ao_serialize xp: s64;
    @ao_serialize level: s64 = 1;
    @ao_serialize unlocked_skins: [..]string;
}

// 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 ver todos los detalles del 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 desde/hacia 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 `campos @ao_serialize` antes de la declaración del campo:

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

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 de destino. Los elementos JSON adicionales 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 `campos @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 del fotograma)
* **Datos grandes que cambian cada fotograma** (sobrecarga innecesaria 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 por sí solo no conserva los cambios en tiempo de ejecución entre sesiones. Usa Save, Economy o Inventory cuando esa persistencia sea necesaria.

## Patrones comunes

### Enums para selección de modo

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

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

### Structs anidados

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

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

### Referencias a recursos

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