# Экономика Ресурсы и производство: сколько у игрока дерева, еды, золота и остального, кто их добывает и тратит. - **Сборки:** - `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()`. ## Контракт `IProduction` (добыча через рабочих, этап 3) | Метод | Что делает | | --- | --- | | `Slots(job)` | Мест для рабочих этой профессии во всех зданиях города. | | `Efficiency(job)` | Множитель нормы от уровня зданий (1 — здания 1 уровня). | | `RatePerHour(type)` | Добыча ресурса в час сейчас. | | `Produce(hours)` | Добыть за `hours` часов. Вызывает модуль Населения в своём расчёте: сначала добыли, потом съели. | Получить: `GameServices.Get()`. ## Ресурсы и склады (этап 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"`. |