# balance/era_1 — таблицы баланса эпохи 1 «Каменный век»

Пакет данных для импортёра CSV → ScriptableObjects (Фаза 0 плана) и Sim Core.
Все цифры согласованы между собой и проверены валидатором (см. ниже).

## Файлы

| Файл | Что описывает |
|---|---|
| `resources.csv` | Ресурсы: цены, хранимость (вода не складируется — её носят водоносы) |
| `buildings.csv` | Здания: стоимость, время стройки, штат (`профессия:кол-во`), радиусы служб |
| `recipes.csv` | Рецепты: `inputs → outputs` за `cycle_time_s` (формат `res:кол-во;res:кол-во`) |
| `professions.csv` | Профессии: зарплата/мин, требуемая квалификация |
| `homes.csv` | Уровни домов: вместимость, чек-лист потребностей апгрейда, деградация |
| `needs.csv` | Потребности: чем закрываются и как проверяются (доставка/покрытие обходчиком) |
| `citizens.csv` | Параметры агентов: интервалы еды/воды, таймеры смерти, иммиграция |
| `economy.csv` | Налог, аренда, казна, запасы месторождений, плечо логистики |
| `reference_layout.csv` | Эталонный состав города на ~120 жителей (для тестов и туториала) |
| `validate_balance.py` | Steady-state валидатор (python3, без зависимостей) |

## Модель времени и денег

- 1 тик = 1 логическая секунда; в CSV ставки за минуту или за цикл.
- **Замкнутый контур:** казна платит зарплаты → жители покупают еду/товары и платят
  аренду+налог → деньги возвращаются в казну.
- **Ключевое проектное решение:** контур сбалансирован так, что у жителей остаётся
  **~11% чистых зарплат** как накопления. Ровно на эту сумму казна в структурном
  дефиците. Это НЕ баг: накопления — единственный источник оплаты апгрейдов домов
  (upgrade_cost в homes.csv платит житель!), а апгрейд возвращает деньги в казну.
  Поток: дефицит казны → накопления → апгрейды → казна. Если менять цены/зарплаты/налог —
  держать накопления в коридоре 5–15% (валидатор следит).

## Ключевые константы (для интуиции)

- Житель ест 1 ед. еды / 15 мин, пьёт 1 воду / 10 мин; дом расходует 1 инструмент / час.
- Трудоспособных 60% населения. Эталонный город: 120 жителей, 72 трудоспособных, 68 вакансий.
- Рацион: 50% хлеб (4 монеты), 30% мясо (6), 20% ягоды (3).
- Хлебная цепочка: 3 фермы (1/36с) → 2 мельницы (1/25с) → 2 пекарни (2 хлеба+топливо/50с).
- Логистика — крупнейший работодатель: 26 переносчиков из 68 работников (как в K&M).
  Плечо переноски 35 м — это KPI планировки: растянутый город потребует больше складов.
- Запас каменоломни 14 400 ед. = ~6 мес добычи при офлайн-коэффициенте 0.25
  (полгода × 30 дн × 24 ч × 60 мин × 1.5/мин × 0.25 ≈ 14 400 с учётом простоев).

## Валидация

```
python3 validate_balance.py --pop 120
```

Результат на эталонном городе: **0 ошибок, 0 предупреждений**. Проверяется: занятость,
покрытие еды (118%), воды (125%), инструментов (200%), сходимость всех цепочек сырья,
пропускная способность переносчиков (131%), денежный контур (накопления 11%),
бюджет домохозяйства (запас 11%).

Диапазон устойчивости эталонного города: **115–125 жителей** (чисто), 110–129 —
предупреждения, за пределами — ошибки. Это осознанно: город на 130+ должен строить
новые фермы/пекарни, а не жить на старой инфраструктуре. Валидатор при `--pop 140`
честно показывает голод и обнищание — так и должно быть.

## Правила изменения баланса (для Codex и дизайнеров)

1. Меняешь цифру → прогоняй `validate_balance.py` — коммить только с 0 ошибок.
2. Цены еды двигать только вместе: соотношение хлеб:мясо:ягоды = 4:6:3 привязано
   к трудоёмкости цепочек (7.5 чел. на хлебной цепочке против 4 охотников и 2 собирателей).
3. Зарплаты: quali-профессии (мельник, пекарь, знахарь, мастер орудий) должны платить
   на 20–75% больше базовых — иначе жителям нет смысла учиться (механика эпохи 2+).
4. Не добавлять ресурсу `storable=0` без механики доставки (как у воды — водоносы).
5. `reference_layout.csv` — контракт для интеграционных тестов SimCore: тест строит этот
   город и проверяет те же метрики внутри симуляции (полное совпадение не требуется,
   допуск ±10% из-за дискретности переносов).

## Подключение в Unity

Импортёр (Фаза 0) читает `balance/era_1/*.csv` → генерирует `BuildingDef`, `ResourceDef`,
`RecipeDef`, `NeedDef`, `ProfessionDef`, `HomeDef` (SO для редактора + plain-классы для
SimCore). Поле `workers`/`inputs`/`outputs` парсится форматом `key:value;key:value`.
Строки, начинающиеся с `#`, — комментарии.
