# Армия Войска и их характеристики: сколько воинов каждого типа в городе, сколько в походах, обучение, потери, уход в поход и возвращение. **Единственное место, где хранятся войска.** - **Сборка:** `Bogatyri.Army` (без Unity). - **Папка:** `Assets/Scripts/Modules/Army`. - **Зависит от:** ядра. ## Контракт `IArmy` | Член | Что делает | | --- | --- | | `TypeCount` | Типов войск — 4 (пехота, лучники, кавалерия, осадные; порядок как в `GameData.Troops`). | | `GetTroops(type)` | Воинов этого типа в городе. | | `SoldiersAtHome` | Всего воинов в городе. | | `TroopsInMarches` | Воинов в походах. | | `AddTroops(type, count)` | Добавить воинов (обучение в Казармах). | | `LoseFraction(fraction)` | Потери в бою: от каждого типа погибает доля (с округлением вниз); возвращает, сколько погибло. | | `TakeForMarch(marchId, count)` | Забрать воинов в поход пропорционально составу армии и запомнить состав. | | `ReturnFromMarch(marchId, survivors)` | Вернуть выживших по тем же типам. | Получить: `GameServices.Get()`. Регистрирует `App/GameModules`. `GameProgress` (обучение, кампания, арена, сила армии) и панели работают с войсками только через этот контракт. ## Правило «один солдат в одном месте» Воин либо в городе, либо в походе. Поход забирает воинов из города и запоминает состав, возвращение раздаёт выживших по тем же типам. Тест `ArmyService_MarchNeverCreatesOrLosesSoldiers` проверяет, что «дома + в походах» всегда равно общему числу. ## События - **Публикует:** `TroopsChangedEvent` (воинов в городе и в походах) — при обучении, потерях, походе, возвращении, загрузке, сбросе. По нему `App/GameModules` перерисовывает панели HUD. - **Слушает:** ничего. ## Сохранение Секция `"army"`. Модуль без Unity, поэтому формат — простые строки: ``` troops=<пехота>,<лучники>,<кавалерия>,<осадные> march=:<пехота>,<лучники>,<кавалерия>,<осадные> ``` Сброс (`ResetState`): войск и походов нет. **Перенос из старых сохранений:** - Раньше войска лежали в `progress.json`: `troops` хранил `GameProgress`, `sashaMarchUnits` — мост `ArmyBridge`. - Если в `save.json` нет секции `"army"`, после загрузки `App/GameModules` переносит их в модуль (`ImportLegacy`). - Из `progress.json` они удаляются только после записи `save.json`. Флаг `armyInModule` отмечает, что перенос сделан. ## Файлы | Файл | Что это | | --- | --- | | `ArmyService.cs` | Хранилище войск, реализует `IArmy` и `ISaveParticipant`. | | `ArmyMath.cs` | `TakeProportional` — кого взять в поход; `SplitSurvivors` — как вернуть выживших. | ## Решения и план - **Этап 5 (план разработки):** солдат стоит 1 человека, 15 еды, 5 металла, 5 золота; содержание 0,2 еды в час; погибшие уменьшают население. Делается вместе с модулем «Население». - **Решение команды от 19.10.2026:** - войска набираются из населения с сохранением гражданского минимума; - гарнизон поселения: часть солдат назначается защищать город; - общая армия = гарнизон + доступные отряды + войска в походах, на точках и в гарнизоне Круга, **один солдат не может быть в двух местах**; - гарнизон ест еду и участвует в защите; - при голоде дебаффы действуют и на гарнизон, и на походы. - **Следующий шаг модуля:** гарнизон — третье место для солдата рядом с «дома» и «в походе». - Описания типов войск (`GameData.Troops`: цена, сила, время обучения) пока в слое приложения; цены перейдут в `EconomyConfig`. ## Журнал изменений | Дата | Кто | Что | | --- | --- | --- | | 23.10.2026 | Claude | Войска переехали в модуль: `ArmyService` — единственное хранилище войск (секция `"army"`), `IArmy` расширен (типы, обучение, потери, войска в походах), событие `TroopsChangedEvent`. Перенос из `progress.json` с удалением старых данных только после записи `save.json`. `ArmyBridge` удалён — контракты и перенос сохранений проверены тестами. | | 19.10.2026 | Claude | `ArmyBridge.TroopsInMarches` для панели «Войска». После удаления маленькой карты войска в походах учитываются только здесь (`sashaMarchUnits`). | | 19.10.2026 | Claude | Модуль создан: `ArmyMath` (правила деления войск, без Unity, тесты на отсутствие двойного учёта). `ArmyBridge` сохранён и теперь реализует `IArmy` через `ArmyMath`; формат `sashaMarchUnits` не изменён. |