<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru"><title>LivingPW devlog (ru)</title><link href="https://livingpw.com/ru/devlog/"/><link rel="self" href="https://livingpw.com/ru/devlog/feed.xml"/><id>https://livingpw.com/ru/devlog/</id><updated>2026-10-26T00:00:00Z</updated><author><name>Макс</name></author><entry><title>Как устроены ИИ-игроки</title><link href="https://livingpw.com/ru/devlog/how-the-ai-players-work/"/><id>https://livingpw.com/ru/devlog/how-the-ai-players-work/</id><updated>2026-10-26T00:00:00Z</updated><author><name>Макс</name></author><summary>Технический обзор для тех, кто любит заглядывать под капот: клиенты на Python, трёхслойный мозг, общий хост, часовая телеметрия с A/B и честный список того, что пока не работает.</summary><content type="html">&lt;p&gt;Это запись для тех, кто любит заглядывать под капот. Я постараюсь писать так, чтобы не потерять тех, кто не читает код, но без технических деталей рассказ не получится. Каждое число ниже я измерял сам, а то, чего не знаю, так и помечено.&lt;/p&gt;
&lt;h2 id=&quot;задача&quot;&gt;Задача&lt;/h2&gt;
&lt;p&gt;В мире должны жить сотни персонажей, которые выглядят как игроки: качаются, торгуют, болтают, собираются в пати. Всё это должно помещаться на один ноутбук (12 ГБ памяти под систему разработки плюс 4 ГБ под виртуальную машину с сервером) и стоить недорого. Бюджет на языковые модели для всего флота я ставлю себе порядка десяти долларов в месяц. Это цель, а не достигнутый результат.&lt;/p&gt;
&lt;h2 id=&quot;клиент-а-не-скрипт-внутри-сервера&quot;&gt;Клиент, а не скрипт внутри сервера&lt;/h2&gt;
&lt;p&gt;Каждый ИИ-игрок это обычный клиент игры без картинки: программа на Python (asyncio), которая говорит с сервером тем же сетевым протоколом, что и настоящий клиент. Для сервера это игрок с логином и персонажем, у которого нет никаких привилегий. Протокол я собирал из трёх источников: описания сообщества и открытые проекты, собственные перехваты трафика и статический разбор серверных программ. Что-то в нём я мог понять неправильно, поэтому боты проверяются на реальном сервере, а не на моих предположениях.&lt;/p&gt;
&lt;h2 id=&quot;мозг-в-три-слоя&quot;&gt;Мозг в три слоя&lt;/h2&gt;
&lt;p&gt;Идея в том, чтобы дорогие решения принимал как можно реже.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Рефлексы&lt;/strong&gt; на каждом тике: выпить зелье, отступить, сменить цель. Это обычный код, он ничего не стоит.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Очередь дел.&lt;/strong&gt; У каждого бота есть очередь дел с приоритетами по «полосам необходимости»: выжить, восстановиться, выполнить обязательства (просьба игрока, роль в группе), обслужить себя (сумки, ремонт, зелья), заниматься прогрессом (культивация, квесты, подземелья, снаряжение) и только потом общаться и отдыхать. Оценщики смотрят на состояние бота и добавляют или убирают дела, наверху очереди работает самое важное. Это тоже код.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Языковая модель&lt;/strong&gt; подключается там, где нужен разговор или неоднозначный выбор: имена и характеры, реплики в чате, редкие «жизненные» решения. Для самых близких персонажей задуман полноценный «ум» с памятью, который просыпается по событиям, но это пока дизайн, а не реальность в мире.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Сегодня почти всё в мире делает код. Языковая модель заранее пишет имена, истории и банки реплик, причём в нескольких голосах (сдержанный, шутник, ворчун и так далее). Вторым вызовом дешёвая модель оценивает написанное, а детерминированный фильтр отсекает мусор и слова, которые выдают бота. Живых вызовов модели во время игры мало, и каждый вызов записывается и считается.&lt;/p&gt;
&lt;h2 id=&quot;один-хост-на-всех-ботов&quot;&gt;Один хост на всех ботов&lt;/h2&gt;
&lt;p&gt;Сначала каждый запуск бота тянул за собой процесс Python с загруженными данными игры: около 0,6 ГБ до появления первого бота. Сотни таких процессов не поместились бы в память, поэтому я сделал единый «хост ботов»: долгоживущий процесс и несколько рабочих, в каждом из которых живёт до 40 ботов на общих данных. Бот внутри рабочего процесса стоит примерно 20 МБ и 0,011 ядра процессора, а когда я сам запускаю тяжёлую игру на этом же ноутбуке, примерно 0,027. Если рабочий процесс начинает отставать, хост сам отключает часть ботов.&lt;/p&gt;
&lt;p&gt;Ещё хост решает вторую задачу: боты работают только на выпущенных версиях кода. Версия фиксируется командой выкладки, и рабочие переезжают на неё. То, что я только что поправил в рабочей копии, до живого мира не доезжает, пока я этого не решу.&lt;/p&gt;
&lt;h2 id=&quot;часовая-телеметрия-и-a-b&quot;&gt;Часовая телеметрия и A/B&lt;/h2&gt;
&lt;p&gt;Каждый бот каждые две секунды пишет, что он делает: где стоит, на каком шаге, куда идёт. Раз в час отдельная проверка складывает это в отчёт: здоровье сервера и ошибки, темп прокачки по классам, сколько ботов застряло, как выглядит чат, что происходит в экономике. Отдельный наблюдатель заходит в стартовые зоны как новичок и ставит оценку от 0 до 100 тому, насколько мир обжит. Эта оценка выведена на странице &lt;a href=&quot;/ru/world/&quot;&gt;«Живой мир»&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Новые возможности я включаю не на всех. В прошлой репетиции модуль походов в подземелья работал в пяти шардах из десяти, и по отчёту видно, что он даёт. Если польза не видна, модуль не остаётся.&lt;/p&gt;
&lt;h2 id=&quot;что-пока-не-работает&quot;&gt;Что пока не работает&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Пати по ролям.&lt;/strong&gt; Бот может позвать недостающую роль, жрец из другой части системы откликается, но группа, которая стабильно убивает боссов, у меня пока не получилась. Это главный долг.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Рынок.&lt;/strong&gt; Лавки открывать умеют, но живой экономики с настоящими ценами пока нет.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Чат.&lt;/strong&gt; Реплики лучше, чем были: 88 % шаблонных строк в прошлой популяции меня не устраивали. Но повторы и однообразие никуда не делись, и новичка встречают не всегда.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Память.&lt;/strong&gt; Рабочие процессы разрослись, и потолок в 400 сейчас не держится, пока я это чиню.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Живая смена эпох.&lt;/strong&gt; Собрана и проверена на файлах, но на работающем мире не применялась.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Английский.&lt;/strong&gt; Пока ИИ-игроки говорят по-русски.&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;как-я-проверяю-что-не-сломал-мир&quot;&gt;Как я проверяю, что не сломал мир&lt;/h2&gt;
&lt;p&gt;Автотесты (около 470 файлов, порядка 8 000 проверок) гоняются перед выпуском версии. Выпуск версии — отдельный шаг, а не побочный эффект. Дальше работает часовая телеметрия и сравнение A/B, а решение «пускать в мир» принимаю я. Проверки на каждый коммит (CI) пока нет, я её сейчас настраиваю.&lt;/p&gt;
&lt;p&gt;Если что-то из этого вам хочется обсудить, я в &lt;a href=&quot;/ru/community/&quot;&gt;сообществе&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Ночная репетиция: сотни ИИ-игроков приходят в стёртый мир</title><link href="https://livingpw.com/ru/devlog/launch-rehearsal/"/><id>https://livingpw.com/ru/devlog/launch-rehearsal/</id><updated>2026-10-26T00:00:00Z</updated><author><name>Макс</name></author><summary>Я стёр тестовый мир, включил стартовые рейты и запустил приход новой популяции. Цифры, порядок действий и чему меня научила прошлая популяция.</summary><content type="html">&lt;p&gt;В ночь на 26 октября я провёл первую репетицию запуска: стёр тестовый мир и запустил в него новое население из ИИ-игроков. Ниже цифры и порядок действий. Всё, что названо измеренным, я действительно измерял.&lt;/p&gt;
&lt;h2 id=&quot;вайп&quot;&gt;Вайп&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Остановил мир, сделал холодную копию и снимок виртуальной машины, потом удалил около 1 450 тестовых аккаунтов и персонажей прошлых популяций. Девять служебных аккаунтов оставил.&lt;/li&gt;&lt;li&gt;Моих личных персонажей выгрузил в файлы, они лежат в копии. Снимок позволяет откатить всё назад.&lt;/li&gt;&lt;li&gt;Первая попытка споткнулась на первом шаге и ничего не успела изменить: ошибка сидела в моём собственном инструменте. Я исправил её и добавил тест.&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;стартовые-рейты&quot;&gt;Стартовые рейты&lt;/h2&gt;
&lt;div class=&quot;table-scroll&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Что&lt;/th&gt;&lt;th&gt;Значение&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Опыт за мобов&lt;/td&gt;&lt;td&gt;×2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Опыт за квесты&lt;/td&gt;&lt;td&gt;×2,5&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SP&lt;/td&gt;&lt;td&gt;×3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Деньги&lt;/td&gt;&lt;td&gt;×2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Дроп&lt;/td&gt;&lt;td&gt;×2&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Те же числа показывает страница &lt;a href=&quot;/ru/world/&quot;&gt;«Живой мир»&lt;/a&gt;: она берёт их прямо с сервера.&lt;/p&gt;
&lt;h2 id=&quot;приход-ии-игроков&quot;&gt;Приход ИИ-игроков&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Заготовлено 3 500 личностей. Первым 400 имя, историю и манеру речи написала языковая модель. Это обошлось примерно в два цента.&lt;/li&gt;&lt;li&gt;Приходы начались в 22:28. Ночью заходит около 90 новых персонажей в час, потом по 24–30 в час.&lt;/li&gt;&lt;li&gt;Потолок по плану около 400 одновременно: 10 «шардов» по 40 ботов. Это предел одного ноутбука, а не маркетинговая цифра.&lt;/li&gt;&lt;li&gt;Живых игроков, кроме меня, пока нет.&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;эксперимент&quot;&gt;Эксперимент&lt;/h2&gt;
&lt;p&gt;В пяти шардах из десяти включён модуль походов в подземелья, в остальных выключен. Так я увижу, что он даёт, и оставлю только то, что работает. Такие сравнения буду проводить и дальше.&lt;/p&gt;
&lt;h2 id=&quot;чему-меня-научила-прошлая-популяция&quot;&gt;Чему меня научила прошлая популяция&lt;/h2&gt;
&lt;p&gt;Перед вайпом я разобрал, как жили прошлые 320–400 ИИ-игроков. Нашлось такое:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;около 26 % времени уходило на квесты, которые так и не выполнялись;&lt;/li&gt;&lt;li&gt;398 из 400 персонажей носили шаблонные имена;&lt;/li&gt;&lt;li&gt;не была открыта ни одна лавка;&lt;/li&gt;&lt;li&gt;88 % реплик в чате были шаблонными;&lt;/li&gt;&lt;li&gt;раздача званий в кланах падала с ошибкой;&lt;/li&gt;&lt;li&gt;подземелья съедали 14 % времени и давали 1,7 % опыта.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Репетиция проверяет исправления: имена и характеры от языковой модели, новый чат, лавки, починенные кланы.&lt;/p&gt;
&lt;h2 id=&quot;как-я-решаю-что-готово&quot;&gt;Как я решаю, что готово&lt;/h2&gt;
&lt;p&gt;Каждый час автоматическая проверка собирает здоровье сервера, темп классов, качество чата, ошибки и экономику. Моя планка для первого показа людям: сутки работы при ~400 онлайн без падений, каждый класс не медленнее 60 % от лучшего на уровнях 1–40, застрявших меньше 5 % времени, групповые походы по ролям подтверждены, клановые ранги работают, лавки и аукцион ожили. Пока это планка, а не результат.&lt;/p&gt;
&lt;h2 id=&quot;обновление-от-26-октября&quot;&gt;Обновление от 26 октября&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Кланы.&lt;/strong&gt; Починил раздачу званий и проверил вживую: клан создаётся, четверо получают звания, одного понижают, он выходит. Ошибка сидела в том, как бот понимал ответ сервера с кодом 109 (в этом звании не осталось мест).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Наблюдатель-новичок.&lt;/strong&gt; Я завёл автоматического персонажа, который каждый час заходит в стартовые зоны и ставит миру оценку обжитости. Первые заходы дали 80 в стартовой зоне людей и около 60 у эльфов и зооморфов: там было пусто и тихо. Последний заход в зону людей дал 97 из 100. Это один наблюдатель в одном месте, поэтому смотрю на оценку как на термометр.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Память.&lt;/strong&gt; Рабочие процессы с ботами съедают больше памяти, чем на прошлых замерах. Пока я это чиню, население держу ниже 400.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Живое число игроков всегда на странице &lt;a href=&quot;/ru/world/&quot;&gt;«Живой мир»&lt;/a&gt;.&lt;/p&gt;</content></entry><entry><title>Привет. Зачем мне всё это</title><link href="https://livingpw.com/ru/devlog/hello/"/><id>https://livingpw.com/ru/devlog/hello/</id><updated>2026-10-25T09:00:00Z</updated><author><name>Макс</name></author><summary>Кто я, почему я строю этот мир, как с ним работают рои ИИ-агентов и что из задуманного уже работает, а что нет.</summary><content type="html">&lt;p&gt;Привет. Это первая запись девлога, и начать я хочу с главного: зачем всё это.&lt;/p&gt;
&lt;h2 id=&quot;я-хочу-в-это-играть&quot;&gt;Я хочу в это играть&lt;/h2&gt;
&lt;p&gt;Если совсем коротко, то потому, что я сам хочу в это играть. Perfect World забрал у меня много вечеров, а потом началась взрослая жизнь, и «сходить в данж» превратилось в «найти того, кто сходит в данж». Я играл Воином и Жрецом одновременно, в двух окнах, потому что напарников по вечерам не было. Это работает, но удовольствия от такой игры меньше, чем хотелось бы.&lt;/p&gt;
&lt;p&gt;Поэтому я делаю мир, в котором всегда есть с кем поиграть. И я хочу, чтобы он был не «сойдёт для тестов», а безумно хорошим: чтобы каждый вечер хотелось зайти, а не заставлять себя. Из этого желания растёт всё остальное, и поэтому разработка у меня не останавливается.&lt;/p&gt;
&lt;p&gt;Ещё одна причина, чуть более личная. Свой онлайн-мир я хотел сделать с детства, это моя давняя мечта. Сначала я назвал этот сервер своим первым бизнесом. Поправка от 27 октября: я отношусь к нему как к хобби и мечте, которые позволяет оплачивать основная работа. Хочу поделиться миром, в котором самому интересно играть, покрывать расходы и сохранить бесплатный доступ, если добровольной поддержки хватит. Сейчас это направление и возможность подписки описаны в &lt;a href=&quot;/ru/support/&quot;&gt;принципах поддержки&lt;/a&gt;; заметки о разработке ниже относятся к 25 октября.&lt;/p&gt;
&lt;h2 id=&quot;кто-я&quot;&gt;Кто я&lt;/h2&gt;
&lt;p&gt;Днём я специалист по кибербезопасности в компании, которую называть не буду. Сервер для меня — вторая работа, а начиналась она как хобби: поднять сервер, залезть внутрь, понять, как он устроен. Серверы Perfect World я раньше не администрировал, поэтому почти всё здесь я делаю впервые и ошибаюсь вслух. Эти ошибки я буду описывать в девлоге.&lt;/p&gt;
&lt;p&gt;Работа в безопасности повлияла на то, как я строю проект. Я не верю словам, в том числе своим, поэтому сначала измеряю, а уже потом пишу. Так же устроен и сайт: каждая цифра идёт с сервера, у каждой возможности честная пометка, а там, где данных нет, стоит «нет данных», а не красивый ноль.&lt;/p&gt;
&lt;h2 id=&quot;как-с-этим-работают-агенты&quot;&gt;Как с этим работают агенты&lt;/h2&gt;
&lt;p&gt;Одному такой проект не потянуть. Поэтому над кодом у меня работают рои ИИ-агентов: они пишут код и тесты, разбирают отчёты, ищут причины багов. Что строим, в каком порядке и что попадёт в мир, решаю я. Ничего не уходит в живой мир, пока я не посмотрел на результат своими глазами. Агент предлагает, решаю я.&lt;/p&gt;
&lt;p&gt;Чтобы эта скорость не превращалась в хаос, я стараюсь работать как нормальная инженерная команда:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Автотесты.&lt;/strong&gt; В репозитории около 470 файлов с тестами, порядка 8 000 проверок. Их гоняют перед релизами.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Релизы по версиям.&lt;/strong&gt; Боты запускаются только на выпущенных, зафиксированных версиях кода. «Залил и посмотрел на живых» у меня не работает.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Телеметрия и A/B.&lt;/strong&gt; Каждый час автоматика собирает здоровье сервера, темп прокачки классов, качество чата и экономику. Новое включаю на части ботов и сравниваю с остальными.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Безопасность.&lt;/strong&gt; Пакет сервера я не писал, поэтому первым делом сделал его аудит: нашёл слабые пароли по умолчанию и опасную панель управления. Пока всё закрыто внутри моей сети. Перед тем как пускать чужих людей, пройду отдельный список исправлений: он уже составлен.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Бэкапы.&lt;/strong&gt; Копии мира делаются каждый час, и я проверил, что копия разворачивается в отдельную папку. Полную репетицию восстановления живого мира ещё проведу.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Чего пока нет, так это проверки на каждый коммит (CI). Её я сейчас настраиваю. До тех пор тесты запускаю сам перед каждой выкаткой.&lt;/p&gt;
&lt;h2 id=&quot;что-работает-а-что-нет&quot;&gt;Что работает, а что нет&lt;/h2&gt;
&lt;div class=&quot;table-scroll&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Что&lt;/th&gt;&lt;th&gt;Состояние&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Мир и ИИ-игроки&lt;/td&gt;&lt;td&gt;работает. Потолок, который я измерил на своём ноутбуке, около 400 одновременно. Сколько сейчас, видно на странице «Живой мир»&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Кланы с рангами&lt;/td&gt;&lt;td&gt;работает. Раздача званий падала с ошибкой, я исправил и проверил вживую&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Мировой чат&lt;/td&gt;&lt;td&gt;работает по-русски, английский в разработке&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Пати по ролям&lt;/td&gt;&lt;td&gt;в разработке. ИИ-игрок зовёт недостающую роль, и жрец откликается. Босса такой группой пока не убили&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Лавки и аукцион&lt;/td&gt;&lt;td&gt;в разработке. Лавки открывать умеют, живого рынка пока нет&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Смена эпох без вайпа&lt;/td&gt;&lt;td&gt;в разработке. Проверена на файлах, на живом мире не применялась&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Живые игроки, оплата, арендованный сервер&lt;/td&gt;&lt;td&gt;пока нет&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h2 id=&quot;что-дальше&quot;&gt;Что дальше&lt;/h2&gt;
&lt;p&gt;Сначала мир, потом всё остальное. Пока мир не ощущается живым, я никого в него не зову. В следующей записи расскажу про &lt;a href=&quot;/ru/devlog/launch-rehearsal/&quot;&gt;ночную репетицию запуска&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Если вам интересно, чем это кончится, &lt;a href=&quot;/ru/community/&quot;&gt;заходите в сообщество&lt;/a&gt; или просто оставьте контакт: я напишу, когда начнутся тесты.&lt;/p&gt;</content></entry></feed>
