Сохранения: JSON, идентификаторы и восстановление состояния
Формат и границы
C7Engine/SaveManager.cs распознаёт SAV, BIQ, JSON и ZIP по расширению. Однако собственный SaveGame.Save записывает UTF-8 JSON, а Load читает файл через File.ReadAllText.
В этом пути нет упаковки или распаковки ZIP. Следовательно, признанное расширение .zip нельзя объявить поддержкой настоящих ZIP-архивов. Такая несогласованность — хороший пример, зачем проверять обработчик, а не enum формата.
Сериализация использует System.Text.Json, отдельные Save-типы, поля и преобразователи. Глубокое копирование ruleset тоже выполняется через JSON. В данных есть поле Version со значением по умолчанию 0.0.0; это не доказывает наличие полной системы миграций.
Восстановление ссылок
Преобразование SaveGame в GameData создаёт определения, технологии, игроков, карту, здания, юниты и города в определённом порядке. Ссылки разрешаются по ключам и ID. После загрузки пересчитываются владельцы клеток и инвалидируется торговая сеть.
Это решает проблему циклического графа: город ссылается на жителя, житель на клетку, клетка на город. Сериализовать весь рабочий граф напрямую означало бы получить циклы или дубликаты. Источники: C7Engine/C7GameData/Save/SaveCity.cs, C7Engine/C7GameData/Save/SaveUnit.cs, C7Engine/C7GameData/ID.cs.
Режим и случайность
Сохраняется конфигурация игрового режима, история, номер хода, состояние игроков и победы. Поведение загружается заново из режима; итог зависит от установленной версии Lua-файлов.
Сохранён seed. При создании GameData генератор случайности инициализируется через new Random(seed). Из рассмотренного пути не следует сохранение внутреннего состояния RNG или счётчика использованных значений. Один seed не гарантирует идентичное продолжение после загрузки.
Источник: C7Engine/C7GameData/GameData.cs. Для нашей игры это основание хранить состояние собственного PRNG и различать случайность генерации карты, боя и AI.
Документация и код расходятся
Technical notes обсуждает проблемы циклов и историческое предложение перейти на Newtonsoft во времена .NET 6. Текущий SaveGame использует System.Text.Json; предложение не следует выдавать за актуальную зависимость сериализации.
Применение к нашему экспорту
Наш version: 1 и localStorage уже полезны, но профиль следует дополнить версией схемы, идентификатором правил, версиями ресурсов, PRNG и фазой хода. Проверять уникальность ID и целостность ссылок до изменения текущей партии.
Ключевой сценарий: сохранить после частичного хода, загрузить и продолжить без повторного производства, повторного хода AI или потери договоров. EngineTests/GameData/SaveTest.cs содержит исходники round-trip и других проверок; здесь тесты не запускались.