Боевая система с типами войск

Модуль Боя (Bogatyri.Battle, без Unity и float):
- сила стороны по типам войск, сила воина — из GameData.Troops (4/5/9/16)
- контры +25%: пехота > кавалерия > лучники > пехота (по составу врага)
- стены +20% защитникам; осадные +50% против стен, −25% в поле
- потери по типам: проигравший — половина, победитель — до половины (чем ровнее бой, тем больше)
- BattleRequest/BattleOutcome расширены (состав, стены, бонусы, сила сторон); бой «числом» считается пехотой
- формула — предложение, числа константами в BattleSystem.cs, ждёт утверждения командой

Мир и Армия:
- состав гарнизона у каждой цели (WorldMapLayout.GarrisonUnits, из id — карта не изменилась)
- поход хранит состав по типам; выжившие возвращаются точно по типам (IArmy.GetMarchUnits/ReturnUnits)
- время походов по GameClock: перемотка в DEV-панели проматывает и походы

Интерфейс карты:
- окно атаки: состав гарнизона и ожидаемый исход (сила сторон, победа/поражение, потери)
- верхняя панель: воины в походах (а не число отрядов)

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alexander
2026-10-27 16:34:58 +01:00
co-authored by Claude Opus 5.5
parent f188c3a8eb
commit 460d1db2de
14 changed files with 406 additions and 35 deletions
+41 -12
View File
@@ -1,8 +1,8 @@
# Боевая система
Урон, потери, исход боя. Модуль только считает: кто победил и сколько погибло. Кто идёт в бой и что делать с итогом, решают другие модули.
Урон, потери, исход боя с учётом типов войск. Модуль только считает: кто победил и сколько погибло каждого типа. Кто идёт в бой и что делать с итогом, решают другие модули.
- **Сборка:** `Bogatyri.Battle` (без Unity — тот же код будет считать бои на сервере).
- **Сборка:** `Bogatyri.Battle` (без Unity и без float — тот же код будет считать бои на сервере).
- **Папка:** `Assets/Scripts/Modules/Battle`.
- **Зависит от:** ядра.
@@ -10,19 +10,45 @@
`BattleOutcome Resolve(BattleRequest request)`
| `BattleRequest` | `BattleOutcome` |
| `BattleRequest` | Что это |
| --- | --- |
| `Attackers` — атакующих | `Victory` — победил атакующий |
| `Defenders` — защитников | `AttackerLosses`, `DefenderLosses`, `Survivors` |
| `AttackerUnits`, `DefenderUnits` | Состав сторон по типам (`TroopType`: пехота, лучники, кавалерия, осадные). |
| `Attackers`, `Defenders` | Число воинов, если состав не задан (`null`) — тогда все считаются пехотой. |
| `DefenderFortified` | Защитники за стенами (город, замок). |
| `AttackerBonusPercent`, `DefenderBonusPercent` | Бонусы сторон в процентах: герой, технологии, голод (минус). |
Регистрирует `App/GameModules`. Мир получает модуль при создании симуляции, не через реестр — так симуляцию можно запустить на сервере.
| `BattleOutcome` | Что это |
| --- | --- |
| `Victory` | Победил атакующий. |
| `AttackerPower`, `DefenderPower` | Сила сторон ×100 (целые числа): с контрами, стенами и бонусами. |
| `AttackerLosses`, `DefenderLosses`, `Survivors` | Потери сторон и выжившие атакующие — всего. |
| `AttackerSurvivorUnits`, `DefenderLossUnits` | То же по типам войск. |
## Текущие правила
Регистрирует `App/GameModules`: силу воина каждого типа передаёт из `GameData.Troops` (4 / 5 / 9 / 16), чтобы числа были в одном месте. Мир получает модуль при создании симуляции, не через реестр — так симуляцию можно запустить на сервере.
- Побеждает тот, у кого больше солдат; ничья — победа защитника.
- Проигравший теряет половину своего войска, победитель — столько же.
## Правила
Пример: 30 против 20 — победа, погибает 10 атакующих и 10 защитников, домой идут 20.
Это **предложение**. Формула боя — открытый вопрос этапа 6 плана, команда должна её утвердить. Все числа — константы в начале `BattleSystem.cs`.
| Правило | Значение |
| --- | --- |
| Сила стороны | Сумма по типам: воины × сила типа × (100% + контры + осадный бонус) × (100% + бонусы стороны). |
| Контры, +25% | Пехота сильнее кавалерии, кавалерия сильнее лучников, лучники сильнее пехоты. Бонус взвешивается по составу врага: против армии, где кавалерии 20%, пехота получает +5%. |
| Осадные | Против стен +50%, в поле −25%. |
| Стены | Защитники за стенами сильнее на 20%. |
| Исход | Побеждает тот, у кого сила больше; ничья — защитнику. |
| Потери проигравшего | Половина каждого типа. |
| Потери победителя | Половина × (сила проигравшего / сила победителя): чем ровнее бой, тем больше потерь, но не больше половины. |
Примеры (замок Змея Горыныча, гарнизон 20: пехота 8, лучники 6, кавалерия 4, осадные 2, за стенами):
| Атакующие | Сила | Исход | Вернутся |
| --- | --- | --- | --- |
| 30 пехоты | 126 против 155 | поражение | 15 |
| 40 пехоты | 168 против 155 | победа | 22 |
| 30 смешанных (12 / 8 / 6 / 4) | 248 против 154 | победа | — |
Бой без состава (старые походы, `Attackers` и `Defenders` числами) считается так, будто все — пехота. Без стен 30 против 20 — по-прежнему победа и 20 вернувшихся.
## События
@@ -34,11 +60,14 @@
## Решения и план
- **Этап 6:** формула с типами войск — кто кого контрит и как делятся потери. Сначала записать правила в документ экономики.
- **Решение команды от 19.10.2026:** при голоде сильные дебаффы на боевую эффективность, включая гарнизон и походы. В `BattleRequest` для этого появятся модификаторы силы сторон; проценты — из `EconomyConfig`.
- **Утвердить формулу** (контры, стены, осадные, потери) или поправить числа в `BattleSystem.cs`.
- **Бонус героя** пока не передаётся в поход: `GameProgress.ArmyBonus` и сила героя в слое приложения. Нужен способ передать их в `AttackerBonusPercent` — например, через новый контракт или поле похода.
- **Решение команды от 19.10.2026:** при голоде сильные дебаффы на боевую эффективность, включая гарнизон и походы. Для этого есть `AttackerBonusPercent` / `DefenderBonusPercent` (минус), проценты — из `EconomyConfig`. Голод уже считает модуль Населения (`IsStarving`).
- **Гарнизоны соседей** пока не уменьшаются после боя: соседи — заглушки до сервера.
## Журнал изменений
| Дата | Кто | Что |
| --- | --- | --- |
| 27.10.2026 | Claude | Бой с типами войск: сила по типам из `GameData.Troops`, контры (пехота > кавалерия > лучники > пехота, +25%), стены +20%, осадные +50% против стен и −25% в поле, потери по типам. `BattleRequest` и `BattleOutcome` расширены, старый бой «числом» считается пехотой. Тесты: контры, стены, осадные, потери в пределах состава. |
| 19.10.2026 | Claude | Модуль выделен: `BattleResolver` из `WorldSimulation.cs` стал `BattleSystem` с контрактом `IBattleSystem`; `BattleOutcome` перенесён в ядро. Правила не изменились. |