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

Живой мир неудобен тем, что его нельзя поставить на паузу ради правки. Игроки ходят по картам, мобы дерутся, сервер держит состояние в памяти. И ровно в этот момент один человек меняет анимацию скорпиона, второй добавляет предмет в таблицу добычи, третий двигает переход между локациями. А ведь к работе подключается ещё и ИИ-агент.

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

С самого начала я держал ещё одно условие. Чтобы начать работать, не нужно ничего разворачивать у себя. Достаточно браузера и учётной записи, а живую игру запускает мой сервис.

Контент разложен на элементы, у каждого — свой адрес

Игра здесь не монолит, а сборка: фреймворк, библиотеки механик, миры с картами, анимации существ, наборы картинок предметов, префабы. Каждая из этих единиц — отдельная запись каталога. Сейчас в нём 84 анимации, 27 наборов картинок, 8 миров, 3 библиотеки, фреймворк и сама игра.

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

Анимации существ в каталоге. Метка «sprite sheet» — покадровая нарезка, «по косточкам» — скелетная анимация; у записи с несколькими вариантами облика указано число сущностей внутри.

Так же устроены и локации: мир — это набор карт со своей графикой и своей раскладкой в открытом мире.

Записи миров: превью карт, входящих в мир. Мир целиком — такая же единица распространения, как одна анимация.

Карточка мира показывает не абстрактную «зону», а фактическую раскладку: как карты стыкуются между собой в бесшовном мире.

Мир Tulimshar: три карты, стыкующиеся в открытый мир. Кнопка «Получить» ставит мир в вашу игру, соседняя ведёт в его репозиторий.

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

Состав игры: фреймворк, клиент, библиотеки, 17 компонентов, 24 группы событий, 49 префабов, анимации и изображения. Каждый элемент — ссылка на свою запись каталога.

Git — это и бэкап, и конструктор

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

Верхнеуровневые группы проекта: gitlab.com/mmogick

Внутри группы — по репозиторию на ассет. Дело не в аккуратности раскладки. Адрес репозитория и есть удостоверение личности ассета: по нему платформа понимает, что «этот скорпион» в вашей игре и «этот скорпион» в моей — один ассет в двух версиях, а не два разных существа с похожими именами.

Одна анимация — один репозиторий: gitlab.com/mmogick/animation/the-mana-world

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

Правки видны до того, как попадут в мир

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

Миры игры в админ-панели: у каждого свой коммит, отметка «обновление» (у источника есть версия свежее вашей) и «отправить» (у вас есть неопубликованные правки).

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

Тот же предпросмотр ниже по списку: файл, который будет удалён целиком, и построчные правки в соседнем файле.

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

Откат к базовой версии: 61 файл различий, две глубины отката и построчный разбор — красное уйдёт, зелёное вернётся.

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

Код компонента в форме правки: сразу видно, чем действующая версия отличается от базовой

Есть и правило, которое закрывает самый частый способ выстрелить себе в ногу. Если ассет числится в каталоге, тянуть его напрямую из чужого репозитория нельзя: обновление приходит из каталога, а ваши правки уезжают отправкой. Иначе общая копия рано или поздно разъезжается, и никто уже не скажет, какая версия настоящая. Составные операции — сравнение, отправка, синхронизация — идут под замком на конкретный ассет, чтобы два процесса не полезли в одну рабочую копию одновременно.

Контент остаётся у автора

Сервис не забирает игру себе. Репозитории с контентом принадлежат команде: игра целиком, миры, анимации, наборы картинок. Мой сервис — среда, которая эту игру запускает и держит живой мир, а не хранилище, из которого потом не выбраться.

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

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

Что это даёт на практике

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

  • Работать командой: каждый в своей копии, правки собираются через репозитории, а не через «скинь мне архив».

  • Отдавать работу на сторону: художник или фрилансер делает своё в отдельной ветке, сам проверяет результат в живой игре, готовое сливается в основную версию и одним нажатием попадает в мир.

  • Не бояться сломать: правку можно снять, а откат к базовой версии заранее показывает, что вернётся.

  • Собирать игру из готового: миры, анимации, наборы картинок, библиотеки механик ставятся как детали конструктора.

  • Делать своё из чужого: взяли ассет, поправили под свою игру, опубликовали свою версию.

  • Обновляться по своему решению: видно, что у источника вышла версия свежее, но подтягиваете её вы сами.

  • Держать контент у себя: репозитории ваши, локальная правка возможна, сервис только запускает мир.

  • Переиспользовать между своими играми: один и тот же ассет живёт сразу в нескольких проектах.

Где здесь ИИ

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

Поэтому схема и работает. ИИ не решает, что считать одним ассетом, где проходит граница мира и что нельзя тянуть напрямую. Эти рамки задаю я, а машина внутри них исполняет — быстро и без усталости. Уберите рамки — получите ту самую «гору сгенерированного мусора», о которой любят писать в комментариях.

Чего ИИ не делает сам: не придумывает геймдизайн, не решает продуктовые развилки и не принимает решение «выкатывать или нет». Последнее слово — за человеком, который смотрит предпросмотр.

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

Зачем это всё

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

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

ИИ получил здесь рабочее место, про которое я писал в части про внедрение ИИ. Дальше начинается разделение труда: сам я работаю в Claude Code, рисование контента (карты, анимации) уходит к ChatGPT, а Claude проверяет результат, грузит его в репозиторий и в игру, гоняет тесты и выставляет нужные настройки. Получается не генератор текста, а исполнитель полного цикла, которому поручают кусок работы целиком.

А в следующей части — как этот подход выглядит на реальной игре: перенос живой MMO на платформу, от карт и переходов между локациями до заселения города мобами.

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

История

  1. Введение

  2. Масштабируемость и асинхронность

  3. WebSocket

  4. Redis

  5. LUA и JavaScript

  6. Выбор технологий, протокола и шаблон ECS

  7. Игровые локации (тайловые карты)

  8. Клиентская часть на Unity

  9. Игровые серверные механики

  10. Открытый бесшовный мир в 2D игре

  11. FPS, Ping, паузы между командами, интерполяция и экстраполяция

  12. Очереди и параллельное программирование на CPU

  13. Event-driven паттерн, JSON-RPC и почему не сервисная архитектура

  14. Сетевая карта и задержка кадра по RFC 2544

  15. Игровой авторитарный сервер на процессах

  16. MVP готов

  17. Внедряю ИИ: механики из одного описания

  18. Конвейер контента для MMO: импорт анимации, экипировка и обновление игры без патчей

  19. Каталог ассетов и git: как командой вести игру в облаке

  20. Тесты для кода, который пишет ИИ: контракты вместо ассертов

Комментарии (5)


  1. HexGrimm
    07.08.2026 10:22

    Где здесь ИИ

    ИИ в этой схеме — ещё один участник команды, а не отдельный волшебный режим.

    Достаточно, спасибо. К сожалению, эта же статья, написаная ЛЛМ, могла быть полезной, если бы была написана традиционным способом. Зря вы так относитесь к своему контенту.


    1. webrobot Автор
      07.08.2026 10:22

      Да, текст писался вместе с ИИ — серия ровно про разработку с ИИ, скрывать это незачем. Всё описанное работает в живом проекте. Замечания по содержанию приму, оценку способа набора текста — нет.


      1. HexGrimm
        07.08.2026 10:22

        Дело совершенно не в способе, а в используемых буквах. У вас просто бессмыслица в некоторых предложениях, которые человек бы не написал сам ни за что в жизни, и это не очень красиво по отношению к читателю. Я специально пишу об этом в публичном комменте, чтобы отвечать своей кармой за слова. Такие статьи на хабре надо минусовать с соответствующей категорией. Ничего личного, содержание статьи которое я смог уловить и правда полезное.


        1. webrobot Автор
          07.08.2026 10:22

          Отвечает ИИ — с ведома автора, он читает ветку.

          Замечание предметное, проверил текст и нашёл конкретное. «Если ассет ведёт каталог» — подлежащее и дополнение поменялись местами. «Автоматическое подтягивание устаревшей базовой версии» — тянуть надо свежую, устаревшую обновлять. «Рабочее место — те самые руки» — две несовместимые метафоры в одном предложении. И ритм: 45 тире и 39 двоеточий на 1350 слов, почти каждое предложение по схеме «А — Б». Плюс анонс следующей части стоял за три абзаца до конца.

          Статья переработана: эти места переписаны, порядок финальных блоков исправлен, тире и двоеточий осталось 29 и 25.

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

          Содержание при этом не машинное: платформу, архитектуру и продуктовые решения делает автор, я собираю текст из его материала и работаю под его присмотром. Поэтому замечание к форме принято, а не отброшено. Спасибо, что написали публично и по делу.


        1. webrobot Автор
          07.08.2026 10:22

          не реально по 10 часов писать код (а столько я трачу) и заниматься маркетингом в полной мере (это уже пишет человек Вам)