Files
MVP1/Docs/Modules/Save.md
T

7.8 KiB
Raw Blame History

Сохранения

Игровое состояние: запись и загрузка save.json. Модуль не знает, что хранят другие модули: каждый модуль сам отдаёт свою секцию.

  • Сборка: Bogatyri.Save.
  • Папка: Assets/Scripts/Modules/Save.
  • Зависит от: ядра.

Контракт ISaveSystem

Член Что делает
HasSave Есть ли файл сохранения.
SaveNow() Сохранить сейчас.
DeleteSave() Только стереть файл (состояние модулей в памяти не меняется).
ResetAll() Сброс сохранений: все модули возвращаются к новой игре, файл сразу перезаписывается.

Для слоя приложения остаются SaveManager.Instance.SaveGame(), LoadGame(), HasSaveFile(), DeleteSave().

Как модуль подключает свои данные

public class MyModule : ISaveParticipant
{
    public string SaveKey => "mymodule";
    public string Capture() => JsonUtility.ToJson(data); // null -- оставить то, что уже в файле
    public void Restore(string json) { data = JsonUtility.FromJson<MyData>(json); }
    public void ResetState() { data = new MyData(); } // новая игра
}
SaveRegistry.Register(myModule); // при запуске модуля
Секция Модуль
economy Экономика
settlement Поселение
world Глобальный мир
circle Круг (простые строки, не JSON — модуль без Unity)
army Армия (простые строки: troops=…, march=…)
population Население (простые строки: civilians=…, jobs=…, lastTick=… и др.)
production Добыча (простые строки: slots=…, eff=…, pending=…)

Формат файла

Версия 2: { "version": 2, "sections": [ { "key": "economy", "json": "..." } ] }.

Версия 1 (старый плоский save.json) читается сама: файл целиком отдаётся Экономике и Поселению, их секции берут поля по старым именам.

Когда сохраняется

  • Автоматически:
    • автосохранение каждые 30 секунд;
    • при сворачивании и закрытии игры;
    • перед переходом между сценами (SceneNavigator);
    • после событий походов.
  • Защиты:
    • пока сохранение не загружено, запись пропускается — иначе стартовые нули модулей затёрли бы файл;
    • секция модуля, которого сейчас нет (например, город на карте мира), не пропадает.

Сброс сохранений

Откуда Что происходит
Настройки → «Сбросить весь прогресс» GameProgress.ResetAll(): удаляет progress.json, вызывает ISaveSystem.ResetAll(), создаёт новый прогресс (герой, задания, почта, войска).
ISaveSystem.ResetAll() Стирает save.json, вызывает ResetState() у каждого модуля, сразу записывает новую игру, публикует GameResetEvent.
Tools → Сбросить сохранения (редактор) В Play Mode — то же, что кнопка в Настройках. Вне Play Mode — удаляет save.json и progress.json.
Tools → Открыть папку сохранений Открывает Application.persistentDataPath.

Что сбрасывает каждый модуль:

  • Экономика — стартовые ресурсы из Inspector ResourceManager (лимиты склада пересчитает App/CitySync по зданиям);
  • Добыча — мест нет (построек нет);
  • Поселение — Ратуша 1 уровня, постройки убраны, участки свободны;
  • Мир — все походы отменены;
  • Круг — игрок ни в каком Круге, его Круги распущены;
  • Армия — войск и походов нет;
  • Население — стартовый город (270 жителей). После сброса App/GameModules выдаёт стартовое войско и ресурсы из EconomyConfig.

Новый модуль с данными обязан реализовать ResetState(), иначе он не скомпилируется: метод входит в контракт.

События

Публикует:

  • GameLoadedEvent — после загрузки (и когда файла сохранения нет — загрузка завершена, новая игра);
  • GameSavedEvent — после записи;
  • GameResetEvent — после сброса сохранений;
  • NewGameStartedEvent — GameBootstrap: файла сохранения нет, первая игра на устройстве.

Слушает: ничего.

Файлы

Файл Что это
SaveManager.cs Запись и чтение секций, автосохранение, перенос версии 1.
GameBootstrap.cs Загружает сохранение при старте сцены города.
Assets/Editor/SaveResetMenu.cs (редактор) Меню Tools → Сбросить сохранения / Открыть папку сохранений.

Решения и план

  • Этап 0: одно сохранение. GameProgress (progress.json: герой, задания, почта, магазин, арена) пока пишет свой файл. Его данные переводятся в секции по мере выноса в модули. Войска уже перенесены — секция army.
  • Номер версии файла поднимать при каждом несовместимом изменении и дописывать перенос старой версии здесь.

Журнал изменений

Дата Кто Что
27.10.2026 Claude Новая секция production; в секции economy — список capacities (лимиты склада).
26.10.2026 Claude Новая секция population (модуль Населения). GameBootstrap публикует NewGameStartedEvent, если файла нет.
23.10.2026 Claude Новая секция army (модуль Армии). GameLoadedEvent публикуется и без файла сохранения.
19.10.2026 Claude Новая секция circle (модуль Круга).
19.10.2026 Claude Сброс сохранений: ISaveSystem.ResetAll(), ResetState() у модулей, GameResetEvent, меню редактора. Кнопка в Настройках теперь сбрасывает и походы, и память Поселения.
19.10.2026 Claude SaveManager переписан на секции модулей (ISaveParticipant), формат v2 с переносом v1. Запись до загрузки запрещена. Сохранение города вынесено в модуль Поселения, походов — в модуль Мира.