# Сохранения Игровое состояние: запись и загрузка `save.json`. Модуль не знает, что хранят другие модули: каждый модуль сам отдаёт свою секцию. - **Сборка:** `Bogatyri.Save`. - **Папка:** `Assets/Scripts/Modules/Save`. - **Зависит от:** ядра. ## Контракт `ISaveSystem` | Член | Что делает | | --- | --- | | `HasSave` | Есть ли файл сохранения. | | `SaveNow()` | Сохранить сейчас. | | `DeleteSave()` | Только стереть файл (состояние модулей в памяти не меняется). | | `ResetAll()` | **Сброс сохранений**: все модули возвращаются к новой игре, файл сразу перезаписывается. | Для слоя приложения остаются `SaveManager.Instance.SaveGame()`, `LoadGame()`, `HasSaveFile()`, `DeleteSave()`. ## Как модуль подключает свои данные ```csharp public class MyModule : ISaveParticipant { public string SaveKey => "mymodule"; public string Capture() => JsonUtility.ToJson(data); // null -- оставить то, что уже в файле public void Restore(string json) { data = JsonUtility.FromJson(json); } public void ResetState() { data = new MyData(); } // новая игра } SaveRegistry.Register(myModule); // при запуске модуля ``` | Секция | Модуль | | --- | --- | | `economy` | Экономика | | `settlement` | Поселение | | `world` | Глобальный мир | | `circle` | Круг (простые строки, не JSON — модуль без Unity) | | `army` | Армия (простые строки: `troops=…`, `march=…`) | ## Формат файла Версия 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`; - **Поселение** — Ратуша 1 уровня, постройки убраны, участки свободны; - **Мир** — все походы отменены; - **Круг** — игрок ни в каком Круге, его Круги распущены; - **Армия** — войск и походов нет. Новый модуль с данными обязан реализовать `ResetState()`, иначе он не скомпилируется: метод входит в контракт. ## События **Публикует:** - `GameLoadedEvent` — после загрузки (и когда файла сохранения нет — загрузка завершена, новая игра); - `GameSavedEvent` — после записи; - `GameResetEvent` — после сброса сохранений. **Слушает:** ничего. ## Файлы | Файл | Что это | | --- | --- | | `SaveManager.cs` | Запись и чтение секций, автосохранение, перенос версии 1. | | `GameBootstrap.cs` | Загружает сохранение при старте сцены города. | | `Assets/Editor/SaveResetMenu.cs` (редактор) | Меню Tools → Сбросить сохранения / Открыть папку сохранений. | ## Решения и план - **Этап 0:** одно сохранение. `GameProgress` (`progress.json`: герой, задания, почта, магазин, арена) пока пишет свой файл. Его данные переводятся в секции по мере выноса в модули. Войска уже перенесены — секция `army`. - Номер версии файла поднимать при каждом несовместимом изменении и дописывать перенос старой версии здесь. ## Журнал изменений | Дата | Кто | Что | | --- | --- | --- | | 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. Запись до загрузки запрещена. Сохранение города вынесено в модуль Поселения, походов — в модуль Мира. |