Готов поделиться трейлером, полностью сделанным на игровом браузерном движке:
*В ролике показан реальный бой на карте на 9 игроков...
- О чём игра?
Cobalt Gale - Пошаговая тактическая браузерная MMORPG (2D-локации и 3D-бои), объединяющая мрачный пост-апокалипсис и элементы sci-fi (вдохновлённая Fallout 1 и TimeZero).
События происходят в будущем после двух мировых войн, в мире, где большинство земель отравлено кобальтовой радиацией, а какой точно год - никто не может сказать... В этом суровом и разрушенном мире, где существуют иерархии бастионов, мутанты, рейдеры и фракции - цена жизни дешевле, чем цена пули. Каждому игроку придётся пройти путь от бродяги до опасного бойца: прокачивать навыки, собирать снаряжение, выполнять квесты и доказывать, что грамотный тактический расчёт позволяет побеждать даже противников, которые сильнее вас.
- В чём основная идея?
- Само поле боя подразумевает тактическое и пошаговое решение, только с одной особенностью: все игроки втайне друг от друга планируют ход, и как только все запланировали - действия всех игроков воспроизводятся одновременно. Тут не требуется скорость мышки и манёвренность, тут нужен стратегический подход, чтобы просчитать действия противников и запланировать ход так, чтобы выиграть:
- Вы можете создавать уникальные сеты брони и оружия, перков и навыков - которые могут увеличить шанс вашего выигрыша, но не стоит забывать: противники тоже могут иметь уникальные комплекты брони и комбинации:
- Живая экономика городов: если на караван в торговле между бастионами было совершено нападение - цены ударят по всем, от приёма ресурсов до продажи снаряжения.
Сейчас игра находится на стадии закрытой pre-alpha.
Базовый боевой движок, перемещение по локациям, инвентарь и экономика уже работают. Внесено 4 вида оружия, 4 комплекта брони и различные предметы для торговли.
Развитие контента и вектор его направления ожидается через фидбек игроков, после настроенного серверного ядра.
Сейчас я ищу единомышленников, заинтересованных в закрытых тестах, которые соскучились по тактическим играм!
Привет, Пикабу! Давно хотел игру, в которой можно просто взять и полетать на паутине между небоскрёбами — без установки, без регистрации, прямо в браузере. Не нашёл — сделал сам. Называется Spider Swinger: New York. Можно пройти сюжет в одиночку, а можно позвать друзей и летать по городу вместе.
Главное, ради чего всё затевалось, — мультиплеер. Заходишь, вписываешь ник — и ты в одном городе с другими игроками. Можно вместе носиться по крышам, устроить гонку до самого высокого шпиля или подраться.
Режимов несколько, переключаются прямо в игре:
все против всех — паутина, кулаки и гаджеты друг против друга;
все вместе против ботов — вызываешь банду, Арлекина на глайдере или бронированного Бронерога и разбираетесь с ними командой;
герои против злодеев — кто-то играет за злодея и летает на глайдере или таранит всё вокруг;
битва с ботами-пауками — боты охотятся на игроков по всему городу.
В игре есть голосовой чат: зажал кнопку — тебя слышат те, кто рядом. Чем дальше отлетел, тем тише. Когда кричишь «я тебя вижу!» и в этот момент тебя опутывают паутиной и приклеивают к стене — это отдельный жанр комедии.
Город большой: улицы с машинами и пешеходами, парки, порт, мосты, небоскрёбы с подсвеченными окнами, день и ночь. Можно раскачиваться на паутине, бегать по стенам, делать рывки к точкам и нырять с высоты в пике.
Бой — комбо, удары в воздухе, захваты и броски, уклонение «по паучьему чутью», паутина. Опутанного врага можно добить ударом об стену — он прилипнет к ней в коконе. Есть гаджеты: паук-дроны (можно выпустить сразу несколько), паутинная граната, электроперчатка, от которой разряд перескакивает на всех вокруг, и супер-удар с прыжка о землю.
Если друзей под рукой нет, игру можно пройти в одиночку: есть полноценная сюжетная кампания на 11 глав. Суперзлодеи сбежали из тюрьмы «Цитадель», и у каждого своя арена, своя механика боя и свой эффектный выход в катсцене: один падает с неба, другой собирается из дыма, третий встаёт из песка. Сюжет и прокачка сохраняются, так что можно играть понемногу. В финале ждёт симбиот Мрак — вот кадр из его катсцены:
Между главами — свободный город с побочными делами: погони, банды, спасение людей, гонки по кольцам. За всё дают жетоны, на них в Мастерской качаешь героя: дерево навыков, веб-шутеры, костюм, гаджеты. Уровень навыков ничем не ограничен — качай что хочешь.
Пара технических деталей для тех, кому интересно: всё работает в браузере на three.js. Сервер только пересылает сообщения, а ботов считает один из игроков. Если он свернул вкладку или у него пропал интернет, ботов через пару секунд подхватывает следующий. Голос идёт напрямую между игроками по WebRTC. Работает на компьютере (клавиатура, мышь или геймпад) и на телефоне с сенсорным управлением.
Игра бесплатная и до сих пор активно дорабатывается — буду рад, если залетите вечером в мультиплеер и напишете в комментариях, что понравилось, что бесит и что добавить. Особенно жду баги: самые смешные чинить приятнее всего 🙂
Небольшой тизер и по совместительству компас общего антуража (из разряда: как хотелось и как получилось).
Это небольшая история о создании игры (Cobalt Gale), а точнее её вектора, где музой является ностальгия по пошаговым тактическим играм, подобным TimeZero и БК.
*история с техническим описанием, для тех кому интересен результат- пункт 6*
Ну что, начнём с "кубиков"...
1. Создаем серверное ядро.
Несмотря на предыдущую сборку (из первого поста), не было учтено самое главное - сам расчётный центр, мозг для условий, алгоритмов и прочего...
В дебри клиент-серверной архитектуры углубляться не будем (для этого есть сотни статей разного сорта), просто сделаем минимальный визуальный набросок на клиенте, ну потому что так удобней (так как механика на цифрах):
p.s. Качество исходных изображений было не таким шакальным, до выгрузки в пост....
Сейчас важным является проверка и оттачивание внутренней обработки данных на сервере, на какой-то грандиозно-сочный интерфейс нам наплевать, это же по сути - черновик.
Но все-таки попутно мы накидываем наброски UI (это окажется очень важным в дальнейшем):
Внимательные и зоркие отловили тот момент, что на скриншоте путь проложен через противника (таких ошибок будет много, и мы сразу стараемся их исправлять). В довесок неправильный расчёт ОД по клеткам - помечаем, но исправляем позже.
С одним игроком глупо проверять чистоту серверной механики, проверять будем на двоих. Создаем точки входа, разделяем на группы (кто союзник, кто враг, кто общий враг и тому подобное). Проверяем:
Да, про инвентарь, броню, оружие и воспроизведение боя я не рассказывал, но тогда пост сильно затянется. Всё это - серверная часть, основа.
Сама таблица персонажей, имеющихся вещей у персонажа, уровень, характеристики (и всё, что придумано у персонажа) должна иметься сразу. Во избежание переписывания алгоритмов и формул.
2. Модернизация системы координат и продумывание UI.
Квадраты или гексы? Выбираете в зависимости от вашего проекта.
Мною были выбраны гексы только по причине 6-позиционной клетки выбора вокруг персонажа, вместо квадратных клеток в 4 позициях (8 с заходом на другие клетки по диагонали - визуально некорректно).
По-простому, это как в игре "Змейка": вы бы вместо 4 направлений могли двигаться в 8, в том числе и по диагонали.
Гексы, соты... Щас бы мёда...
Попутно для удобства отладки назначаем по оси X буквенное значение. Теперь вместо 2/15 у нас B15. Но это на любителя.
Изначально проект в боевом режиме я видел в 3D. Но в какой-то момент понял, что вылизывание моделей и анимаций с сохранением геймдизайна - это достаточно длительный процесс для одного человека. Попробовал все-таки для начала поиграть с изометрией, попутно создавая себе дополнительные инструменты для работы со спрайтами и анимацией:
Здесь на самом деле появилась другая боль и полное осознание глубины.
Несмотря на изометрию (а точнее, триметрию - не спешите открывать форточку), нам необходимы спрайты во всех 6 направлениях, во всех положениях. Чтобы вы понимали: анимация бега в 6 направлениях (с пустыми руками) в 4 кадра - это 24 спрайта (картинки). Добавляем ходьбу, присед, бросок гранаты, лечение, движение с разными видами оружия, в разной броне - и это уверенно переваливает за полтысячи спрайтов. И это только персонаж.
Меня напугало не количество (я примерно ожидал не одну тысячу рисованной графики), а исполнение создания таких спрайтов. Обратите внимание: это не просто плоский 2D-спрайт, он объемный, с тенями. То есть по факту для такого качественного спрайта нам нужна 3D-модель с анимацией, которую потом можно "нафоткать" и дробить на спрайты.
И что мы имеем: 2D в изометрии происходит через 3D (кстати, для игры Fallout использовалась изометрия в 2D только по причине ограничения характеристик пк у большинства игроков... да, крутая видяха и сейчас не у всех, так что понимаем и не осуждаем).
Если вы хотите поднять такие темы, как отзеркаливание положения, то на такую халтуру я не готов идти. ГПТ и наны-бананы не могут сделать это качественно (последовательная анимация все равно выходит криво и не без артефактов), но тему геймдизайна и графики мы обсудим позже.
Что получается на выходе со спрайтами и текстурами:
На выделенную ошибку не обращайте внимания, это скрин из архива. Была длительная война с ограничениями пакетов в Socket.IO и некорректной сборкой данных обмена между клиентом и сервером.
3. 3D неизбежен.
Этот проект для меня важен. Находить лёгкие решения по типу покупки ассетов для изометрии и ограничить всё видом сверху - это подход спустя рукава (+ потеря контроля над стилем).
Да и если 3D неизбежен - идём в него, набираемся опыта через метод проб и ошибок (идеально ничего не бывает).
На самом деле критичного для меня в этом ничего не было: главным было важно собрать приоритетный сервер, а какую "морду" натянуть, 2D-изометрию или 3D - оставалось лишь решением на будущее, ну а пока - пробуем.
Берём Godot и делаем итерацию клиентской части (набросок):
Думаю, могут появиться споры, что 2D выглядит лучше, а в 3D пошаговые действия с полетом камеры только перегружают гемплей. Готов выслушать ваши доводы и дискуссионные моменты, считаю, что это весьма спорная тема (даже до сих пор).
Двигаемся дальше, насыщаем карту объектами (заглушки на карте уже имеются, как для неразрушаемых, так и для разрушаемых объектов). Собираем на коленке базовые модели, играемся с видом от первого лица, скоростью проигрывания анимации:
Если вас начало подташнивать от вида от первого лица - понимаю.
Раз мы такое добавили, попробуем отполировать в дальнейшем и сделаем вкл/выкл, сейчас это не приоритетная задача.
Делаем апгрейд и, что немаловажно, начинаем углубляться в общий геймдизайн: экспериментируем с окном авторизации, инвентарём, раскладкой предметов, расположением окон.
Проверяем, как это всё у нас заводится, попутно исправляем ошибки:
Основная причина заключается в том, что 2D - это составляющая локаций, инвентаря и предметов (это 70% игры), и она должна выглядеть достойно и качественно. В Godot с её кастомными темами (tres) это превращается в какой-то кошмар, особенно для сборки такого сложного интерфейса. Да еще и немалые страдания в этом интерфейсе с drag and drop (а его тут очень много). Не отрицаю тот факт, что на том же Unity тоже пришлось бы повозиться немало времени, но сама графика инвентаря легче даётся на CSS и выглядит так, как я и ожидал.
4. Итерация клиента в полный WEB (Three.js + WebGL).
Будем считать, что проект на Godot заморожен. Ничего не теряем, опыт ценнее, и в дальнейшем мы сможем вернуться более подготовленными.
Что по итогу - мы переезжаем в браузерные игры? "Алло, 2000-е, ну как вы там?"
На данном этапе - да. В целом для MMORPG это не страшно, это скорее её место обитания изначально. Будем считать, что это второе дыхание. Компы помощнее у всех, интернет (тьфу-тьфу-тьфу) стал быстрее - это никак не портит web-игру (но свои занозы в этом есть).
Собираем 3D-сцену, цепляем наши черновые модели, тут добавили, там подкрутили, насытили карту минимальными эффектами (попутно щупаем всё это дело). Воспроизводим сцену боя:
Вот собака! Ну... или крыса. Ладно. И правильно, вдруг укусила бы. Нам какие-то негативные эффекты не хотелось - надо дойти до выхода из шахты, а он в конце поста...
5. Инструменты.
Сам проект оказался куда больше и глубже, чем я ожидал на первый взгляд.
У меня есть финальное видение проекта, но дьявол кроется в деталях.
С учетом масштаба проекта потребовалось около 13 (пока что) - дополнительных инструментов, которые требуют ручной правки и внесения данных. И это не только создание локаций, редактор квестов, настройщик бестиария, редактирование карт боя и прочее. Самый главный дьявол тут кроется в балансе... О да... Не зря этой теме посвящена книга, не просто так до сих пор вносят патчи в онлайн-игры десятилетней давности.
Думаю, кто знаком с MMORPG, знают это не понаслышке.
Вот так выглядит частица увлекательного рандеву:
Это 1/4 калькулятора и настроек баланса. Не всё влезает, но для понимания масштаба прикрепляю.
Про вайбкодинг в целом сказать мне нечего. Если у вас правильно выстроена архитектура проекта, соблюдена разбивка на модули, настроен локальный git для взаимодействия с другими агентами - вам даже не важно, что бы я тут написал, вы и так шарите.
6. Текущий результат.
Описывать всё реализованное мне не хватит сил в этом посте, а вам не хватит терпения. Поэтому в рамках общей концепции этого поста я ограничусь описанием происходящего только на двух роликах.
Этот ролик посвящен перемещению по локациям как внутри зданий, так и снаружи. Это та самая 2D-составляющая, где будут квесты, NPC, караваны для ограбления и непосредственное перемещение по бастионам, бункерам, зданиям:
*Из всего предфинального проекта выложил только какой-то унылый скриншот, ну и тип, конечно...*
Всё что имеется в интерфейсе - полностью рабочее.
В данной сборке все кнопки функционируют и в интерфейсе нет каких-то пустых (визуальных) заглушек.
Обдумав и всё взвесив, я принял решение, что открывать публичный тест прямо сейчас - это неправильно.
Голая механика без "живого мира" не даст каких-либо эмоций. Зайти, провести два боя с NPC (или игроком) и выйти с мыслью: "Ну прикольно, а делать-то тут что в итоге?" - это худшее первое впечатление, которое может произвести игра. Для проекта, к которому я отношусь кропотливо и серьёзно, это непозволительно.
Поэтому я сознательно беру паузу на рутину: наполнить мир квестами, локациями, экипировкой и предметами, настроить баланс и диалоги, довести до ума стартовые модели и анимации. Лучше выкатить тест чуть позже, но дать хорошее погружение, чем скормить пустой технологический скелет (да и ради чего?).
* Я не ищу инвесторов, для меня лучшая поддержка это ваша заинтересованность, и я хочу оправдать её*
7. Резюмируя технические аспекты WEB.
При миграции в web выяснились хорошие и плохие моменты.
Я бы отметил из плюсов:
- Создание инструментов. Да, для ручной работы это не сильно проще, но когда нужно поправить или сделать гибким игровой элемент - это очень спасает. Не приходится собирать инструмент на одном движке, а саму игру на другом. Для гибкости большинство параметров должны иметь отдельные записи, в том же JSON ну или на крайний случай в БД.
- Возможность запуска без предустановки. Хоть в офисе, хоть дома... Удобно!
- Гибкая подстройка форм под мониторы с учетом CSS .
Из минусов:
- Проект без продвижения. Все заботы остаются на разработчике. Никакая площадка не будет продвигать. Конечно, можно попробовать собрать отдельный клиент (но веб - он и в Африке веб).
- За счёт простоты запуска на любом компе (практически на любом) приходится следить за нагрузкой, общим количеством полигонов и минимизировать графические эффекты, проверяя это замерами в тестах.
Надеюсь, материал был плотным и качественным, возможно, погрузил вас в те времена или просто история показалась вам интересной.
Мой первый пост (тык), возможно, получился сумбурным, но я как автор готов расти, пробуя разные форматы.
Всех, кому интересен проект, игра или просто хочется поностальгировать по тем временам, приглашаю в ТГ канал (Мастерская Cobalt Gale).
P.S. Я понимаю, что пост вышел достаточно техническим, но я хотел рассказать об особенностях проекта и определении того, в каком виде он будет существовать на текущий момент.
В следующем посте я планирую рассказать о самом геймплее простым языком, о моментах, которые кажутся спорными, о реализованном функционале и о том, что планируется добавить.
Всем привет! С момента прошлого поста прошло прилично времени. Я не забросил проект, руки не опустил и всё ещё продолжаю пилить-пиить-пилить :).
Сразу дисклеймер: 5000 онлайна — это синтетические боты. Не живые игроки. Но это честные боты, которые подключаются по реальным WebSocket-сокетам, перемещаются по геодате 25 зон острова, собирают лут, применяют скиллы, пишут в чат и нагружают Spatial Grid сервера точно так же, как живые люди.
Городская площадь Деревни поющей стали: толпа ботов у фонтана и NPC, живой чат и стабильные 50 FPS при 5001 онлайне
1. С чего всё началось:
Cамый главный вопрос - сколько людей сервер потянет до того, как сгорит процессор). На 100–300 игроках всё летает. На 1000 - начинаются первые проблемы. Но хотелось проверить планку в 3000-5000 одновременных подключений (CCU) на скромном сервере (2 vCPU, 2 ГБ RAM на базе Яндекс Облака).
Я попросил ИИ написать генератор нагрузки на Node.js и запустил его со своего домашнего компьютера прямо в боевой сервер.
План был простой: заспавнить 3000 сокетов батчами по 20 штук и посмотреть на тик ядра.
Где-то на отметке в 2200–2400 ботов дома внезапно наглухо лёг интернет. Браузер перестал открывать страницы, а в консоли посыпались тайм-ауты сокетов.
Сначала я подумал, что лёг VPS. Захожу с мобильного интернета - сервер живой, тик 0.5 мс, всё спокойно. А домашний роутер просто завис.
Причина оказалась банальной: Обычные домашние роутеры и Wi-Fi-коробочки от провайдеров не рассчитаны на то, что с одной машины в квартире откроется 3000 одновременных TCP/WebSocket соединений. На роутере кончилась таблица NAT-трансляций (SNAT порты), память забилась, и он просто ушел в глубокий нокдаун.
Стало ясно: стресс-тестировать тысячи сокетов с домашнего ПК больше нельзя.
2. Переезд на распределенный кластер GitHub Actions
Чтобы не вешать домашнюю сеть и не арендовать отдельную пачку серверов только ради тестов, пришла идея: использовать раннеры GitHub Actions Matrix.
Восточный полигон: боты распределены по полям, на счетчике 5001 онлайн, рендер 7.6 мс, сеть 0.8 мс
Но тут возникла вторая засада. Если запустить один раннер Ubuntu в GitHub Actions на 5000 сокетов, он упирается в лимит Azure NAT Gateway - для одной виртуальной машины выделяется всего около 2048 эфемерных портов на внешний IP. Всё, что выше, начинает отваливаться с ETIMEDOUT и ECONNRESET.
Решение - матричный запуск:
Раннер #1 (Runner 1): 1700 ботов (смещение ID от 0 до 1699, часть ботов в городе, часть в полях);
Раннер #2 (Runner 2): 1700 ботов (смещение ID от 1700 до 3399);
Раннер #3 (Runner 3): 1600 ботов (смещение ID от 3400 до 4999);
Четвертый агрегатор: собирает метрики, перцентили RTT и формирует итоговый отчет.
Каждый раннер запускается на изолированной виртуальной машине со своим независимым публичным IP-адресом. Проблема с исчерпанием портов исчезла.
3. «Запустил... и нагрузил ровно 49 ботов»
Казалось бы, всё готово. Жму кнопку запуска в GitHub Actions, захожу в игру и вижу: Онлайн: 49.
Запрашивали 5000, а зашло 49. В консолях раннеров - сотни ошибок: Connect error: Unexpected server response: 429
Полез в логи разбираться:
Раннер 1 подключил ровно 16 ботов.
Раннер 2 подключил ровно 16 ботов.
Раннер 3 подключил ровно 16 ботов.
$16 \times 3 = 48$ ботов + я в клиенте = ровно 49.
Оказалось, сработала защита от DoS-атак! В сетевом транспорте стоял лимит: не более 16 активных сокетов с одного внешнего IP-адреса. Для реальных игроков это имело смысл (хотя даже для CGNAT мобильных операторов 16 маловато), но для нагрузочных раннеров это стало железобетонной стеной. Сервер честно отвечал: HTTP 429 Too Many Requests.
Мы с ИИ добавили авторизованный заголовок x-stress-key, подняли базовый порог для игроков до 64, передеплоили ядро на VPS и перезапустили тест.
4. Итог: 5001 онлайн в реальном времени
После фикса все три раннера залетели на сервер на полной скорости.
Холмы Астарда: боты фармят автоматонов и бешеных кофемашин
Вот реальные цифры из консоли и игрового оверлея:
Запрошено ботов: 5000
Успешно подключено: 5000 из 5000 (100%)
Ошибок рукопожатия: 0
Онлайн в игре: 5001 CCU (5000 ботов + 1 GM персонаж)
FPS клиента в браузере: 50–59 FPS (WebGL Three.js)
Время тика игрового сервера: 1.0 мс (EMA: 0.3 мс при норме тика в 100 мс / 10 Hz)
Event Loop Lag Node.js: 11.88 мс (полное отсутствие блокировок главного потока)
Обработано входящих пакетов: свыше 4.7 млн пакетов за тестовую сессию
Трафик: благодаря дельта-сжатию AOI сервер отфильтровал 61.5% лишних обновлений координат
Что позволило серверу не умереть под 5000 сокетами:
uWebSockets.js (C++ Zero-GC транспорт): забыли про стандартный ws из npm для 5000 сокетов на 2GB RAM. Нативный C++ транспорт держит соединения без давления на сборщик мусора V8.
C++ SIMD (AVX2) для расчёта дистанций и коллизий: модуль project_steam_native.node считает AOI и радиусы агро мобов векторными инструкциями процессора за микросекунды.
Worker Threads для сохранения в базу: вся работа с диском и состоянием игроков вынесена на отдельный поток vCPU, поэтому запись профилей никак не задерживает тик игры.
Проект жив, пилится дальше. Впереди ещё огромная гора работы.
Спасибо всем, кто следит и поддерживает! На бумаге все выглядит шикарно, как будет в реальной жизни? Время покажет))
3D-репродукция «Ночного дозора» Рембрандта (1642), которая открывается в браузере — на компьютере или телефоне. Всё началось с подарка на день рождения другу, который давно мечтал о «Ночном дозоре» в 3D.
24 человека и собака с картины, ворота с аркой, лестница и щит. Камера стоит в ракурсе картины, а у каждой фигуры свой свет на лице — так Рембрандт выхватывает лица из темноты.
Следующие кадры — снимки экрана живой веб-сцены, а не рендеры.
1/3
Это сцена, а не картинка: роту можно обойти и рассмотреть с любой стороны, даже сверху.
Сцена работает на телефоне. Нажмите на фигуру — откроется карточка: имя, годы жизни, биография и источники. Отождествления — по Дудоку ван Хелу («Rijksmuseum Bulletin», 2009).
1/2
На щите над аркой имена стрелков заменены строкой из «Мёртвых душ» Гоголя, опубликованных в 1842 году — через двести лет после картины. Я тоже есть в сцене: скромненько стою возле Рембрандта и проверяю ту же надпись на картуше со свитка. Планирую разработать шрифт в стиле голландского курсива для лучшего соответствия этой надписи.
Кое-чего у Рембрандта нет. В толпе стоят мои друзья — с их разрешения. У ступеней сидят мои собаки Тотошка и Чип. А ещё есть «Амстердамская кавалерия»: три спаниеля, на одном из которых восседает кот, — оммаж «Бременским музыкантам» братьев Гримм и «Каштанке» Чехова.
Детализации фигур хватает, чтобы напечатать их на 3D-принтере как большие статуэтки (по частям) или как миниатюры в упрощенном виде. Капитана (геометрия) и лейтенанта (с текстурой) можно скачать с GitHub.
1/2
Чтобы сцена Blender на 6 ГБ поместилась в веб-страницу, каждая фигура упрощена примерно до 200 000 треугольников, текстуры сжаты, а свет пересобран для браузера. Заметки, скрипты и замеры лежат на GitHub — включая то, что здесь стандартная практика.
Все знают, что делать MMORPG в одиночку — верный способ сойти с ума, и прослыть дибилом. Это честный девлог о том, как мой сервер чуть не захлебнулся от JSON, почему толпа на спавне сломала сетку мира и как ужать расчеты в 17 байт на игрока.
Проблема №1: Клиент — это враг
В обычной игре клиенту можно доверить базовые вещи: например, расчет анимации или координаты. В браузере доверия нет вообще. Ноль. Любой игрок может открыть DevTools (F12), написать в консоли player.speed = 99999 или отправить поддельный пакет «я убил босса». Поэтому сервер спроектирован по принципу Zero-Trust (нулевое доверие): Клиент не знает своих координат. Он отправляет только намерение: «Я зажал клавишу W, хочу бежать вперед». Сервер сам считает скорость, проверяет геодату рельефа, смотрит, нет ли перед носом стены, делает шаг и подтверждает точку. Урон, заточка, выпадение дропа, радиус каста клиент вообще не имеет к этому доступа. И всё это сервер должен рассчитывать 10 раз в секунду для каждого моба и игрока.
Проблема №2: Смерть от мусора и 42 мегабайта в секунду
Первый сетевой протокол ИИ написал на старом добром JSON. Сервер слал клиенту строчки с ID, координатами X/Y и жизнями. Красиво и удобно. Ровно до первого стресс-теста на 2 000 игроков и 1 500 мобов.Когда каждый видит вокруг хотя бы 30–40 соседей, сервер генерирует под 50 000 обновлений в секунду.И тут начался кошмар:1. Трафик: 42.5 МБ в секунду! Нужен гигабитный канал ради сотни тестеров.2. Мусор в памяти: Создание сотен тысяч временных JSON-строк мгновенно забивало оперативку. Сборщик мусора Node.js врубал экстренную очистку (Stop-the-World).3. Весь мир замирал на 200–300 мс каждые пару секунд. Мобы телепортировались, удары не проходили.Спасение: диета до 17 байтМы выбросили JSON из симуляции навсегда. Вместо текста упаковали всю информацию об игроке или мобе в 17 сырых бинарных байт:— 2 байта на ID;— по 2 байта на координаты X, Y, Z (квантование до сантиметра);— 1 байт на угол поворота;— 2 байта на процент жизней;— 2 байта на маску состояний (бежит, атакует, кастует, мертв).Итог: сетевой трафик рухнул с 42.5 МБ/с до 2.2 МБ/с при "5 000" онлайна. Падение в 19 раз! Сервер вздохнул свободно, а мир перестал заикаться.
Проблема №3: Проклятие Городской Площади
Чтобы сервер не проверял расстояние между каждым игроком и каждым мобом, мир нарезается на сетку — Spatial Grid с клетками по 108 метров. Ты опрашиваешь только свою клетку и 8 соседних. В поле это работает идеально.А потом зашли живые игроки. Они толпой пришли на центральную площадь: торговать, орать в чат и собирать группы.В одну несчастную клетку набилось 400 человек. И вся оптимизация мгновенно выродилась обратно в жуткие тормоза: сервер снова начал считать расстояние каждого ко всем.Как решили:Написали адаптивное дробление. Как только в клетке собирается больше 100 сущностей, она прямо на лету делится на 16 мелких зон по 27 метров. Игроки в толпе получают обновления только о тех, кто рядом, а дальние персонажи обновляются реже. Сервер даже не заметил нагрузки.
Проблема №4: «Проклятие одной монетки»
Еще одна ошибка новичка — писать данные в базу при каждом чихе игрока. Моб умер -> упала шестеренка -> игрок подобрал -> пишем в базу. Когда тысячи игроков месят мобов, диск захлебывается за секунды. Игра виснет.Решение: игра живет только в оперативной памяти.База данных вообще не знает, что вы бегаете по острову. Сервер просто ставит флаг «персонаж изменен». Раз в 15 секунд фоновый процесс пачкой сбрасывает всех изменившихся игроков в базу за один быстрый запрос. Никаких лагов и никаких откатов инвентаря при рестарте.
Миллиард токенов и 320 часов марафона: сколько стоит разработка с ИИ
Пишу этот проект один вместе с Gemini 3.8 Flash )) Когда люди слышат «делает игру с нейросетью», они представляют кнопку «сделай шедевр». В реальности это был 29-дневный марафон по 11–12 часов в день. Сложнейшие сессии отладки длились по 40 шагов, где на каждом шаге в модель скармливался контекст по 150 000 – 180 000 токенов: монолит сервера на 5 300 строк, таблицы боевой математики, геодата и сырые дампы сетевых пакетов.
442 миллиона токенов только на серверную часть
суммарно весь проект (Three.js клиент и сервер) сожрал 1.265 МИЛЛИАРДА токенов!
В середине 90-х и начале 2000-х у многих из нас дома стояли пузатые ЭЛТ-мониторы с Windows 95/98 или голым MS-DOS. И среди сотен игр были те самые особенные шедевры, музыка из которых въедалась в память навсегда:
Xixit (1995) — медитативная головоломка, чей глубокий, меланхоличный и невероятно атмосферный саундтрек затягивал так, что игру не хотелось выключать часами.
Mine Bombers 3.1 (1995) — финский хит, за которым мы с друзьями устраивали ожесточенные баталии на одной клавиатуре. Взрывы динамита в темных шахтах гремели под бешеный, зажигательный драйв трекерных мелодий.
А чуть позже — музыка из кейгенов и кряктро от культовых демогрупп (Razor 1911, Fairlight, Paradox), где авторы умудрялись упаковывать полноценные симфонии в файлы размером 20–50 килобайт!
Это была трекерная музыка (MOD, XM, IT, S3M). В ней не было записанного аудио: файл содержал крошечные кусочки сэмплов и таблицу шестнадцатеричных нот, которые компьютер синтезировал в реальном времени.
Я сам с юности увлекался написанием таких треков в FastTracker II и долгие годы мечтал о пет-проекте: сделать настоящий веб-плеер трекерной музыки, который играл бы эти хиты прямо в браузере с живым звуком и аутентичной атмосферой демосцены.