114 lines
12 KiB
Markdown
114 lines
12 KiB
Markdown
# Экономика
|
||
|
||
Ресурсы и производство: сколько у игрока дерева, еды, золота и остального, кто их добывает и тратит.
|
||
|
||
- **Сборки:**
|
||
- `Bogatyri.Economy` — склад ресурсов и здания-рабочие места (Unity);
|
||
- `Bogatyri.Economy.Rules` — правила добычи, чистый C# без Unity (папка `Rules`).
|
||
- **Папка:** `Assets/Scripts/Modules/Economy`.
|
||
- **Зависит от:** ядра.
|
||
|
||
## Контракт `IEconomy`
|
||
|
||
| Метод | Что делает |
|
||
| --- | --- |
|
||
| `Get(type)` | Сколько ресурса сейчас. |
|
||
| `Has(type, amount)` | Хватает ли. |
|
||
| `Add(type, amount)` | Добавить (или отнять отрицательным числом; в минус не уходит). |
|
||
| `TrySpend(type, amount)` | Потратить, если хватает. |
|
||
| `CanAfford(cost)` / `TrySpend(cost)` | Проверить и списать цену из нескольких ресурсов — всё или ничего. |
|
||
| `GetCapacity(type)` | Лимит склада; `float.PositiveInfinity` — без лимита (люди, сила). |
|
||
|
||
Получить: `GameServices.Get<IEconomy>()`.
|
||
|
||
## Контракт `IProduction` (добыча через рабочих, этап 3)
|
||
|
||
| Метод | Что делает |
|
||
| --- | --- |
|
||
| `Slots(job)` | Мест для рабочих этой профессии во всех зданиях города. |
|
||
| `Efficiency(job)` | Множитель нормы от уровня зданий (1 — здания 1 уровня). |
|
||
| `RatePerHour(type)` | Добыча ресурса в час сейчас. |
|
||
| `Produce(hours)` | Добыть за `hours` часов. Вызывает модуль Населения в своём расчёте: сначала добыли, потом съели. |
|
||
|
||
Получить: `GameServices.Get<IProduction>()`.
|
||
|
||
## Ресурсы и склады (этап 1)
|
||
|
||
- **Ресурсы:** дерево, еда, золото, камень, металл, синий кристалл. `Power` («Сила») — не ресурс, а вычисляемая мощь для рейтинга (`GameProgress.TotalPower`), лимита у неё нет. «Люди» — отражение модуля Населения.
|
||
- **Лимиты:** без построек — 1000 дерева, камня, металла и золота, 1500 еды. Каждый уровень **Склада** — +1000 к первым четырём, каждый уровень **Амбара** — +1500 к еде. Синий кристалл — отдельный небольшой лимит 50 (решение команды от 19.10). Все числа — `EconomyConfig`, раздел «Склады и лимиты», не утверждены.
|
||
- **Сверх лимита ресурс не прибавляется** — ни добыча, ни награды, лишнее пропадает. Если запас уже выше лимита (старое сохранение), он не урезается, просто больше не растёт.
|
||
- **Склад и Амбар** появляются в списке стройки кодом (`App/StorageBootstrap`, как Казармы), пока без своего арта — отличаются цветом. Компонент `App/StorageBuilding`.
|
||
- **Верхняя панель** (`ResourceUIText`): «запас / лимит» и строкой ниже прирост в час (у еды — добыча минус расход). Без сокращений 1.2K. У «Людей» — население / предел жилья и прирост людей.
|
||
|
||
## Добыча через рабочих (этап 3)
|
||
|
||
- **Ресурс производят люди, здание даёт места и эффективность.** Добыча в час = min(рабочие, места) × норма × эффективность.
|
||
- **Нормы T1 в час:** лесоруб — 2 дерева, фермер — 2 еды, каменотёс — 1.5 камня, шахтёр — 1 металла (Шахта) или 0.4 золота (Золотой рудник).
|
||
- **Здание 1 уровня — 30 мест.** Каждый следующий уровень: +10 мест и +10% к норме. Не утверждено.
|
||
- **Кликер убран.** `ResourceCollector` теперь здание-рабочее место (имя класса оставлено, чтобы не перенастраивать префабы). Тап по зданию — окно здания и рабочих (`App/BuildingWindow`): `−` / `+` на каждую профессию, «Свободно: N из M», кнопка «Улучшить». `ResourceProducer` (добыча по таймеру) выключен.
|
||
- **Дом** (здание «Население», `resourceType = Population`) — не рабочее место: каждый уровень +50 к пределу жилья.
|
||
- **Кристалл** — рабочих нет, синий кристалл добывается в разломах на карте мира (этап 6).
|
||
- **Какие здания стоят,** модулю сообщает `App/CitySync`: раз в полсекунды смотрит город и передаёт места, Дома и уровни Складов. Модуль запоминает места в сохранении, поэтому добыча идёт и на карте мира, и офлайн.
|
||
- **Новые места заполняются сами:** построили или улучшили здание — свободные рабочие встают туда. Старое сохранение при первом запуске — рабочие расставляются поровну по всем местам.
|
||
- **Проверка из документа** (тест `BalancedCity_…`): 45 фермеров, 25 лесорубов, 15 каменотёсов, 15 шахтёров → 90 еды, 50 дерева, 22.5 камня, 15 металла в час.
|
||
|
||
## События
|
||
|
||
- **Публикует:** `ResourceChangedEvent` — при любом изменении ресурса (тип и новое значение).
|
||
- **Слушает:** ничего.
|
||
|
||
Для интерфейса остаётся C#-событие `ResourceManager.OnResourceChanged` (его слушает `ResourceUIText`).
|
||
|
||
## Сохранение
|
||
|
||
Секция `"economy"`: `{ "resources": [ { "type", "amount" } ], "capacities": [ … ] }` — имена полей как в старом `save.json`, лимиты склада — новым списком.
|
||
|
||
Секция `"production"` (`ProductionService`, простые строки): `slots=` — места по профессиям, `eff=` — эффективность, `pending=` — доли добычи меньше 1.
|
||
|
||
Сброс (`ResetState`): стартовые значения из Inspector `ResourceManager` (`startWood` и т.д.).
|
||
|
||
## Файлы
|
||
|
||
| Файл | Что это |
|
||
| --- | --- |
|
||
| `ResourceManager.cs` | Хранилище ресурсов и лимитов склада, реализует `IEconomy` и `ISaveParticipant`. Живёт между сценами. |
|
||
| `ResourceCollector.cs` | Здание-рабочее место (или Дом, Кристалл). Реализует `ILeveledBuilding`. Тап — событие `Tapped`. |
|
||
| `ResourceProducer.cs` | Устарело: выключен, оставлен для старых префабов. |
|
||
| `Rules/ProductionService.cs` | Добыча через рабочих: `ProductionRules`, `IProduction`, секция `"production"`. |
|
||
|
||
Слой приложения:
|
||
|
||
| Файл | Что это |
|
||
| --- | --- |
|
||
| `Economy/ResourceUIText.cs` | Ресурс на верхней панели: «запас / лимит» и прирост в час. |
|
||
| `Economy/BuildingUI.cs` | Полоска над зданием: рабочие / места. |
|
||
| `App/CitySync.cs` | Здания города → места, Дома, лимиты. |
|
||
| `App/BuildingWindow.cs` | Окно здания и рабочих. |
|
||
| `App/StorageBuilding.cs`, `App/StorageBootstrap.cs` | Склад и Амбар. |
|
||
|
||
## Таблица баланса `EconomyConfig`
|
||
|
||
Все числа экономики — в ассете `Assets/Resources/EconomyConfig.asset` (класс `App/EconomyConfig.cs`, слой приложения). Меняются в Inspector без перекомпиляции. Разделы: население, стартовые ресурсы новой игры, производство T1, месторождения, цена солдата. Числа с пометкой «не утверждено» — временные.
|
||
|
||
Модули конфиг не видят: `App/GameModules` переводит его в правила модуля (например, `PopulationRules`). Нет ассета — берутся числа по умолчанию из `EconomyConfig.cs` и в консоли предупреждение.
|
||
|
||
Стартовые ресурсы новой игры выдаёт `App/GameModules` (при первой игре и после сброса): ресурс поднимается до стартового, если его меньше.
|
||
|
||
Ресурс `Population` («Люди») теперь отражает модуль Населения: `App/GameModules` держит его равным `IPopulation.Total`. Тратить его напрямую не нужно.
|
||
|
||
## Решения и план
|
||
|
||
- **Этап 1 (план разработки):** сделано 27.10.2026 — лимиты Склада и Амбара, «запас / лимит» и прирост на панели, без сокращений. `Gems` по-прежнему называется `Gems` (числа enum записаны в сохранениях), в интерфейсе — «Кристаллы».
|
||
- **Решение команды от 19.10.2026:** у синего кристалла отдельный небольшой настраиваемый лимит хранения, не бесконечный. Переполнение — одно правило для наград и добычи. Число не утверждено.
|
||
- **Этап 3:** сделано 27.10.2026 — кликер убран, производство = рабочие × норма × эффективность уровня. Множитель качества месторождения добавится в этапе 4.
|
||
- Все числа — из `EconomyConfig`, не в коде. Таблица создана 26.10.2026; производство, месторождения и цена солдата в ней уже есть, но используются начиная с этапов 3–5.
|
||
|
||
## Журнал изменений
|
||
|
||
| Дата | Кто | Что |
|
||
| --- | --- | --- |
|
||
| 27.10.2026 | Claude | Этапы 1 и 3: лимиты склада (`GetCapacity`, Склад, Амбар), «запас / лимит» и прирост на панели; добыча через рабочих (`Bogatyri.Economy.Rules`, `IProduction`), кликер убран, окно здания и рабочих, улучшение зданий. Исправлены лишние `ResourceUIText` «Люди» на ячейках панели. |
|
||
| 26.10.2026 | Claude | Таблица баланса `EconomyConfig`. Стартовые ресурсы новой игры. Ресурс «Люди» отражает модуль Населения. |
|
||
| 19.10.2026 | Claude | `ResetState()`: при сбросе сохранений ресурсы возвращаются к стартовым. |
|
||
| 19.10.2026 | Claude | Модуль выделен: `ResourceManager`, `ResourceProducer`, `ResourceCollector` перенесены в `Modules/Economy`. `ResourceManager` реализует `IEconomy`, публикует `ResourceChangedEvent`, сам сохраняет секцию `"economy"`. |
|