Я сшил разрозненные карты MMO в один бесшовный мир: игрок выходит из города в пустыню и не замечает, что под ним уже работает другой сервер. А всю рутину картографа — импорт, разметку препятствий, разрезание карт и проверку связей — отдаю ИИ. Заодно проверил, что происходит, если доверить ему игровую графику Читать далее
Карта тайлового мира — это файл: несколько слоёв тайлов, слой непроходимых клеток и объекты-двери, у каждой в свойствах записаны карта назначения и клетка прибытия. Законченная единица, нарисованная отдельно от соседей. Края карт заходят друг на друга на десяток клеток, тропа с одной упирается в обрыв на соседней, а переход между ними всегда телепорт с экраном загрузки.
Мне нужен бесшовный стык: игрок идёт из города на юг, пересекает границу и не догадывается, что под ним сменился сервер. Между этими двумя состояниями лежит работа картографа, которую я почти целиком отдал машине.

Что происходит с картой по дороге в мир: слева дверь-телепорт с экраном загрузки, справа бесшовный стык
Коротко о проектеС 2022 года я в одиночку веду дневник разработки: делаю авторитарный сервер для 2D MMO RPG — игры с открытым бесшовным миром, где сотни игроков и существ живут в реальном времени. Сервер на PHP и Symfony, клиент на Unity, правду о мире считает только сервер. С семнадцатой части в проекте работает ИИ: механику я описываю словами, а собирает её он — и на сервере, и в клиенте, через свой протокол доступа к данным и коду игры. В прошлой части был контур проверки, который не даёт этой сборке молча разъехаться с задумкой: спеки, агенты-ревьюеры, прогон по живому серверу.
Сегодня — про местность, по которой всё это ходит, и про тот же подход, приложенный к данным. Там машина писала код, а контракты и живой сервер не давали ему разъехаться. Здесь машина ведёт карту через цепочку преобразований и точно так же проверяет результат — инструментами и кадром из игры.
Карты я беру из The Mana World, открытой MMO с историей длиннее моей. Её мир рисовали люди и достраивали годами, а лицензия позволяет брать его в работу. Мне он нужен как настоящий полигон: синтетическая карта из трёх домиков не покажет ни одной живой проблемы.

Миры игры: открытый мир из трёх состыкованных карт, отдельные подземелья, пещеры и городские интерьеры — каждый мир ставится и снимается целиком
Карта — это процесс, а не картинкаПервое, что стоит знать про мою архитектуру: карта у меня не изображение и не запись в базе. Это отдельный процесс на сервере. В нём считаются механики этой местности, держится пул её игроков, оттуда уходят игровые пакеты. Мир — набор таких карт, живущих на одной ноде. Почему процессы, а не потоки, я разбирал в пятнадцатой части; здесь это данность, на которой стоит всё остальное.
Отсюда сразу следует практика, к которой в других движках приходят через боль. Нарезка местности на карты — это распределение нагрузки. Слишком крупная карта даёт один тяжёлый процесс, слишком мелкая — лишние переходы. Раздаётся контент тоже мирами: мир ставится в игру целиком, обновляется целиком и снимается целиком. В витрине он так и выглядит — набором карт со своей раскладкой, который ставится к себе одним нажатием.

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

Сверху персонаж в тех же воротах, номер карты — 54. Снизу он же шагом южнее: ворота видны вверху кадра, номер уже 55
Самое интересное здесь не сам переход, а то, из чего рождается граница.
Поставить две карты рядом на раскладке мало. Соседство даёт только соприкосновение краёв, а пройти игрок сможет там, где непроходимые клетки убраны с обеих сторон. Границу открывают дыры в преградах, и ничего кроме них.
Сейчас у портового Тулимшара с южной картой два прохода шириной по пять клеток — ровно две дороги, по которым люди и ходят. А с Пустынными горами карты соприкасаются, но граница глухая: туда пока только дверью. Разница между «соседи» и «можно пройти» в моём мире осязаемая, и её видно в интерфейсе.
Отсюда правило, которое сэкономило мне месяцы ручной работы. Дверь-телепорт, легшая на общую границу с той картой, куда она ведёт, просто не исполняется. В исходной игре весь мир связан такими дверями. Когда я ставлю две карты встык, их встречные двери молча выключаются и игрок переходит границу сам. Снимать ничего не нужно, а стоит сдвинуть карту на раскладке — стык рвётся, и те же двери снова работают телепортом.
Что из этого делает ИИТеперь про руки. Работа картографа состоит из десятков однотипных операций над данными, и они хорошо ложатся на машину.
Только вокруг карт, тайлов и миров у ИИ больше сорока инструментов: залить карту вместе с её графикой одним архивом, переложить преграды, разрезать карту на части, подвинуть её на раскладке, переписать цель двери, снять превью, прочитать связность всей игры. Плюс глаза: превью карты, схема переходов, кадр из живой игры.
Заливка одной карты — цепочка шагов, и каждый шаг машина делает сама.
Импорт. Карта приезжает вместе со своими наборами графики одним архивом. Сам разбор формата Tiled у меня появился давно, ещё в седьмой части, и с тех пор не менялся. Изменилось то, что происходит с картой дальше.
Перекладка преград. В исходнике непроходимость нарисована слоем клеток. Мой рантайм считает стенами не его, а прямоугольники-обводки, и хранить их дешевле на порядок. Пропустишь этот шаг — получишь карту, проходимую насквозь, без единой ошибки в логах.
Срез мёртвых краёв. Карты источника лежат с перекрытием: по краям идут ряды-заглушки, закрывающие игроку выход наружу. Их срезают, а величину среза читают по самой карте — сколько рядов с краю занято сплошной стеной. Дальше начинается рельеф, и резать его нельзя.
Разрезание. Один файл источника часто содержит десяток не связанных между собой комнат: трактир, банк, тюрьму, кузницу. У меня каждая становится отдельной картой со своим процессом. Из городских интерьеров Тулимшара так вышло семь карт, из пустынных — одиннадцать. Заодно приходится перенацелить все двери, которые вели в общий файл.
Сведение кромок. Соседние края сверяются клетка в клетку: проходимой клетке одной карты должна отвечать проходимая клетка другой. Не совпало — игрок упрётся в невидимую стену там, где видит открытую дорогу.
Отдельная кампания — перенос непроходимости на правильный носитель. Стена, нарисованная обводкой, живёт на одной конкретной карте. Но скала остаётся скалой везде, поэтому непроходимость переезжает в свойства самого тайла и начинает действовать на весь мир разом. ИИ проходит по миру, собирает кандидатов, считает, сколько клеток каждый из них реально держит, и после проверки помечает их пачкой. Обводки, ставшие после этого бесполезными, снимаются последним шагом. Руками так не делают: в одном мире сотни тайлов и десятки тысяч клеток.
Приборная панель вместо веры на словоОтдать машине руки мало. С кодом эту роль играют контракты и прогон по живому серверу, с картами нужен экран, где сразу видно, что она натворила.
У меня это схема переходов: граф всех карт игры и всех связей между ними. Бесшовные стыки идут пунктиром, двери — линиями, и у каждой связи разобрана цель: какая карта, в какую клетку прибывает игрок.
Она же считает поломки. Прямо сейчас по игре их тридцать восемь, и это не тридцать восемь багов. Большая часть — двери, ведущие в зоны, которые я ещё не залил: цель у них верная, карты просто пока нет в игре. Такие починятся сами в день заливки зоны, и читать их надо как список оставшейся работы. Настоящих поломок в этом списке единицы, вроде точки прибытия, попавшей в стену.

Схема переходов: пунктир — бесшовные стыки, линии — двери, справа разбор поломок
Разница между «сломано» и «ещё не сделано» звучит мелочью, пока карт десяток. На сотне без неё работать невозможно.
Отдельно ловится класс ошибок, о которых игра молчит. Дверь с незаданной точкой прибытия не пустит в игру всю карту, а не одну себя. Точка прибытия, поставленная на клетку встречной двери, будет швырять игрока назад при первом же шаге. Ни то, ни другое не даёт ни ошибки, ни предупреждения — только пустое место там, где ждали город.
Чего ИИ не умеетДанные машина ведёт отлично. С картинками всё иначе, и граница проходит резко.
Claude, которым я работаю, прекрасно кроит атлас механически: обрезать, расширить холст, вклеить недостающие тайлы, переписать их свойства. Рисовать он не умеет и вида не делает.
Поэтому графику я отдал генеративной модели. Задача была понятная: сделать ремастер набора — осовременить рисунок, сохранив размер тайла, пропорции и сетку. Тайл ведь не картинка, а ячейка: он обязан лечь ровно в свои тридцать два пикселя, иначе поедут все карты, где он стоит.
Этот заход сразу показал главное: рисунок действительно осовременивается. Камень стал объёмным, у арки появилась фактура, песок перестал быть плоской заливкой. Стиль игры при этом узнаётся — инородного модель не притащила.

Слева исходный набор, справа он же после ремастера
А дальше начинаются детали, из-за которых набор пока не поехал в игру. Прозрачности для модели не существует: пустые места между объектами она закрашивает камнем — на кадре выше этот фон уже вырезан, но об этом чуть ниже. Кое-где вместо исходного предмета нарисовано своё. И главное — содержимое клеток съехало на пару пикселей. Тайл обязан укладываться ровно в свои тридцать два: сдвиг на два даёт шов на каждой стене, где этот тайл повторяется.
Часть этого чинится не промптом, а руками вокруг модели. Прозрачность я ей больше не доверяю вовсе: пустые места известны из исходного набора, и после генерации они вырезаются по нему же — целый класс брака закрыт насовсем. Геометрию собираюсь добирать тем же способом: резать результат по сетке и подгонять каждую клетку отдельно. Рисование остаётся за моделью, всё остальное возвращается ко мне.
Есть и развилка, из которой я пока не вышел. Когда модель видит весь набор целиком, ей достаётся горстка пикселей на тайл и правки выходят косметическими. Когда режешь набор на куски и увеличиваешь каждый, деталь появляется — но соседние куски начинают жить разной жизнью, и посреди одной стены меняется манера рисунка. Либо однородно и скромно, либо детально и вразнобой.
Есть и продуктовая сторона, о которой легко забыть. Местность собирается из нескольких наборов графики сразу, и осовремененный кусок перестаёт совпадать с соседями. Пока обновлён один набор, город выглядит хуже, чем до ремастера: половина стен новая, половина старая. Значит вести такую работу можно только по всей палитре разом.
Такой результат мне нравится больше, чем если бы всё легло с первого раза. Он ровно показывает, где проходит граница: машина закрывает объём и рутину, а решение о том, что попадёт в игру, остаётся за человеком. В мир не заливают то, что «в целом похоже».
Что дальшеМир Тулимшара уже живёт: город, юг, пустынные горы, подземелья, интерьеры. Дальше я его заселяю и довожу глухие границы до настоящих проходов, а заодно решаю вопрос с общим набором графики.
Вопрос к вам. Кто делал открытый мир: как у вас решён момент, когда игрок стоит на границе двух серверов и ровно в этот момент в него летит удар? Интересны ваши грабли, а не теория.
ИсторияRedis как память игрового мира: сколько игроков и NPC он держит
Клиент на Unity для авторитарного сервера: что он обязан уметь
Почему персонаж телепортируется: пинг, интерполяция и экстраполяция
Event-driven и JSON-RPC: почему игровой сервер не собран из сервисов
Не размер пакета: где на самом деле узкое место сетевого сервера
MVP авторитарного сервера для 2D MMO: три года и что получилось
Конвейер контента для MMO: импорт анимации, экипировка и обновление игры без патчей
Каталог ассетов и git для MMO: как командой вести игру в облаке
ИИ-картограф: как карты сшиваются в бесшовный мир
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Как ИИ не дал загнуться ещё одной ноунейм игре. Даже текстовой | 0 | 8.88 | 24-07-2026 |
| 2 | 7 месяцев вайбкодинга: как в одиночку делать то, что раньше требовало команду | 0 | 9 | 01-08-2026 |
| 3 | 7 месяцев вайбкодинга: как в одиночку делать то, что раньше требовало команду | 0 | 9 | 01-08-2026 |
| 4 | DS MCP: как дать AI-агенту знание о вашей дизайн-системе | 7 | 8 | 08-07-2026 |
| 5 | ИИ-Автопилот: замкнутый цикл разработки на C++ — от тикета до проверки в живом GUI | 0 | 8.22 | 29-07-2026 |
| 6 | ИИ-Автопилот: поток принятых задач вырос в тринадцать раз | 1 | 8.82 | 31-07-2026 |
| 7 | Ааа, всё пропало! AI создаёт дырявый код! Что же делать? | 0 | 11.43 | 16-06-2026 |
| 8 | Невыносимая слопность бытия | 0 | 10.73 | 25-07-2026 |
| 9 | Книга: «Эффективный разговорный ИИ. Создаем чат-ботов, которые действительно работают» | 0 | 12.49 | 29-04-2026 |
| 10 | Для русскоязычной версии игры Throne and Liberty вышло первое крупное обновление | 0 | 5.49 | 12-08-2026 |