# KPI — Game Design Document

## 1. Концепция

**KPI** — мрачная системная игра про офицера советского репрессивного аппарата.

Игрок управляет отделом в течение одного месяца. Сверху ему спускается план по количеству признаний и этапированных подозреваемых.

Главная задача:

**выполнить месячный KPI по посадкам и самому не попасть под подозрение системы.**

Игра не является детективом и не строится вокруг поиска объективной истины.

Игроку не обязательно выяснять, действительно ли человек виновен.

Для системы важен результат:

**задержанный → признание → этапирование → +1 KPI.**

При этом потенциальные подозреваемые являются конечным ресурсом партии. Человек может умереть, сбежать или быть отпущен, после чего потенциальная единица KPI может быть потеряна навсегда.

---

# 2. Основная идея

Игра строится вокруг конфликта:

**нужно быстро получать признания, но чрезмерное давление разрушает систему и повышает риск для самого офицера.**

Игрок постоянно балансирует между:

* выполнением плана;
* ограниченным количеством подозреваемых;
* вместимостью изолятора;
* количеством доступных агентов;
* временем;
* риском смерти задержанных;
* риском побега;
* доверием агентуры;
* подозрением начальства.

---

# 3. Формат партии

Одна партия длится **один месяц**.

Базово:

* 30 игровых дней;
* фиксированный KPI;
* фиксированное количество граждан;
* фиксированное количество агентов;
* ограниченный изолятор.

Все люди партии создаются на старте.

Во время партии игра не должна бесконечно генерировать новых граждан взамен потерянных.

Если человек:

* умер;
* сбежал;
* был окончательно отпущен;

он может быть потерян как потенциальная единица KPI.

Поэтому ошибка в начале месяца может привести к проигрышу в самом конце.

---

# 4. Детерминированный сценарий

На старте партии создаётся скрытый сценарий.

Сценарий определяет:

* всех граждан;
* агентов;
* офицера;
* связи между людьми;
* кто реально состоит в подполье;
* кто невиновен;
* здоровье;
* сопротивляемость;
* склонность к побегу;
* друзей;
* коллег;
* соседей;
* супругов;
* личные связи агентов;
* личные связи офицера;
* набор событий партии;
* исходы некоторых событий.

После начала партии скрытая реальность не должна произвольно переписываться.

В дальнейшем допускается использование небольшой локальной LLM для генерации сценария, биографий, связей и событий.

LLM может решить на старте:

* кто с кем связан;
* кто кого покрывает;
* какие события произойдут;
* какие персонажи реально виновны;
* кто является другом агента;
* кто является знакомым офицера.

После генерации сценарий фиксируется.

Игровые правила и последствия действий во время самой партии рассчитываются движком.

> Готовая инструкция (промпт) для локальной LLM лежит в отдельном файле
> **`LLM_PROMPT.md`**: формат JSON на выходе, таблицы всех полей
> (анкетные данные, скрытая реальность, улики, связи, факты, вещи, черты),
> конкретные инструкции генерации (сколько граждан, сколько подполья,
> пропорции улик и здоровья) и блок переменных, которые можно «подкручивать»
> под желаемую сложность партии. Подробности интеграции — в `SCENARIO.md` §13.

---

# 5. Игровой день

Основной игровой цикл идёт по дням.

Начало дня:

1. обрабатываются последствия предыдущего дня;
2. возвращаются агенты с заданий;
3. могут появиться новые задержанные;
4. происходят события в изоляторе;
5. поступают звонки начальства;
6. приходят ориентировки и новые указания.

После этого игрок свободно работает.

Он может:

* смотреть дела граждан;
* смотреть данные агентов;
* смотреть текущие задачи от начальства;
* допрашивать задержанных;
* отдавать задания агентам;
* ставить граждан под слежку;
* отправлять агентуру искать новых подозреваемых;
* принимать решения по новым задержанным;
* звонить начальству;
* завершить день.

---

# 6. Граждане

`Citizen` — базовая сущность человека.

Агенты и офицер также являются гражданами и наследуют базовые человеческие свойства.

У гражданина есть:

* ID;
* имя;
* возраст;
* пол;
* профессия;
* место работы;
* статус;
* здоровье;
* сопротивление;
* принадлежность к подполью;
* склонность к побегу;
* супруг/супруга;
* друзья;
* коллеги;
* соседи.

Связи хранятся непосредственно в полях гражданина.

На текущем этапе используются только:

* `spouse`;
* `friends`;
* `colleagues`;
* `neighbors`.

---

# 7. Скрытая информация

Офицер не знает всех реальных характеристик человека.

Например фактически гражданин может иметь:

* слабое здоровье;
* заболевание сердца;
* высокую склонность к побегу;
* связь с подпольем;
* друга среди агентов.

Но офицер может этого не знать.

Информацию необходимо получать через агентуру, допросы, наблюдение и события.

Пример:

пожилой мужчина имеет плохое здоровье, но офицер этого не знает.

Если сразу применять сильное давление, человек может умереть.

Если сначала поручить агенту собрать сведения, можно узнать о проблемах со здоровьем и выбрать менее рискованный способ получения признания.

---

# 8. Статусы гражданина

Основные игровые статусы:

* `UNKNOWN` — офицер ещё не знает человека;
* `KNOWN` — человек известен;
* `UNDER_SURVEILLANCE` — находится под наблюдением;
* `DETAINED` — находится в изоляторе;
* `CONFESSED` — дал признание;
* `TRANSFERRED` — этапирован, KPI засчитан;
* `RELEASED` — отпущен;
* `ESCAPED` — сбежал;
* `DEAD` — умер.

---

# 9. Изолятор

Изолятор имеет ограниченную вместимость.

Например:

**5 мест.**

Если все места заняты, нового человека нельзя просто добавить.

Игрок должен:

* отпустить кого-то;
* добиться признания;
* этапировать уже признавшегося;
* отказаться от нового задержанного.

Основной поток:

**задержание → изолятор → признание → этапирование → освобождение места.**

Если задержанный умер до этапирования:

* место освобождается;
* KPI не увеличивается;
* потенциальная единица плана потеряна.

---

# 10. Новые задержанные

Агенты могут приводить новых подозреваемых.

Когда агент докладывает о новом человеке, игрок выбирает:

### Отпустить

Человек не занимает место в изоляторе.

### Завести дело и задержать

Человек помещается в изолятор, если есть свободное место.

### Отпустить под слежку

Человек остаётся на свободе, но к нему прикрепляется агент.

### Взять на заметку

Человек остаётся в мире и может всплыть позже.

---

# 11. Агентура

У игрока есть ограниченное количество агентов.

Агент может выполнять только одно полноценное задание одновременно.

Например агент может:

* искать новых подозреваемых;
* следить за конкретным гражданином;
* собирать сведения;
* искать дополнительные материалы.

Если агент занят слежкой, он в это время **не приводит новых задержанных**.

Это создаёт прямую цену любого задания.

---

# 12. Слежка

Игрок самостоятельно задаёт длительность слежки.

Короткая слежка:

* небольшой шанс получить информацию;
* низкий риск обнаружения.

Средняя слежка:

* выше шанс обнаружить связи или доказательства;
* умеренный риск.

Длинная слежка:

* высокий шанс получить важную информацию;
* высокий риск, что человек заметит наблюдение.

Если реальный участник подполья замечает слежку, он может сбежать.

После побега человек может быть потерян до конца партии.

Таким образом:

**арестовать сейчас = сохранить потенциальную палку;**

**следить = рискнуть одной палкой ради дополнительных доказательств или выхода на новых людей.**

---

# 13. Поиск подозреваемых

Агентов можно отправлять искать новых подозреваемых по районам и объектам города.

В будущем карта должна содержать, например:

* заводы;
* вокзал;
* железную дорогу;
* рынок;
* площади;
* жилые районы;
* университет;
* больницы;
* административные здания.

Игрок выбирает место и отправляет туда агентуру.

Результатом могут стать:

* новый подозреваемый;
* несколько подозреваемых;
* новые данные по уже задержанным гражданам;

---

# 14. Реакция населения

Население реагирует на активность репрессивного аппарата.

Если агентов слишком много или в районе постоянно происходят задержания:

* люди реже выходят на улицы;
* избегают общественных мест;
* меньше разговаривают с незнакомыми;
* меняют маршруты;
* стараются не попадаться агентуре.

В результате чрезмерное давление может уменьшить количество новых задержанных.

---

# 15. Допрос

Главная задача допроса:

**получить признание и оставить задержанного в живых до этапирования.**

Способы получения признания:

### Доказательства

Предъявить человеку достаточно сильный материал.

Самый безопасный путь, но требует времени и работы агентуры.

### Обман

Убедить человека, что:

* сообщники уже признались;
* у следствия есть больше доказательств, чем на самом деле;
* исход дела уже предрешён.

### Шантаж

Использовать:

* супруга;
* друзей;
* работу;
* другие личные обстоятельства.

### Сила

Быстрый способ сломить сопротивление.

Но увеличивает:

* риск смерти;
* недоверие агентуры;
* страх;
* подозрение к офицеру.

---

# 16. Признание

Само расследование истины не является целью игры.

Для игрового KPI важен факт признания.

После признания игрок может этапировать человека.

После этапирования:

* гражданин покидает изолятор;
* освобождается место;
* `KPI +1`.

---

# 17. Реальная виновность

У гражданина существует скрытая реальная принадлежность к подполью.

Игрок её напрямую не видит.

Можно получить признание:

* у настоящего участника подполья;
* у полностью невиновного человека.

Для KPI оба случая дают одинаковый результат.

Реальная статистика может быть показана игроку только после окончания партии.

---

# 18. Смерть задержанного

Задержанный может умереть:

* от применения силы;
* от общего ухудшения здоровья;
* от болезни;
* от холода;
* в результате отдельного события;
* покончить с собой.

Если он умер до этапирования:

**KPI не засчитывается.**

Человек потерян.

Это делает чрезмерное давление экономически невыгодным даже для игрока, который не заинтересован в судьбе граждан.

---

# 19. Агенты могут обманывать

Агент не является абсолютно надёжным источником.

Он может:

* покрывать друга;
* покрывать супруга;
* защищать соседа;
* защищать коллегу;
* скрывать собственную связь;
* искажать информацию из страха;
* говорить офицеру то, что тот хочет услышать.

Игрок может начать подозревать собственных агентов.

Например агент утверждает, что по гражданину ничего нет.

Позже игрок выясняет, что этот гражданин — его близкий друг.

Игра не должна автоматически говорить:

**«агент соврал».**

Игрок делает вывод самостоятельно.

---

# 20. Связи агентов

Поскольку `Agent` наследует `Citizen`, агент также имеет:

* супруга;
* друзей;
* коллег;
* соседей.

Поэтому среди подозреваемых может оказаться:

* друг агента;
* супруг агента;
* сосед агента;
* коллега агента.

Это может изменить его поведение.

---

# 21. Связи офицера

`Officer` также наследует `Citizen`.

Поэтому среди граждан может оказаться:

* друг офицера;
* супруг;
* сосед;
* бывший знакомый или коллега, если в будущем добавим соответствующую связь.

Механически такой человек остаётся обычным гражданином.

Игра просто создаёт личный конфликт для игрока.

---

# 22. Репутация офицера

У офицера есть репутация перед начальством.

Высокая репутация может позволить:

* запросить дополнительных агентов;
* получить определённые уступки;
* снизить последствия отдельных проблем.

Дополнительных агентов можно получать через звонок начальству.

Количество агентов не должно свободно увеличиваться без ограничений.

---

# 23. Подозрение к офицеру

Система отслеживает самого игрока.

Подозрение может расти из-за:

* невыполнения плана;
* слишком хорошей статистики;
* слишком высокой смертности;
* постоянного силового давления;
* подделки статистики;
* жалоб;
* странных решений;
* показаний собственных агентов.

Слишком хорошие показатели также подозрительны.

Если отдел резко превосходит нормальные результаты, начальство может начать проверку.

---

# 24. Подделка статистики

Игрок может подрисовать результаты.

Например:

реально:

**17 / 20**

в отчёте:

**20 / 20**

Это позволяет формально выполнить план.

Но значительно повышает подозрение.

Если проверки обнаружат расхождения или агент сдаст офицера, партия может закончиться поражением.

---

# 25. Начальство

Начальство взаимодействует с игроком через телефон.

Возможны:

* новый KPI;
* увеличение плана;
* уменьшение плана;
* требование закрыть определённое число дел к конкретному дню;
* ориентировки;
* информация о предполагаемых террористах;
* приоритет по конкретному заводу или району;
* требование заняться конкретным человеком;
* проверка статистики.

---

# 26. События

Каждый день может состоять из набора событий.

Примеры:

* агент приводит нового задержанного;
* агент возвращается со слежки;
* гражданин умер ночью;
* гражданин покончил с собой;
* подозреваемый сбежал;
* начальство звонит;
* появляется новая ориентировка;
* в разработку попадает друг офицера;
* в разработку попадает друг агента;
* задержанный оказывается тяжело болен;
* агент начинает скрывать информацию;

Часть событий может быть заранее определена сценарием.

Часть может зависеть от действий игрока.

---

# 27. Конечный пул людей

Это фундаментальное правило дизайна.

**Граждане не являются бесконечным процедурным ресурсом.**

Сценарий содержит конечное количество людей.

Поэтому:

* смерть уменьшает доступный пул;
* побег уменьшает доступный пул;
* неудачная слежка может уменьшить доступный пул;
* неправильное освобождение может уменьшить доступный пул.

К концу месяца может возникнуть ситуация:

> KPI: 18 / 20
> в изоляторе: 1
> известных свободных подозреваемых: 2
> остальные уже умерли, сбежали или были потеряны.

И одно неправильное решение может сделать победу математически невозможной.

---

# 28. Условия победы

Игрок побеждает только если одновременно:

1. месяц закончился;
2. KPI выполнен;
3. уровень подозрения к офицеру остаётся допустимым.

Недостаточно просто выполнить план.

---

# 29. Условия поражения

Партия заканчивается поражением, если:

### KPI не выполнен

Закончился месяц, а план не выполнен.

### Система забрала офицера

Подозрение достигло критического уровня.

### Агент предал офицера

Агент сообщил о:

* фальсификациях;
* подделке статистики;
* незаконных манипуляциях;
* других компрометирующих действиях.

### Офицер арестован

Сценарное завершение при высокой степени подозрения.

### Офицер покончил с собой

На поздней стадии угрозы в кабинете может появиться пистолет.

Игрок получает возможность самостоятельно закончить историю.

---

# 30. Финальная статистика

После окончания партии можно раскрыть объективную реальность.

Например:

* этапировано: 20;
* реально состояли в подполье: 4;
* невиновных этапировано: 16;
* умерло до признания: 3;
* сбежало: 2;
* отпущено: 5;
* настоящих подпольщиков осталось на свободе: 3;
* агентов, скрывавших информацию: 1.

Во время партии игрок эти данные не знает.

---

# 31. Финальный визуальный стиль

Финальная игра планируется как **2D pixel-art game**.

Главный экран — кабинет офицера.

Основные физические элементы интерфейса:

* папка дел граждан;
* отдельная папка агентов;
* телефон;
* карта;
* ключи;
* документы;
* другие сюжетные предметы.

Интерфейс должен ощущаться как физическое рабочее место, а не как стандартная management-dashboard игра.

Кабинет должен постепенно визуально меняться:

* растут стопки дел;
* появляются новые документы;
* увеличивается давление;
* чаще звонит телефон;
* появляются признаки интереса системы к самому офицеру.

---

# 32. Текущий этап разработки

Сейчас разрабатывается **headless prototype**.

Никакой графики.

Никаких сцен.

Никакого pixel art.

Управление через CLI.

Пример:

```text
> start day
> state
> citizens
> detainees
> end day
```

Цель текущего этапа — доказать работоспособность игрового цикла.

---

# 33. Текущий стек

* Godot;
* GDScript;
* запуск в `--headless`;
* CLI как временный интерфейс.

Графика будет добавляться только после проверки механик.

---

# 34. Архитектура прототипа

Не переусложнять архитектуру.

Основные классы:

### `Citizen`

Базовый класс человека.

### `Agent extends Citizen`

Агент.

Дополнительные свойства:

* состояние агента;
* доверие;
* страх;
* честность;
* позднее текущее задание.

### `Officer extends Citizen`

Игровой персонаж.

Дополнительные свойства:

* репутация;
* подозрение.

### `GameState`

Хранит текущее состояние партии:

* день;
* KPI;
* изолятор;
* граждан;
* агентов;
* офицера;
* статус партии.

### `Scenario`

Создаёт стартовый сценарий.

На текущем этапе сценарий описывается статически через:

```gdscript
Citizen.new(...)
Agent.new(...)
Officer.new(...)
```

Не использовать промежуточные `Dictionary`, JSON или фабрики без необходимости.

### `GameLoop`

Обрабатывает течение игровых дней и правила партии.

---

# 35. Правила реализации

Для текущего прототипа:

1. не создавать лишние классы и абстракции;
2. один класс должен соответствовать понятной игровой сущности;
3. не создавать отдельную сущность изолятора — это часть `GameState`;
4. не создавать отдельную сущность KPI — это часть `GameState`;
5. связи хранятся непосредственно в `Citizen`;
6. не создавать отдельные Relationship-классы;
7. сценарий описывается непосредственно объектами;
8. игровые качественные характеристики в сценарии должны задаваться через enum;
9. не использовать непонятные магические коэффициенты в сценарии;
10. один шаг разработки = одна небольшая законченная механика.

---

# 36. Enum-подход

Статические сценарии должны легко читаться человеком.

Хорошо:

```gdscript
Citizen.Health.WEAK
Citizen.Resistance.HIGH
Citizen.EscapeTendency.LOW
Citizen.UndergroundStatus.MEMBER
Citizen.Workplace.FACTORY
```

Плохо:

```gdscript
35
0.72
3
true
```

Числа используются только там, где значение действительно числовое:

* ID;
* возраст;
* KPI;
* дни;
* вместимость;
* ссылки на ID других людей.

---

# 37. Главная проверяемая гипотеза

Headless-прототип должен ответить на один вопрос:

> **Интересно ли управлять конечным пулом людей, ограниченным изолятором и агентами так, чтобы к концу месяца получить необходимое число признаний и самому не попасть под систему?**

До доказательства этой гипотезы не следует тратить много времени на:

* графику;
* анимации;
* сложную генерацию;
* большую LLM;
* диалоговую систему;
* полировку интерфейса.

Сначала должна работать сама игра.