Files
MVP1/Docs/Modules/World.md
T
AlexanderandClaude Opus 5.5 b1a396e9a2 Лагеря разбойников (PvE) на карте мира
Модуль Мира (Bogatyri.World.Simulation, без Unity):
- 12 лагерей трёх уровней: Стан разбойников, Логово лиходеев, Становище Соловья-разбойника
  (гарнизон 6–9 / 14–17 / 26–29, добыча — еда, дерево, золото, металл)
- ставятся отдельным генератором после городов: замок, твой город и соседи остались на местах
- бой в поле (без стен), у разбойников нет осадных
- после победы лагерь разбит на 30 минут (CampRules.RespawnMs), напасть нельзя
- бои считаются по времени прихода: второе войско к разбитому лагерю — без боя, все домой, добычи нет
- секция сохранения world хранит разбитые лагеря (camps); сброс — все лагеря на месте
- MarchReturnedEvent.TargetEmpty, окно в городе пишет «лагерь уже был разбит»

Интерфейс карты:
- лагерь — фиолетовый круг с подписью «название, ур. N, гарнизон»; разбитый — серый с таймером
- окно атаки: уровень лагеря, «бой в поле» / «за стенами», прогноз с учётом стен
- окно «ЛАГЕРЬ ПУСТ», подсказка при нажатии на разбитый лагерь

Тесты: расстановка лагерей, бой в поле без осадных, разбит → второе войско находит пустым → сохранение → появляется снова.
Документы World, Battle, Save, Core, README обновлены. Числа требуют балансировки.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 16:46:54 +01:00

10 KiB
Raw Blame History

Глобальный мир

Карта и перемещения: замок с боссом, 20 соседних городов, 12 лагерей разбойников, походы по реальному времени (идут, даже когда игра закрыта).

  • Сборки:
    • Bogatyri.World.Simulation — карта и походы, чистый C# без Unity (переедет на сервер);
    • Bogatyri.World — MarchManager, Unity-часть.
  • Папка: Assets/Scripts/Modules/World.
  • Зависит от: ядра. Войска — через IArmy, добыча — через IEconomy, бой — через IBattleSystem.

Контракт IWorld

Член Что делает
ActiveMarches Сколько походов в пути.
TryStartMarch(targetId, soldiers, out error) Отправить войско на цель.

Получить: GameServices.Get<IWorld>(). Интерфейсу карты (WorldMapController) можно обращаться к MarchManager.Instance и его C#-событиям: там полные данные похода.

События

Публикует:

  • MarchStartedEvent — войско выступило;
  • MarchBattleResolvedEvent — бой у цели прошёл;
  • MarchReturnedEvent — войско вернулось, солдаты и добыча зачислены. Поля: MarchId, Victory, Survivors, Sent, TargetEmpty (лагерь уже был разбит, боя не было), TargetName, LootText.

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

По этим событиям App/GameModules:

  • считает статистику для заданий (marchesSent, dailyMarches, worldWins);
  • показывает окно «ВОЙСКО ВЕРНУЛОСЬ» в городе (UI/MarchReturnPopup.cs): куда ходили, победа или поражение, сколько вернулось из скольких, добыча.
    • Окно появляется и за походы, закончившиеся, пока игра была закрыта: сразу после входа в город.
    • Несколько возвращений — окна по очереди.
    • На карте мира окно своё (WorldMapController).

Сохранение

Секция "world": { "marches": [ MarchData ], "camps": [ { "id", "respawnMs" } ] } — походы и разбитые лагеря с моментом их появления. Старые сохранения без camps читаются: все лагеря на месте.

Сброс (ResetState): все походы отменяются, все лагеря на месте. Войска в походе не возвращаются: их сбрасывает GameProgress вместе с армией.

Раньше походы лежали в progress.json (sashaMarches). При первом запуске App/GameModules переносит их в модуль Мира и удаляет из progress.json только после записи save.json.

Файлы

Файл Что это
MarchManager.cs Ведёт походы, реализует IWorld и ISaveParticipant. Создаётся сам при запуске игры.
Simulation/WorldMapLayout.cs Карта: замок, город игрока, 20 соседей и 12 лагерей из seed.
Simulation/WorldSimulation.cs Походы: старт, бой по прибытии, возвращение. Бой получает через IBattleSystem.

Бой с типами войск:

  • у похода есть состав по типам (MarchData.units, берётся у Армии при выступлении) и выжившие по типам (survivorUnits);
  • у цели — состав гарнизона WorldMapLayout.GarrisonUnits(node). Он вычисляется из id цели, а не из генератора карты, поэтому карта осталась прежней. У Змея Горыныча 40% пехоты, 30% лучников, 20% кавалерии, 10% осадных; у соседей пропорции свои у каждого;
  • замок и города сражаются за стенами;
  • выжившие возвращаются в Армию точно по типам (IArmy.ReturnUnits). Старые походы без состава — как раньше, по пропорции;
  • окно атаки показывает состав гарнизона и ожидаемый исход: силу сторон, «скорее победа / поражение» и примерные потери. Расчёт тот же, что сделает модуль Боя.

Лагеря разбойников (PvE):

  • 12 лагерей, по 4 каждого уровня. Ставятся отдельным генератором после городов (seed ^ CampSeedSalt), поэтому замок, твой город и соседи остались на прежних местах. Лагерь может стоять ближе к городу (2,6 клетки), чем город к городу (3,6).
Уровень Название Гарнизон Добыча Нужно пехоты (примерно)
1 Стан разбойников 6–9 15 еды, 15 дерева 8–12
2 Логово лиходеев 14–17 25 еды, 25 дерева, 8 золота 18–21
3 Становище Соловья-разбойника 26–29 40 еды, 40 дерева, 15 золота, 8 металла 34–37
  • бой в поле: стен нет (WorldMapLayout.IsFortified), у разбойников нет осадных — их доля уходит пехоте;
  • после победы лагерь разбит на 30 минут (CampRules.RespawnMs, отсчёт от момента боя): на карте серый, с таймером, напасть нельзя;
  • если к лагерю шли два войска, бьётся первое пришедшее (бои считаются по времени прихода). Второе находит лагерь пустым: боя нет, домой идут все, добычи нет (MarchData.targetEmpty, окно «ЛАГЕРЬ ПУСТ»);
  • на карте лагерь — фиолетовый круг, подпись «название, ур. N, гарнизон».

Время походов — по GameClock: кнопки «+1 час» / «+10 часов» в отладочной панели проматывают и походы.

В слое приложения остаются WorldMap/WorldMapController.cs, MarchView.cs, MapCameraController.cs, SceneNavigator.cs.

В игре одна карта мира — сцена WorldMap. Открывается кнопкой «БОЙ» и кнопкой «МИР» в городе (UIPanelManager.Open("World") ведёт в эту сцену).

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

  • Этап 0, решено 19.10.2026: осталась одна карта мира — эта. Маленькая карта (панель «МИР», Meta/World) удалена. Перед удалением проверены ссылки в коде, сценах и префабах. Перенос сохранений: солдаты из её походов (marches в progress.json) возвращаются в город при загрузке — отправленные, а если отряд уже шёл назад, то выжившие. Добыча таких походов не переносится.
  • Этап 4 (утверждён без изменений): у позиций на карте — месторождения и их качество.
  • Этап 6: временные ресурсные точки и кристальные разломы; войска на точке недоступны дома.
  • Лагеря: числа (гарнизон, добыча, 30 минут до появления) — предложение, требуют балансировки. Позже их можно перенести в EconomyConfig. В мультиплеере разбитый лагерь — общий для всех игроков, его состояние будет вести сервер.

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

Дата Кто Что
27.10.2026 Claude Лагеря разбойников (PvE): 12 лагерей трёх уровней, бой в поле, после победы лагерь разбит на 30 минут, второе войско находит его пустым. Секция world хранит разбитые лагеря, в MarchReturnedEvent добавлен TargetEmpty. Тесты: расстановка лагерей, разбит и появляется снова, сохранение.
27.10.2026 Claude Бой с типами войск: состав похода и гарнизона, стены у замка и городов, выжившие по типам, ожидаемый исход в окне атаки. Время походов — по GameClock (перемотка в DEV проматывает походы).
23.10.2026 Claude Окно «ВОЙСКО ВЕРНУЛОСЬ» в городе. В MarchReturnedEvent добавлены Sent, TargetName, LootText.
19.10.2026 Claude Маленькая карта мира (Meta/World: WorldSystem, WorldMapPanel, WorldData, WorldLine) удалена, окно Panel_World убрано из сцены города. Кнопка «МИР» открывает эту карту. Солдаты из походов старой карты возвращаются в город.
19.10.2026 Claude ResetState(): при сбросе сохранений походы отменяются.
19.10.2026 Claude Модуль выделен. MarchManager больше не обращается к GameProgress и ResourceManager: войска через IArmy, добыча через IEconomy, сохранение — своя секция "world", статистика — через события. Формула боя вынесена в модуль Боя.