Шесть месяцев соло-разработки: как сумасбродная затея выросла в платформу для ролевых игр с ИИ

Прокомментировать Просмотры: 5

Так сайт выглядит на 08.10.2026 — в тот момент, когда я пишу эту статью

Этой весной я взялся за разработку анонимного чата. Отчасти из скуки, отчасти потому, что ни одно из готовых решений на рынке меня не устраивало. В этой статье я расскажу, как менялась моя идея, с какими сложностями пришлось столкнуться, какие полезные приёмы работы с ИИ и кодом мне удалось открыть и чем всё это закончилось спустя полгода.

От первоначального замысла за это время почти ничего не осталось. Проект получил имя Katomu и дважды кардинально менял направление: сначала он превратился в площадку для текстовых ролевых игр с живыми людьми, затем сделал ставку на ролевые игры с ИИ‑персонажами, а дальше… кто знает. Боюсь даже предполагать, что подкинет мне фантазия в следующий раз. Проект я веду в одиночку (разве что с рекламой помогает друг), так что могу воплощать любые идеи, какие только захочу.

А так выглядела одна из первых версий. Разумеется, не самая ранняя: к тому моменту прошло около двух месяцев разработки.
А так выглядела одна из первых версий. Разумеется, не самая ранняя: к тому моменту прошло около двух месяцев разработки.

С чего всё началось

Немного предыстории: расскажу, как я вообще оказался в мире анонимных чатов. Я давний посетитель Nekto.me, и за долгие годы этот сайт, как и многие его собратья, изрядно меня разочаровал. Сценарий там практически всегда одинаков: заходишь, тебя случайным образом соединяют с собеседником, вы обмениваетесь парой фраз о насущном и, скорее всего, расстаётесь навсегда. Беда в том, что никто даже не пытается свести тебя с человеком, который хотя бы теоретически может оказаться тебе интересен. Тебя просто гоняют по случайным диалогам, попутно навязывая рекламу какого‑нибудь сомнительного продукта.

Поэтому я, как и положено мечтателю, решил, что смогу создать собственную, идеальную версию. Первый вариант назывался AnonChat (позже выяснилось, что название настолько банальное, что давно занято. Да и тогда это был скорее шуточный проект: я рассчитывал поиграться пару недель и бросить. Ну да, конечно). Цель у него была одна — практика в программировании. В тот момент я воспринимал проект исключительно как тренажёр, не более того. Но так увлёкся, что к концу апреля (а начал я в феврале) чат уже работал на удалённом сервере. Домен я подобрал под стать названию — такой же неоригинальный: ChatsChan.com (отсылка к другим сайтам с приставкой «Чан». Мне казалось, это будет забавное, слегка маргинальное местечко, но потом название показалось мне кринжовым, и в начале мая появился домен katomu.com. Само слово, кстати, взято из моего псевдонима: КАфка ТОМУра. Вот так вот :3)

Как всё пошло не по плану

Когда базовый функционал был готов, проект резко свернул в неожиданную сторону — и до сих пор я не могу чётко определить его вектор. Началось всё с простого наблюдения: самые интересные диалоги (по моему опыту) случаются вовсе не в разделе обычного общения и даже не в разделе флирта, а в ролевых играх. Там разговор не упирается ни в обсуждение повседневных дел, ни в интим. В ролевой двое сочиняют историю, и она вырастает в дружбу и целую совместно прожитую жизнь. (Не уверен, что на SE7ENе такое кого‑то интересует — я здесь новичок, — но всё же.) А это уже хорошая основа для собственного комьюнити, о котором я всегда мечтал. Делать ещё один анонимный чат мне вдруг показалось бессмысленным, и я сосредоточился на ролевых играх.

Сам я часто играл в ролевые и прекрасно знаю главную беду всех подобных сайтов: поиск достойного соигрока отнимает уйму времени (ну реально очень много). И дело не в людях, а в самом процессе поиска. Ты пролистываешь десятки анкет с разными интересами, пока не наткнёшься на того самого человека. Тогда я подумал: а что, если сделать наоборот? Разместить объявление о том, кого ты ищешь, и дождаться, пока нужный человек сам тебя найдёт. Объявить, так сказать, нужного человека в розыск.

Так появилась доска сюжетов (вдохновлялся я ЧатВдвоем), и проблем с ней хватало. Было неясно, как сделать так, чтобы объявление сразу связывало тебя с собеседником, а не превращалось в очередную анкету. И как удержать людей на сайте, чтобы они не разбегались по Telegram.

Поначалу мне казалось принципиально важным, чтобы люди играли именно на моей платформе. В итоге я отказался от этой идеи: моя задача — помочь найти партнёра, а где вы будете играть, решать вам. Поэтому к объявлению можно прикрепить свой Telegram, и тот, кто его увидит, напишет напрямую. А кто хочет остаться на сайте, просто откликается и сразу попадает в чат с автором. Кроме того, объявления дублируются в Telegram‑бота, чтобы их замечали и те, кого сейчас нет на сайте. (Вроде бы неплохой компромисс.)

Вокруг доски выросла и остальная часть сайта. Чат разделился на три раздела: обычная ролевая, ролевая с ИИ и флирт. Разделы с общением и флиртом я попросту убрал: они только мешали, потому что распределяли и без того небольшую аудиторию между режимами, а при маленьком онлайне это убивало сайт.

Раз акцент сместился на ролевые игры, пришлось расширять набор механик. Для
ролевиков важно, с кем именно ты переписываешься: одним по душе короткие реплики в пару строк, другие пишут по абзацу на пост, а порой и целые мини‑истории на несколько лимитов сообщений (в Telegram). Значит, обычный поиск мне не подходил. (Мы снова упираемся в проблему случайных собеседников.)

Так появились репутация и мастерство. Репутация растёт, когда общаешься нормально, и падает за грубость и жалобы, отсеивая совсем неадекватных людей от основной массы пользователей. Мастерство же оценивается по качеству постов: учитываются разнообразие лексики, количество знаков препинания, число предложений и многое другое. По совокупности этих метрик пользователю присваивается так называемый «класс письма» — от «однострочника» до «романиста». Подбор собеседников учитывает и репутацию, и мастерство, чтобы романист не попадал к однострочнику и наоборот.

P. S. Система получилась весьма любопытной, но на октябрь 2026 года себя так и не проявила: онлайн не набрал необходимой критической массы.

Доска сюжетов закреплена сбоку. Задумана она как новостная лента, только с сюжетами. На скриншоте она пуста.
Доска сюжетов закреплена сбоку. Задумана она как новостная лента, только с сюжетами. На скриншоте она пуста.
Так выглядят настройки. Лимиты на сообщения небольшие — особо не разгуляешься. Это тоже одна из серьёзных проблем объявлений: как сделать так, чтобы человек успел прочитать и присоединиться в
Так выглядят настройки. Лимиты на сообщения небольшие — особо не разгуляешься. Это тоже одна из серьёзных проблем объявлений: как сделать так, чтобы человек успел прочитать и присоединиться в

Момент, когда проект перестал помещаться в моей голове

Сайт я создаю с помощью ИИ. Скрывать это бессмысленно: опытные пользователи и так сразу поймут по дизайну. Идея родилась ещё в начале февраля, а активная разработка стартовала в марте, но под нормальный контроль версий я перенёс проект только в июне — и к тому моменту в нём было уже больше 150 тысяч строк. С тех пор набралось около полутора тысяч коммитов и почти миллион строк кода, половину из которых составляют тесты. Об этом чуть позже. (Данные с начала разработки по настоящий момент.)

Статичная страница, снятая с телефона. Раньше я планировал собирать людей в одно время с помощью расписания событий («Событие ещё не началось» висело пять дней в неделю, а доступ я открывал только вечером в пятницу и закрывал утром в понедельник). Идея была проста: я бросаю в Telegram клич вроде «Господа, в эту пятницу мы все играем, отговорки не принимаются» — и с радостью наблюдаю, как все дружно стекаются на сайт. Ожидания не оправдались, идея не прижилась..
Статичная страница, снятая с телефона. Раньше я планировал собирать людей в одно время с помощью расписания событий («Событие ещё не началось» висело пять дней в неделю, а доступ я открывал только вечером в пятницу и закрывал утром в понедельник). Идея была проста: я бросаю в Telegram клич вроде «Господа, в эту пятницу мы все играем, отговорки не принимаются» — и с радостью наблюдаю, как все дружно стекаются на сайт. Ожидания не оправдались, идея не прижилась..

Примерно тогда же в вопросах инфраструктуры пришлось повзрослеть. Сначала всё работало на SQLite, но я довольно быстро перебрался на PostgreSQL, потому что прежняя база была… медленной. (У меня нездоровая тяга оптимизировать всё под десятки тысяч пользователей, хотя на деле их едва наберётся даже тысяча.)
Появилась и резервная статичная версия сайта на случай, если основной сервер упадёт. (А падал он часто.)

Активности на сайте почти не было: в Telegram тогда сидело меньше сотни человек, не слишком заинтересованных в проекте. Что неудивительно — я набирал их в анонимном чате, буквально уговаривая вступить в канал. Кровью и потом я собрал тогда сотню человек и остановился. Но я всё равно решил заморочиться с оптимизацией. Зачем? Чёрт его знает. Мне казалось, что сайт обязан выдерживать нагрузку в тысячи посетителей, хотя заходили на него единицы.

Я всерьёз боялся, что сайт не справится с нагрузкой, которой не существовало. (И до сих пор не существует.) Из‑за этого я потратил несколько недель на кластеризацию: вместо одной копии приложения теперь работают две, и при обновлении сайт не падает. (К тому же таких копий можно запустить сколько угодно — были бы ядра на сервере.)

Звучит просто, но для чата это настоящая головная боль. Вот что пришлось решать:

Собеседники на разных копиях. Балансировщик закрепляет каждого пользователя за одной копией, но два участника одного диалога вполне могут оказаться на разных. Сообщения между копиями передаются через Redis: Socket.IO отправляет событие в общую «комнату», и его получают обе стороны, где бы они ни находились.

  • Состояние в памяти. Очередь поиска, комнаты и лимиты на спам раньше спокойно хранились в памяти процесса. При двух копиях каждая видела бы лишь свою половину данных, поэтому всё это переехало в Redis и базу.

  • Гонки. Две копии могли одновременно взять из очереди одного и того же человека и свести его сразу с двумя собеседниками. Пришлось сделать выбор из очереди атомарным: человека забирает тот, кто успел первым, а второй получает отказ. Кто первым встал, того и тапки.

  • Фоновые задачи. Очистка старых чатов и рассылки не должны выполняться дважды. Задачу берёт та копия, которая первой получила «аренду» в Redis, а сама задача написана так, чтобы повторный запуск ничего не ломал.

  • А если упадёт сам Redis? Это был самый неприятный вопрос. Обычные функции переходят в запасной режим через базу и работают медленнее, но работают. А всё, что связано с безопасностью и деньгами, наоборот, честно отказывает и сообщает об ошибке: лучше не позволить совершить действие, чем выполнить его дважды.

    Нагрузки, ради которой всё это затевалось, пока, откровенно говоря, нет. Но когда она придёт (а я надеюсь, что придёт), ничего переписывать не придётся.

    Как вы уже заметили, к своему детищу я отношусь довольно оптимистично, хотя за полгода в Telegram‑канал пришло всего около 250 человек. Но, как говорится, оптимизм — это недостаток информации. Так и вышло: подобных проектов оказалось великое множество, а значит, продвигать мой будет очень непросто. К тому же идея сайта исключительно с живыми людьми быстро исчерпала себя. Я сделал всё, что задумывал, но этого оказалось недостаточно, чтобы сайт стал по‑настоящему удобным местом для времяпрепровождения в виртуальных мирах.

Ролевые игры с ИИ

К тому же я стараюсь идти в ногу со временем, поэтому приоритеты пришлось пересмотреть ещё раз. К июню я и сам плотно засел в ботах для ролевых игр и понял, что они меня тоже не устраивают. (Да, если уж делать, то сразу во всех направлениях, которыми я недоволен. А недоволен я почти всем.)

Тогда я отчётливо осознал, в чём проблема живых игроков. У них своя беда: не всегда их найдёшь в два часа ночи, а история обрывается, как только человек решает, что сон важнее выдуманных сюжетов. Поэтому летом я добавил то, ради чего, честно говоря, сейчас всё и делается, — ролевые игры с ИИ‑персонажами. Ты создаёшь мир и героев с характером, предысторией и манерой речи, а дальше играешь сколько душе угодно.

Быстро выяснилось, что подключить нейросеть можно минут за двадцать, а вот сделать так, чтобы с ней было интересно играть, — это месяцы работы. Вот на что ушло больше всего времени.

Память. Модель видит только последние сообщения, поэтому всё важное из прошлого нужно хранить отдельно и подкладывать ей в нужный момент. Тут меня ждал неприятный сюрприз: бот начал зацикливаться и по кругу пересказывать одно и то же. Оказалось, он кормил сам себя: из его же ответа извлекался факт, по этому ответу строился поиск, находился тот же самый факт, и модель повторяла его снова. Разорвать этот круг удалось лишь несколькими правками сразу. Главный вывод: в «тупости» ИИ чаще виновата не модель, а то, что ей подают. (Хватит хейтить DeepSeek за глупость. Дело, скорее всего, не в нём, а в неправильном промпт‑инжиниринге.)

Время. В обычных ботах ночь может тянуться десять ходов подряд. В моих мирах есть часы: время движется от действий, а в подробных режимах персонажи устают, хотят есть и спать. (Хотя, признаю, пока это работает криво.) Часы дают и кое‑что ещё: по ним можно запускать события через определённые промежутки и точнее рассчитывать состояние героев. А чем точнее считается состояние, тем детальнее можно смоделировать характер. Правда, функционала для таких событий я пока не добавил. Работа в процессе.

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

Настройка персонажа. С одной стороны, параметры можно задать подробно, с другой — чего‑то будто не хватает. Сам не пойму чего. Позже хочу переделать это меню.
Настройка персонажа. С одной стороны, параметры можно задать подробно, с другой — чего‑то будто не хватает. Сам не пойму чего. Позже хочу переделать это меню.

Как я работаю в одиночку

Без помощников такой объём одному человеку не потянуть, поэтому значительную часть кода я пишу вместе с ИИ‑агентами. Точнее, чаще всего пишут они, а я лишь подбрасываю идеи реализации. Ведь Codex вроде бы уже претендует чуть ли не на сверхинтеллект, а логично решить задачу у него получается далеко не всегда. Да ещё и сломать по пути всё, что можно, ухитряется.

Поэтому главное, во что я вкладываюсь, — тесты. И тут я, пожалуй, перегнул палку: на них уже ушло больше 400 тысяч строк кода. По сути, большую часть времени ИИ пишет не новые функции, а страховку, чтобы не сломать уже готовое. Логично ли это? Не уверен. Друг утверждает, что я занимаюсь ерундой. Я же гордо продолжаю: сделал кусок проекта — залил его бетоном из тестов, чтобы точно знать, что никакой дурак не сломает его случайно. (Обычно в роли дурака выступаю я сам: даю предельно неразумной модели сверхсложную задачу, и она, разумеется, всё ломает. Удивительно, правда?)

Но и здесь не всё гладко: у такого подхода есть свои минусы. Случалось, что функцию уже починили, а тесты всё ещё ожидали старого поведения. Пару раз из‑за этого модель откатывала крупные изменения, лишь бы тесты снова позеленели. Выручал Git, да и происходило это на старых моделях, кажется, на GPT‑5.5. На новых я такого пока не замечал.

Зато урок получился ценный. Как‑то раз я исправил баг: тест зелёный, всё прекрасно. А в проде не работало вообще ничего. Выяснилось, что тест проверял функцию напрямую, а реальный код до неё даже не добирался. Тест был зелёным, а код за ним — мёртвым.

Так я открыл для себя мутационное тестирование. Идея проста: прежде чем доверять тесту, ты намеренно ломаешь в коде именно то, что он должен проверять, и запускаешь его. Упал — значит, тест работает. Не упал — он ничего не проверяет, и его нужно переписать. Это медленнее, зато тесты наконец говорят правду.

Итоги полугода

Соцсеть я так и не создал. Зато Katomu превратился в полноценный ролевой чат: от анонимной болтовни остались только ролевые игры — с живыми людьми и с ИИ. Соигрока сайт подбирает по репутации и по манере письма, а если ждать подбора не хочется, можно разместить сюжет на доске, и он заодно улетит в Telegram. Появились друзья, личные чаты и приложение для Android. Ролевые игры с ИИ помнят, что было раньше, живут по часам мира и сохраняют характер героев.

Ближайшее обновление — персонажи с собственными целями. Они будут не просто отвечать игроку, а сами к чему‑то стремиться, пробовать разные способы и не сдаваться после первой неудачи. Как это устроено, расскажу отдельно, когда механика выйдет.

Но ролевые игры — это только начало. Я хочу создать самостоятельную творческую площадку: место, где пишут фанфики и собственные истории, играют с людьми и с ИИ, а сыгранная история не теряется в переписке и может превратиться в рассказ. Раздел фанфиков уже ждёт своего часа, просто до него пока не дошли руки. И главное, я хочу собрать вокруг этого своё комьюнити — людей, которым интересно сочинять вместе.

Забавно, но в каком‑то смысле я вернулся к тому, с чего начинал. Мне хотелось, чтобы знакомство в анонимном чате не заканчивалось словом «пока». Похоже, для этого нужна была не лента с лайками, а общая история.

Если хотите посмотреть, что из этого выйдет, я рассказываю о проекте в Telegram‑канале: t.me/KatomuChat. А в комментариях буду рад вопросам — и про разработку в одиночку, и про то, как заставить ИИ не нести чушь.

 

Источник

Похожие статьи

Поиск по играм, новостям и статьям…

Введите не менее двух символов

Введите не менее двух символов