For the complete documentation index, see llms.txt. This page is also available as Markdown.

Sistema de guardado

El sistema de guardado ofrece un sistema de almacenamiento de datos clave-valor para conservar el progreso y las preferencias del jugador entre sesiones.

El sistema de guardado es un simple almacén de pares clave-valor. Le das una clave de cadena (como "xp"), y almacena un valor que seguirá ahí la próxima vez que el jugador se conecte.

Hay dos tipos de datos de guardado:

  • Guardado del jugador: datos personales de un jugador (XP, mejoras, ajustes, inventario, etc.)

  • Guardado global del juego: compartido por todos en el juego (récords del mundo, ajustes del servidor, contadores globales, etc.)

Inicio rápido (guardar + cargar una estadística)

El patrón más común es:

  • Carga los valores guardados en ao_start

  • Guarda de nuevo cada vez que cambie el valor

Player :: class : Player_Base {
    xp: s64;
    level: s64;

    ao_start :: method() {
        // Los valores predeterminados se usan para jugadores nuevos
        xp    = Save.get_int(this, "xp", 0);
        level = Save.get_int(this, "level", 1);
    }
}

add_xp :: proc(player: Player, amount: s64) {
    player.xp += amount;

    // ... tu lógica de subida de nivel aquí ...

    // Guarda inmediatamente cuando cambie
    Save.set_int(player, "xp", player.xp);
    Save.set_int(player, "level", player.level);
}

Guardado del jugador (datos por jugador)

El guardado del jugador está limitado a un solo jugador. Cada jugador tiene sus propios datos aislados de clave/valor.

Tipos compatibles:

  • Cadena: Save.set_string / Save.get_string

  • Entero (s64): Save.set_int / Save.get_int (nota: actualmente los valores se truncan internamente a 32 bits)

  • Flotante (f64): Save.set_f64 / Save.get_f64

  • JSON (avanzado): Save.set_json / Save.try_get_json

Proporciona siempre un valor predeterminado sensato al leer. Los jugadores nuevos aún no tendrán claves, y get_* devolverá tu valor predeterminado.

Guardar datos “más grandes” (JSON)

Si tienes un pequeño conjunto de campos (como progreso + elementos desbloqueados), a menudo es mejor guardarlo como un único bloque JSON.

Solo los campos marcados con @ao_serialize se guardan.

Save.try_get_json devuelve false si la clave no existe o la cadena JSON está mal formada. Asigna memoria para los datos de la clase antes de cargar, porque la ruta falsa no la asigna. Los campos faltantes conservan los valores predeterminados de su clase, y los campos desconocidos se ignoran.

Versionado del guardado (migrar datos antiguos de forma segura)

Si alguna vez cambias el formato de guardado, conserva una versión clave y migra los guardados antiguos hacia adelante.

Guardado global del juego (compartido por todos)

El guardado global del juego se comparte en todo el juego, no por jugador.

Usa Save.increment_game_int para contadores que varios jugadores podrían actualizar al mismo tiempo (bajas, uniones, rondas jugadas, etc.). Su optimistic_update parámetro tiene el valor predeterminado de true, así que el valor local en caché cambia inmediatamente.

Patrones comunes

Booleanos

Guarda los booleanos como 0/1:

Nomenclatura de claves

Las claves son solo cadenas, así que elige nombres que no entren en conflicto más adelante:

  • "xp", "level", "selected_skin"

  • "tycoon.cash", "tycoon.upgrades.mouth_level"

Si tienes varios juegos conectados mediante game parenting (hub + minijuegos), consulta Productos/datos entre juegos para ver cómo se pueden compartir los datos guardados.

APIs adicionales

ordered_get y ordered_get_all son asíncronos y se ejecutan en el servidor. Llámalos desde la ruta normal compartida del juego; no añadas una Game.is_server() protección.

Los arreglos de devolución de llamada solo son válidos durante la devolución de llamada, así que copia cualquier entrada que necesites conservar:

Cada solicitud completada ordered_get invoca su devolución de llamada una vez. Una entrada faltante o un fallo de la solicitud devuelve el valor predeterminado proporcionado. Cada solicitud completada ordered_get_all también invoca su devolución de llamada una vez; un resultado vacío o un fallo de la solicitud proporciona un arreglo vacío. Los fallos de la solicitud se registran.

Última actualización