Я сделал текстовый симулятор власти, где ИИ — рассказчик, но читерить ему запрещено

Привет, DTF. Я сделал «Вертикаль власти» — бесплатную текстовую игру, где ты правишь государством, сценой шоубиза, преступным кланом, технокорпорацией, футбольным клубом, космической программой, домом моды, светскими гостиными, дворцом монарха или фэнтези-королевством. Ходы пишутся обычным текстом — хоть «повышаю налоги», хоть «женю сына на дочери главы клана Медичи». Хочу рассказать, как она устроена и почему я не дал нейросети трогать цифры.

Проблема всех «ИИ-игр»

Все, кто игрался с текстовыми ИИ-приключениями (привет, AI Dungeon), знают их две беды:

  1. ИИ поддаётся. Напиши «я убеждаю дракона отдать золото» — и он отдаст. Напряжение умирает: нельзя проиграть тому, кто хочет тебе угодить.
  2. ИИ всё забывает. Убитый в прошлой главе злодей радостно входит в комнату.

Из-за этого такие игры разваливаются за полчаса. Я решил собрать гибрид: пусть нейросеть делает то, что умеет (понимать свободный текст и красиво рассказывать), а честность обеспечивает старый добрый детерминированный код.

Как это работает

В игре у тебя есть ресурсы (казна, репутация, стабильность) и семь фракций со своей лояльностью — от армии до прессы. Каждый ход:

  1. LLM-классификатор читает твой текст и отвечает строгим JSON: это одно из известных действий? Своё действие? Тогда — какое направление влияния на какие метрики, по шкале от −3 до +3. Не больше. Никаких «+100 к казне».
  2. Rule Engine — обычный PHP-код — переводит эти «направления» в числа в жёстких границах, применяет эффекты, клэмпит значения, проверяет условия победы и поражения. Он же решает, огрызнётся ли обиженная фракция и не прилетит ли «чёрный лебедь» (внезапное событие вне твоего контроля — от эпидемии до нежданного наследства).
  3. LLM-нарратор получает уже посчитанный результат и описывает его событиями мира: заголовками газет, слухами на улице, шёпотом в кулуарах. Ему промптом запрещено называть числа — цифры игрок смотрит отдельной кнопкой.

Итого нейросеть не может ни поддаться, ни завалить тебя несправедливо: у неё нет доступа к state. Она — рассказчик при жёстком гейммастере.

Память: убитый журналист не воскреснет

Вторую беду лечит «память партии». После каждого хода дешёвый LLM-вызов выдёргивает из нарратива факты: «журналистка Соколова убита», «генерал Быков враждебен». Это ложится в реестр сущностей, и дальше нарратор получает жёсткое правило: сущности со статусом «мёртв/распущен» больше не существуют — не говорят, не пишут статей, не приходят на приёмы. Плюс хроника ключевых событий, чтобы сюжет не противоречил сам себе.

Смешной побочный эффект: первый же тестер немедленно убил журналистку. Проверял память. Память выдержала.

Эпохи и анти-анахронизм

Миров десять, эпох на них — пятьдесят шесть, от античности до марсианской колонии. Самое весёлое — заставить нейросеть жить в выбранном времени. По умолчанию она тащит в 1905 год Telegram и смартфоны. Пришлось жёстко прибивать промптом игровой год («сейчас для тебя — 1937, а не год твоего обучения») и отдельным вызовом адаптировать подписи метрик под эпоху: «Бюджет, млрд ₽» превращается в «Казну в талантах», «СМИ и телеграм-каналы» — в «глашатаев и летописцев».

Что под капотом (коротко)

Laravel + PostgreSQL, LLM через шлюз с фейловером на резервные каналы (когда у ключа кончается лимит — партия не умирает, запрос уходит на запасной). Классификатор и нарратор — разные модели: классификации нужна дешёвая и строгая, нарративу — быстрая и живая. Ход обходится в копейки.

Поиграть

Бесплатно, без регистрации, партия начинается за две минуты:

Буду благодарен за фидбек — особенно интересно, на каком ходу вам стало скучно и почему. Это сейчас мой главный вопрос к геймдизайну.

4
1
1
1