Files
MVP1/Docs/Modules/Save.md
T
AlexanderandClaude Opus 5.5 15b06b8f42 Модули Чата и Круга, разворот чата на весь экран, кнопка «Почта» в Safe Area
Модуль Чата (Bogatyri.Chat, без Unity):
- чат вынесен из Social в отдельный модуль; контракт IChat в ядре,
  событие ChatMessageReceivedEvent, LocalPlayer (id и имя игрока)
- панель чата работает только через контракт и события
- разворот чата на весь экран: кнопка «Развернуть/Свернуть» или Esc

Модуль Круга (Bogatyri.Circle, без Unity):
- основать Круг, вступить, выйти; роли главы и участника; 30 мест
- уход главы передаёт главенство, последний участник распускает Круг
- секция сохранения "circle", участвует в сбросе сохранений
- окно «Круг» (кнопка внизу карты мира), демо-Круги до появления сервера
- канал «Круг» в чате — только для участников Круга

Прочее:
- кнопка «Почта» привязана к правому краю нижней панели
  (в безопасной зоне она уезжала за экран)
- тесты Чата и Круга; документы Chat.md, Circle.md, обновлены README, Core, Save

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:07:45 +02:00

6.3 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)

Формат файла

Версия 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: герой, задания, почта, войска) пока пишет свой файл. Его данные переводятся в секции по мере выноса в модули: первыми — войска (модуль Армии).
  • Номер версии файла поднимать при каждом несовместимом изменении и дописывать перенос старой версии здесь.

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

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