92 lines
6.8 KiB
Markdown
92 lines
6.8 KiB
Markdown
# Население
|
||
|
||
Сколько в городе людей, сколько они едят и как прирастают. Этап 2 плана разработки.
|
||
|
||
- **Сборка:** `Bogatyri.Population` (без Unity).
|
||
- **Папка:** `Assets/Scripts/Modules/Population`.
|
||
- **Зависит от:** ядра. Еду берёт через `IEconomy`, воинов считает через `IArmy`, уровень Ратуши — через `ISettlement`.
|
||
|
||
## Как устроено
|
||
|
||
- **Люди города = жители + воины.** Жителей хранит этот модуль, воинов — Армия. Так один человек не записан в двух местах.
|
||
- **Жители:** рабочие (`Workers`) и остальные (`Idle`). Распределение рабочих по зданиям — этап 3, пока рабочих 120.
|
||
- **Еда в час:** 0.1 на жителя, 0.2 на воина. Стартовый город (270 жителей + 30 воинов) ест 33 еды в час.
|
||
- **Прирост:** +2.5 человека в час, только если еды хватило и население ниже предела жилья.
|
||
- **Голод:** еды не хватило — остатки доедаются, прирост останавливается, `IsStarving = true`. Что ещё происходит при голоде, команда пока не решила.
|
||
- **Предел жилья:** `HousingBase + HousingPerTownHallLevel × (уровень Ратуши − 1)`. Числа не утверждены.
|
||
- **Время** — только из `GameClock`. Расчёт идёт кусками по 10 минут, и в игре, и офлайн, и при перемотке — правила одни. Офлайн досчитывается не больше чем за `MaxOfflineHours`. Если часы ушли назад, расчёт просто продолжается с «сейчас».
|
||
- **Еда списывается целыми единицами,** доли копятся в модуле: склад хранит `float`, и частые мелкие списания давали бы ошибку округления.
|
||
|
||
## Контракт `IPopulation`
|
||
|
||
| Член | Что это |
|
||
| --- | --- |
|
||
| `Total` | Все люди: жители + воины (в городе и в походах). |
|
||
| `Civilians`, `Workers`, `Idle` | Жители, из них рабочие и остальные. |
|
||
| `Soldiers` | Воины — из модуля Армии. |
|
||
| `HousingCap` | Предел населения. |
|
||
| `FoodPerHour`, `GrowthPerHour` | Расход еды и прирост в час сейчас. |
|
||
| `IsStarving` | Еды не хватило на последний расчёт. |
|
||
| `Tick(unixNow)` | Досчитать население до момента `unixNow`. |
|
||
|
||
Получить: `GameServices.Get<IPopulation>()`.
|
||
|
||
## События
|
||
|
||
- **Публикует:**
|
||
- `PopulationChangedEvent` — изменилось число людей;
|
||
- `StarvationChangedEvent` — голод начался или закончился.
|
||
- **Слушает** (через `App/GameModules`):
|
||
- `GameLoadedEvent` — офлайн-прогресс;
|
||
- `GameTimeAdvancedEvent` — перемотка в отладочной панели;
|
||
- `TroopsChangedEvent`, `TownHallLevelChangedEvent` — пересчёт общего числа и предела.
|
||
|
||
## Сохранение
|
||
|
||
Секция `"population"`, простые строки: `civilians=`, `workers=`, `growth=`, `food=`, `lastTick=`, `starving=`, `kit=`.
|
||
|
||
Сброс (`ResetState`): стартовый город, 270 жителей. Стартовое войско (30 пехоты) и стартовые ресурсы выдаёт `App/GameModules` после сброса и при первой игре (`NewGameStartedEvent`) — один раз (`kit=1`). Старым сохранениям без секции населения стартовый набор не выдаётся.
|
||
|
||
## Связь с игрой (слой приложения)
|
||
|
||
| Файл | Что делает |
|
||
| --- | --- |
|
||
| `App/GameModules.cs` | Создаёт модуль с числами из `EconomyConfig`, подписывает на события, выдаёт стартовый набор, держит ресурс «Люди» на верхней панели равным `Total`. |
|
||
| `App/PopulationTicker.cs` | Раз в 2 секунды вызывает `Tick` (модуль без Unity и не знает про `Update`). |
|
||
| `App/DebugPanel.cs` | Кнопка «DEV»: «+1 час», «+10 часов», ресурсы, «Еда = 0». Только редактор и Development Build. |
|
||
|
||
## Файлы
|
||
|
||
| Файл | Что это |
|
||
| --- | --- |
|
||
| `PopulationRules.cs` | Числа правил (заполняются из `EconomyConfig`). |
|
||
| `PopulationService.cs` | Модуль: расчёт, контракт `IPopulation`, сохранение. |
|
||
|
||
## Тесты
|
||
|
||
`Modules/Tests/PopulationTests.cs`:
|
||
- стартовый город — 300 человек, ест 33 еды в час;
|
||
- прирост 2.5 в час;
|
||
- голод останавливает прирост, еда вернулась — прирост идёт;
|
||
- упёрлись в предел — прирост стоит, Ратуша выше — идёт; предел не превышается;
|
||
- офлайн ограничен 48 часами;
|
||
- частые расчёты дают то же, что один большой;
|
||
- часы назад — ничего не ломается;
|
||
- перемотка идёт через те же правила;
|
||
- сохранение;
|
||
- стартовый набор — один раз;
|
||
- сброс.
|
||
|
||
## Решения и план
|
||
|
||
- **Голод:** дебаффы (в том числе у защитников) и правило снятия — решение команды от 19.10.2026, числа не утверждены. Модуль уже сообщает `StarvationChangedEvent`.
|
||
- **Предел жилья:** по решению команды растёт с постройкой Дома. Пока Дома нет — предел от уровня Ратуши.
|
||
- **Этап 3:** рабочие распределяются по зданиям, свободные — `Idle`.
|
||
- **Этап 5:** найм воина забирает человека из жителей (гражданский резерв — решение от 19.10.2026).
|
||
|
||
## Журнал изменений
|
||
|
||
| Дата | Кто | Что |
|
||
| --- | --- | --- |
|
||
| 26.10.2026 | Claude | Создан модуль: жители, еда, прирост, голод, предел жилья, офлайн-прогресс, секция `population`, тесты. |
|