
Два месяца назад мы анонсировали запуск своего игрового сервера в Minecraft. В комментариях, ожидаемо, нас попросили поделиться техническими подробностями и сложностями запуска. Но на старте проекта камней преткновения не так много, ведь задача по развертыванию кубического сервера сводится к тому, что нужно разложить файлы, написать юниты и просто ждать игроков.
Самая непредсказуемая переменная — действия игроков. За два месяца к нам пришло более 500 «Стивов», чтобы поиграть, покритиковать и попытаться сломать сервер. Именно действия пользователей стали самой сложной и интересной задачей.
Используйте навигацию, если не хотите читать статью целиком:
Дисклеймер

Прежде чем начнем погружение в технические детали, я хочу отметить, что идея официального игрового Minecraft-сервера — это буквально пет-проект инициативных сотрудников под крылом Selectel. По сути, это позволило нам создать полностью бесплатный для игроков сервер. Конечно, пришлось пройти несколько согласований, но по итогу мы нашли общие точки интереса.
Как и полагается пет-проектам, развитие сервера происходит в свободное от основной работы время силами четырех человек: разработчика, DevOps-инженера, главреда и технического редактора.
Начало начал

Сервер открылся не два месяца назад. С момента запуска прошло уже пять лет — именно тогда было начало пандемии и самоизоляции.
Помните, стала популярна идея переносить рабочие созвоны в различные игры? Тогда даже Большой драматический театр даже дал несколько спектаклей в Minecraft. В то время я и решил в шутку создать образ места, в котором я работал, — ЦОД на Цветочной 19. Его же я позже показал коллегам — и они заинтересовались.
Идею поддержали, в мире вскоре появились более-менее приемлемый спавн, образ Цветочной 21 — и мы быстро собрали небольшую промо-кампанию с раздачей кодов с разным номиналом на услуги облачной платформы. На волне хайпа и небольшой рекламе на сервер заходили игроки. Но в долгосрочной перспективе у проекта не было развития, а мое администрирование было довольно ленивым.

Игроки заходили посмотреть на постройки, но без мотивации играть: социальной составляющей нет, античит агрессивный, «фишек» и заботливого админа не встретить. Тем не менее, всегда есть игроки, которые готовы сами ставить себе цели и сами их достигать. Один из проектов игроков — рендер карты сервера по годам с 2021 по 2024.
Так сервер безмятежно стоял с начала 2020 года. Я лишь изредка заходил откатить разрушения и проверял, что резервные копии делаются. Аптайм сервера, конечно, впечатляет:
firemoon@minecraft:~$ uptime
17:18:45 up 1893 days, 3:31, 1 user, load average: 0.07, 0.07, 0.08

В 2025 году мне вдруг взбрело в голову «воскресить» этот проект. В лучшем случае получится что-то более интересное, в худшем — официально закроем проект. Быстро пробежимся по наследию.
О сервере: версия и плагины
Версия Minecraft: 1.15.2, ядро Spigot.
AuthMeReloaded — аутентификация для игроков.
AntiCheatReloaded — очень агрессивный античит.
WorldEdit — служебный плагин для редактирования пространства.
WorldGuard — плагин для защиты пользовательских построек.
Кастомный плагин, который заставлял некоторые кнопки выдавать промокоды в рамках рекламной кампании.
WorldBorder — установлены границы мира: пять тысяч блоков от точки спавна. Это позволяло держать мир в пределах 5 ГБ.
Chunky — плагин, который сгенерировал игровой мир в пределах границ, чтобы не вызывать «лагов», когда игроки попадают в несгенериованную область.
По современным меркам это довольно простой сервер, к тому же застрявший в далеком прошлом. А для его работы было достаточно конфигурации с Intel Xeon Gold 6240, 128 ГБ RAM и NVMe-дисками на 512 ГБ в RAID1.

Игровой сервер с криперами и порталом в Незер. Добывайте ресурсы, стройте объекты, исследуйте мир Selectel в Minecraft и получайте призы.
Эпоха возрождения
Как админ сервера я бы мог топнуть ножкой и сказать, что начинаем все с чистого листа. Но выбрасывать пятилетнюю историю не хотелось. Был вариант обновить ядро до новейшей версии и начать обслуживать сервер, но какой в этом толк? Все в радиусе пяти тысяч блоков уже сгенерировано под старую версию игры и там не появятся все нововведения.

Мы обсудили с коллегами возможные варианты развития события и договорились до чуть более распределенной архитектуры.
Лобби — точка подключения игроков, откуда можно переместиться в любой из игровых серверов.
Выживание — обычный игровой мир «с чистого листа».
Музей — тот самый исторический мир, в котором можно посмотреть на наши дата-центры. В нем больше нельзя строить, только смотреть.
Арена — отдельный сервер для PvP- и PvE-событий. Здесь игроки соревнуются в навыках за наш мерч.
*Тест — скрытый сервер, на котором я могу проверять различные плагины и настройки до раскатки на основные серверы.
Для объединения всех серверов в одну сеть используется прокси-сервер BungeeCord. Он, как и игровой сервер Minecraft, может работать в одном из двух режимов: онлайн и офлайн. В онлайн-режиме сервер при каждом подключении игрока обращается к официальному API Minecraft и валидирует профиль игрока. В этом случае в игре виден скин персонажа и, возможно, плащ. Если сервер в офлайн-режиме, то он безоговорочно верит всем подключениям, что несколько расширяет аудиторию, но отключает функции официальных профилей Minecraft.
Чтобы игровые серверы работали с BungeeCord, они должны быть выведены в офлайн-режим. Это создает потенциальную уязвимость: если игрок может подключиться к игровому сервер в обход прокси-сервера, то онлайн-аутентификации не произойдет. Таким образом, злоумышленник может зайти в профиль другого игрока, зная его ник. Поэтому важно на сетевом уровне ограничить подключения игроков «мимо» прокси-сервера.
Так как это все же пет-проект, я решил освоить новые технологии: облачную платформу. Я взял сервер (8 vCPU, 64 ГБ RAM) для прокси и всех игровых серверов, которые однопоточные. Этого было достаточно, ведь сложно рассчитывать на онлайн в более чем 100 игроков сразу после запуска. Кроме того, если понадобится, то облачные технологии позволяют легко масштабироваться.
В качестве ядра оставили сервер Spigot, но обновили версию до 1.21.5. Мне кажется символичным, что переезд с прошлой версии 1.15.2 — это буквально перестановка цифр.
Почему не Paper?
Почему не Purpur? Почему не Folia? Ядро Spigot уже было обкатано, а ставить другое из-за надписи «Это лучший форк» — сомнительная стратегия.
После утверждения ядра мы установили набор плагинов, которые были на старом сервере, но с учетом прокси-сервера.
AncientGates — визуальные порталы для телепортации внутри одного мира и между серверами.
AuthMe и AuthMeBungee — плагины для аутентификацию игроков. Плагин на прокси-сервере автоматически подтверждает успешную аутентификацию при переходе между серверами в рамках одного прокси.
WorldGuard и WorldEdit — с ними ничего не поменялось, это все те же старые добрые плагины для привата и работы с миром.
LuckPerms и LuckPermsBungee — нужны для управления правами.
SetHome — возможность быстро вернуться домой. Немного упрощает игровой процесс, но почему бы и нет.
ODailyQuests — ежедневные квесты для поддержания постоянного интереса.
bungeecord-prometheus-exporter — экспортер данных с прокси-сервера. Позволяет отслеживать онлайн и распределение игроков по игровым серверам.
ViaVersion — позволяет клиентам с более новой версией подключаться к старому серверу. Пока я готовил инфраструктуру, вышел Minecraft 1.21.8. Не все плагины обновились, поэтому я просто добавил слой совместимости.
HelpOp — «самопал», который по команде отправляет текст в чатик с админами. Односторонняя связь с администрацией на случай экстренных ситуаций.
Граница мира теперь выставлена внутриигровыми средствами, ограничение 100 тысяч блоков в каждую сторону. Карта генерируется при посещении новых мест.
Важные плагины, такие как LuckPerms и AuthMe, имеют поддержку баз данных SQL и могут общаться через прокси, что позволяет автоматически синхронизировать знания между разными игровыми серверами. Так, например, если выдать какие-то права в глобальном контексте на сервере Лобби, то остальные серверы тут же подхватят изменения. Очень удобно.
Я решил, что хочу самостоятельно набить первые шишки, не подглядывая на другие серверы. Поэтому развитие было, есть и будет эволюционным. Игроки в процессе игры делятся впечатлениями и обратной связью, а мы — учитываем: изучаем запрос и добавляем то, что кажется действительно нужным.
Приоритет — ванильный Minecraft с некоторыми улучшениями качества жизни, но без ломающих механик вроде стартового набора с полностью зачарованной алмазной броней.
Итак, 14 июля мы подменили адрес со старого сервера на новый, сделали анонс и стали ждать первых игроков.
Голос первых игроков
Первые игроки запросили целый набор улучшений, который они видели на других серверах. Что было интересного?
Антигриферский плагин CoreProtect. Он записывает все действия игроков и позволяет точечно откатывать уничтожение или кражу чужого имущества. Впоследствии я по достоинству оценил этот плагин, но это материал для отдельной статьи…
Плагин SkinRestorer. Так как прокси-сервер работает в офлайн-режиме, то скины и плащи не прокидываются в игру. Это плагин восстанавливает несправедливость.
Правило игры playersSleepingPercentage. Оно позволяет указать количество игроков, которые должны лечь в кровать, чтобы пропустить ночь. Это довольно важное игровое замечание, потому что с ростом количества игроков уложить спать весь сервер становится затруднительно. А чем больше бессонных ночей — тем больше кошмаров (фантомов) и чаще дожди. По пути еще добавил прав на безобидные команды WorldEdit, о которых не думал раньше, и расширил разрешенную область защиты для игроков в плагине WorldGuard.

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

При десяти одновременных игроках стало понятно, что глобальный чат — это серьезная проблема. Так на сервер пришел плагин EssentialsXChat, который принес локальный чат, в котором игрок говорит на 50 блоков вокруг себя, и глобальный чат, который слышат все на сервере, безотносительно местоположения.
Помимо этого, в чате появилась цветовая дифференциация: зеленый ник — обычный игрок, оранжевый ник — админ, белый текст — глобальный чат, серый текст — локальный чат, фиолетовый чат — личные сообщения.
Чуть позже я установил InteractiveChat, чтобы добавить — простите за каламбур — интерактивности. Теперь по нажатию на ник игрока в чат автоматически подставлялась команда (/msg playername), что сильно упрощало личное общение.
Кажется, что первые базовые потребности были легко удовлетворены.
«Фабрика должна расти!»

Первые тревожные звоночки для облачного сервера прозвучали, когда игроки стали автоматизировать свой труд. Вот, например, небольшая ферма из 96 куриц, по 24 в каждом блоке. Они очень эффективно несут яйца, но не менее эффективно нагружают сервер, ведь каждая курятина — отдельная сущность с собственной логикой, которую просчитывает сервер.
Слева на скриншоте — ферма из 20 овец, а рядом был загон на более чем 200 коров. Суммарно все фермы одного игрока добавляют около пятисот дополнительных сущностей. А такие базы делает не один игрок.

Как отмечалось ранее, игровой сервер просчитывает все события в одном потоке и старается делать это 20 раз в секунду. В облаках не используются хитрые технологии типа TurboBoost, которые разгоняют тактовую частоту ядер, поэтому vCPU с 2,45 ГГц вскоре перестал справляться и TPS (количество тактов в секунду на игровом сервере) начало проседать с 20 до 19, а в какой-то момент дотянулось и до 16. Играть все еще возможно, но не так классно, как при 20 TPS.
Когда TPS падает меньше определенной отметки, сервер начинает отказываться от просчета некоторых менее важных механик. Например, на сервере 2b2t настолько много игроков, что TPS там не поднимался выше 12. Из-за этого на сервере отсутствовал естественный рост деревьев на старой версии.
Ну, попытка — не пытка, облачный сервер не очень подходит для Minecraft. По примерно той же цене я выбрал выделенный сервер конфигурации AR44-NVMe (AMD Ryzen 9 7950X 4,5 ГГц, 128 ГБ RAM, NVMe-диски на 2 ТБ). Да, никакой облачной гибкости, зато неудержимая выделенная мощь.
Переезд занял несколько часов, а даунтайм игрового сервера — около получаса. Я настроил локальную сеть между выделенным сервером и облачным, перенес все игровые серверы на физический, а на облачном оставил прокси. Теперь точно хорошо.
Путь порядка

Конечно, не все игроки хотят играть честно. Один из самых простых читов — X-Ray, который делает «обычные» блоки прозрачными, что позволяет видеть алмазы сквозь толщу породы. Хотя на скриншоте набор ресурсов, который делает блоки прозрачными, это все равно дает нечестное преимущество. В более продвинутых случаях есть клиенты с «самонаведением» до ближайших алмазов. Следить за всеми игроками — это заведомо проигрышная стратегия.
Тут мне попалось, что в ядре Paper есть несколько реализаций функций anti-X-ray, которые усложняют жизнь читерам. На скриншоте работа этой функции: сервер генерирует ложную руду в местах, где игрок с «нормальным» клиентом видеть не может.
Наличие такой прекрасной функции прямо в ядре сервера меня порадовало настолько, что я решил переезжать на Paper, раз его все хвалят. Может еще и в производительности выиграю.
Но знаете, кто проиграл? Игроки, которые советовали перейти на Paper. Почему? Paper позиционирует себя как более производительный, стабильный и продвинутый сервер, в котором исправили механику дюпа, то есть удвоения предметов из-за бага. А эта механика использовалась в некоторых фермах игроков.

Мы стараемся поддерживать мир, труд и дружбу, но не все разделяют наши ценности. Для кого-то грабеж, читерство и разрушения — последний оплот радости и веселья. Я не хотел, но для более-менее мелких проступков пришлось сообразить небольшую исправительную зону. Новых плагинов не потребовалось, EssentialsX решает эту задачу.
К счастью, пользоваться банхаммером приходится реже, чем созидать…
«Запасной» сервер
После перехода на другое ядро выяснилась довольно неприятная особенность. При перезагрузке игрового сервера Paper просто отключает всех игроков по причине «Сервер перезагружается». А вот ядро Spigot «перебрасывало» всех игроков на сервер по умолчанию, то есть в Лобби. Конечно, при плановых перезагрузках можно использовать команду /send и временно отправлять всех игроков на другой сервер, но это дополнительные ручные действия, от которых хочется отказаться.
К счастью, есть плагин FallBackServer для прокси-сервера, который решает эту проблему. Этот плагин, вне зависимости от причины завершения игрового сервера, «перебрасывает» всех игроков на запасной игровой сервер. Перезагрузка серверов — это неудобства для игроков, но «остаться в игре и попасть на другой сервер» — это меньший дискомфорт, чем вылететь в главное меню с ошибкой «Попробуйте переподключиться через две минуты». Более того, этот плагин умеет возвращать игроков с временного сервера обратно на основной, когда тот вернется в строй.
При настройке FallBackServer я понял, что переносить все игровые сервера на «дедик» было поспешным решением. Я вернул Лобби на облачный сервер — теперь даже в случае перезагрузки физического сервера игроки смогут попасть в игру.
Это позволяет мне более комфортно устанавливать обновления. Достаточно предупредить игроков, что через некоторое время будет обновление и перезагрузка сервера.
Помощь и взаимовыручка

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

Второй неиграбельный персонаж, Гюнтер, за игровые ресурсы предлагает расширение возможностей. Например, по умолчанию игрокам доступно семь регионов в плагине WorldGuard. В начале игры это расширение совершенно не обязательно, но чем дольше играешь, тем больше баз и аванпостов в мире нужно «приватить». Это одновременно позволяет ограничить «новичков», которые пришли ломать сервер, и дать волю «старичкам», которые играют давно.
Закрытие креатива

Развитие Выживания шло хорошо. Чего не скажешь про сервер с неограниченными ресурсами на строительство. Я не питал надежд, что люди тут же бросятся строить лучшие строения из великих фандомов. Но я до конца верил, что всё будет не так плохо.
Первые игроки, которые заходили, когда игровой сервер был в облаке, построили вот такую конструкцию для одновременного открывания нескольких десятков дверей. Эта конструкция не сработала — и тогда они создали в мире очень много вагонеток, из-за чего игровой сервер начал подтормаживать.

На креатив я чаще заходил откатывать очередные «эпические» идеи. Последней каплей креатива стала вот эта постройка. Те, кто догадываются, что тут планируется, наверняка скажут «Ха-ха, классика». Если вы не догадываетесь — это механизм для массового нанесения нравственных и физических страданий внутриигровым овцам. Итого оскорбительного и непристойного стало достаточно, чтобы закрыть публичный креатив.

Закрытие креатива я отразил визуально в Лобби. Рамка портала разрушена и горит, а на обломках стоят отсылки: стержень Края и овечка. Однако игроки на этом не успокоились и периодически били овечку. Конечно, я предусмотрел это — теперь овечка бессмертна. Но все равно как-то обидно.
В своем Telegram-канале я писал про эту историю, а также про некоторые особенности создания и распространения плагинов для игры. Подписывайтесь, там можно увидеть заметки по темам статей, над которыми я работаю, и небольшие познавательные посты.
С добавлением неиграбельных персонажей мне пришла в голову потрясающая идея. Вместо обычной овечки без искусственного интеллекта поставить NPC в виде овцы, которая будет реагировать на действия игрока.
Так появилась овечка Облачко, которая смотрит за игроком. Если игрок поговорит с ней (ПКМ), то она скажет, что ей больно вспоминать про креатив. Если же игрок ударит ее (ЛКМ), то Облачко даст сдачи. Смотрите сами:
Что дальше
До сего момента я администрировал сервер «вручную», раскладывая файлы по каталогам. Чем больше разных плагинов, тем чаще что-то обновляется. В общем, пора переставать играть в «перекладывальщика» файлов и применить систему управления конфигурациями по назначению.
«Подождите, у вас же в команде есть DevOps-инженер!» — скажете вы. Да, я указал наши должности на работе, но в этом проекте все иначе. Я — разработчик, выполняю функции технического админа, а мой коллега-DevOps занимается внутриигровым порядком в мое отсутствие. И так как обновление 1.21.8 уже настоялось, скоро мы обновим и наш сервер.
В отличие от других серверов, я придерживаюсь мнения, что нужно жить без вайпов (полного сброса всего игрового процесса) максимально долгое время. Донатов не было пять лет и не будет дальше.
Но теперь, когда я набил собственные шишки, пора заглянуть на другие серверы и посмотреть, насколько там токсично, дорого и весело. Так что я еще вернусь к вам со статьями по Minecraft. А пока — увидимся на сервере Selectel!
Комментарии (0)
Jijiki
15.09.2025 13:33интересно и классно, я всё не могу никак доделать кубики эти, как я понял ядро спигот написана на яп java
opengl 1 hello world ну по крайней мере где-то видел обзор что из-за старости APIшек java версию не запустить в дебагере, в то время когда бедрок вроде дебажится
0x00FA7A55
А вы случайно не разбирались как затолкать эту историю в куб и приделать сверху балансировку? Я видел давно какие-то приблуды для запуска несколько инстансов сервера как одного, но всё это было сомнительного качества.
iveahugeship
Хоть кому-то, кроме меня, пригодится. Я написал helm-chart'ы - https://github.com/iveahugeship/minecraft-helm-charts. Есть и для основного сервера, и для прокси, поддерживаются разные ядра, бэкапы, автоустановка модов, плагинов и модпаков, их конфигурация.
Не понял только что имеется в виду под балансировкой. Прокси? Туннели? Для прокси, опять же, есть helm-chart выше. Туннели - можно попробовать использовать Gate Proxy в Lite режиме. Но работают так себе. В качестве альтернативы использую другой чарт - https://github.com/itzg/minecraft-server-charts/tree/master/charts/mc-router. Сервис для mc-router с типом NodePort. Сам роутер на какой-нибудь ноде с белым ip. Домены - через тот же duckdns прикрутить.
В общем, я для своего сетапа использовал k3s, свои чарты, чарт mc-router. Запущено все на одной ноде с белым ip. К нему же A-записи через duckdns. Ну и в целом ок.
@Firemoon приветы старым друзьям, одобрите ссылочку, пожалуйста :)
И спасибо за статью!
Firemoon Автор
«Запихать в куб» — это как будто не самая сложная задача. Но я любитель запускать на железе, поэтому без кубернетеса х)
Что касается расширения одного мира на несколько серверов — вроде есть MultiPaper и у него написано, что это форк Purpur'а, который тоже так мог. Балансировать между серверами может хоть прокся (Bungeecord/Velocity), хоть по DNS на разные серверы отправлять.
Но я как-то не очень оптимистично смотрю на эти извращения, потому что, мне кажется, обязательно где-нибудь что-нибудь отвалится. Folia, пытающийся в многопоточность — в бете, MultiPaper в бете и с ним несовместимы обычные плагины.
В какой-то момент кажется, что проще сделать несколько серверов на ~200 игроков с драконовскими ограничениями на количество сущностей в мире. Ну по крайней мере с высоты сегодняшнего опыта мне так кажется