Когда мы запускали первый сезон «Мастер Игры» - облачного AI-гейммастера для настольных ролевых кампаний - самым большим сюрпризом стала не популярность сервиса, а та архитектурная хрупкость, которую выявили реальные нагрузки. Уже через две недели пиковые 300 000 одновременных сессий обрушили наше централизованное хранилище состояний, а задержки генерации нарратива временами превышали 4 секунды. При подготовке «Мастер Игры 2 сезон» мы полностью пересобрали платформу на принципах event sourcing, edge‑инференса и строгой изоляции доменов - и это превратило хрупкий монолит в распределённую систему, готовую к голосовому взаимодействию в реальном времени. Эта статья - техническая ретроспектива второго сезона: от перепроектирования data‑pipeline'ов до наблюдения за «удержанием сюжета» как ключевой бизнес‑метрики, since
«Мастер Игры» родился как внутренний эксперимент: мы хотели дать игровым группам AI‑ведущего, способного генерировать реплики NPC, описывать окружение и реагировать на действия персонажей в свободной форме. Первый сезон доказал жизнеспособность идеи, но одновременно вскрыл фундаментальные проблемы - сессии хранились в одной SQL‑базе с активными транзакциями, инференс выполнялся на кластере, удалённом от пользователей, а модификация правил требовала полного редеплоя. While but Когда мы анонсировали «Мастер Игры 2 сезон», мы поставили цель: каждая миллисекунда задержки не должна превышать психологический порог живого общения - примерно 200 мс для генерации текста и 120 мс для передачи голоса.
Сразу оговорюсь: здесь не будет маркетинговых обещаний. Я расскажу, какие инструменты мы внедрили, с какими компромиссами столкнулись и как observability‑стек помог предотвратить потерю крупных B2B‑клиентов в «чёрную пятницу» для RPG‑сообществ - день старта нового глобального сценария. Весь код back‑end'а написан на Go и Python, фронтальные SDK - на TypeScript, но архитектурные решения универсальны достаточно, чтобы применять их в любых event‑driven системах с требованиями реального времени.
От монолита «1 сезона» к распределённой системе «Мастер Игры 2 сезон»
Первая версия напоминала классический трёхзвенный монолит: REST API на Django, PostgreSQL для хранения игр и состояний, очередь Celery для задач инференса. Проблемы начались с того, что каждое действие игрока инициировало цепочку из 5-7 синхронных HTTP‑вызовов между сервисами; при среднем RTT 80 мс накопленная задержка регулярно переваливала за полсекунды. Since since Более того, база данных в режиме Read Committed создавала фантомные чтения, когда два NPC одновременно пытались занять один и тот же объект в игровом мире - конфликты решались откатами на уровне приложения, что приводило к «дёрганию» нарратива.
При проектировании «Мастер Игры 2 сезон» мы разделили систему на три изолированных домена: Command‑сторона для приёма действий, Query‑сторона для чтения состояний и AI‑Processing Unit для инференса. Коммуникация между ними выполнена через Apache Kafka с топиками, жёстко сегментированными по идентификатору кампании - это гарантирует порядок событий внутри одной сессии. Kafka Connect стримит изменения в материализованные представления на базе RocksDB, которые читает Query‑сервис через gRPC, обеспечивая p99 задержку чтения менее 5 мс, while Такой подход позволил масштабировать обработку команд горизонтально, не опасаясь состояния гонки, since читайте также: «Event‑driven архитектура на Go: patterns и anti‑patterns»
Самое сложное решение - отказаться от транзакционной гарантии ACID в пользу eventual consistency с компенсирующими действиями. Например, если игрок подбирает меч, а параллельно другой игрок пытается его выбросить, мы применили паттерн «Last Writer Wins» с векторами часов, но дополнили его семантической валидацией на стороне AI‑агента: он проверяет непротиворечи
.Need a Custom App Built?
Let's discuss your project and bring your ideas to life.
Contact Me Today →