Для сохранения более сложных структур данных вы можете сериализовать их в JSON и хранить в системе сохранений.
CSL может сериализовать для вас определённые структуры данных в JSON. Это особенно полезно, когда вы хотите сохранить «пакет» связанных полей (например, прогресс игрока, улучшения, разблокировки и т. д.) без управления множеством отдельных ключей сохранения.
Под капотом это использует JSON API системы Save:
Save.set_json(player, key, value)
Save.try_get_json(player, key, out) -> bool
Сохранение/загрузка JSON выполняется для каждого игрока отдельно (он принимает player). Глобальное сохранение игры сейчас поддерживает только строки и целые числа.
Что сохраняется?
В JSON включаются только поля, помеченные @ao_serialize .
Save.try_get_json возвращает false если ключ отсутствует или строка JSON имеет неверный формат. Если ключ существует, но структура изменилась (добавлены новые поля, удалены старые поля), он возвращает true с пропущенными полями, заполненными нулями.
Если вы переименуете/удалите сериализованные поля, старый JSON может не распарситься, и вы попадёте в путь со значениями по умолчанию. Планируйте миграции заранее (см. ниже).
Версионирование и миграции
Если вы ожидаете, что схема JSON изменится, включите поле version в структуру и выполняйте миграцию после загрузки.
Лучшие практики для сохранения совместимости:
Предпочитайте добавлять новые поля (старый JSON часто всё ещё парсится; заполните значения по умолчанию после загрузки)
Избегайте переименования/удаления полей (это может вызвать ошибки парсинга)
Если вам нужен жёсткий разрыв, рассмотрите сохранение под новым ключом (например, "progress_v2") и наличие резервного загрузчика
Пример миграции:
Когда использовать JSON, а когда простые ключи
Используйте простые ключи (Save.set_int, Save.set_string, и т. д.) — для небольшого числа значений, которые вы часто читаете/записываете.
Используйте JSON когда вы хотите хранить цельную структуру (прогресс, наборы снаряжения, разблокировки) и держать логику сохранения централизованной.
Отдельный JSON API
Вы также можете сериализовать/десериализовать JSON независимо от системы Save (например, для логирования, сети или пользовательского хранилища):
// Примечание: записываются только поля @ao_serialize
Save.set_json(player, "progress", ref progress);
load_progress :: proc(player: Player) -> Player_Progress {
progress: Player_Progress;
if !Save.try_get_json(player, "progress", ref progress) {
// Новый игрок (или старый JSON больше не совпадает) → значения по умолчанию
progress.version = 1;
progress.xp = 0;
progress.level = 1;
progress.unlocked_skins = .{};
}
return progress;
}