← Все новости

Оптимизация сервера

Завершили крупный этап оптимизации: сервер стабильнее работает при распределённой нагрузке и массовых сражениях.

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

С чего начали

Когда игроки рядом, они делят общие чанки, и сервер неплохо справляется даже с большой толпой. Проблемы начинались, когда игроки расходились по карте. Всего 45 имитаций игроков в радиусе 2 000 блоков давали 19,96 TPS, 29,6 мс avg и 50,0 мс p95. Сервер был на грани стабильных 20 TPS, хотя многие ядра процессора простаивали.

Причина в том, что большая часть логики Minecraft выполняется последовательно на главном потоке. Чем шире игроки разбросаны, тем больше чанков и сущностей приходится обрабатывать по очереди.

Что изменили

Активные чанки. Moonrise (один из наших основных модов оптимизации) раньше каждый тик заново обходил мир в поисках активных чанков. Теперь их список обновляется по событиям: при движении игрока, изменении чанк-билета или состояния чанка. Это снизило стоимость обработки чанков примерно на 25%.

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

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

Дополнительно:

  • сохранение делает снимок данных в тике, а сжатие и запись выполняются отдельно;
  • состояние природного спавна собирается за один проход вместо нескольких;
  • далёкие существа реже выполняют проверки, не влияющие на игроков;
  • массовый вход после рестарта обрабатывается небольшими группами;
  • пакеты получают только игроки, наблюдающие нужную область, а повторяющиеся обновления объединяются.

Например, при 25 игроках один пакет синхронизации отправлялся около 1 025 раз в секунду, а теперь около 24.

Результаты

Тесты проводились в прогруженном мире с дальностью прорисовки 12 чанков и симуляции 6:

  • 200 игроков в компактной области (радиус 300 блоков): 22,69 мс avg, 29,23 мс p95
  • 200 игроков равномерно в радиусе 2 000 блоков: 26,58 мс avg, 37,10 мс p95
  • 500 игроков группами по 6–7 человек: 35,80 мс avg, 46,62 мс p95
  • 575 игроков группами по 6–7 человек: 39,18 мс avg, 49,22 мс p95
  • 750 игроков в восьми крупных скоплениях: 40,34 мс avg, 48,28 мс p95

Главный результат: 200 равномерно распределённых игроков теперь нагружают сервер меньше, чем раньше 45. Наибольший прирост получился именно там, где серверу было хуже всего.

Массовые сражения

У рекрутов мы переработали поиск противников, построения, ближний бой и поведение неактивных бойцов. Стресс-тесты в полном контакте:

  • 1 000 против 1 000: 10,77 мс avg
  • 1 500 против 1 500: 15,61 мс avg
  • 2 000 против 2 000: 18,81 мс avg

Даже при 4 000 сражающихся рекрутах среднее время тика остаётся значительно ниже 50 мс.

Клиент

Главной нагрузкой в массовых битвах были повторная сборка моделей, лишние проходы экипировки и множество одинаковых текстур. Теперь:

  • повторяющиеся скины собраны в общий атлас, и клиент реже переключает текстуры;
  • пустой слой ткани больше не создаёт отдельный проход рендера;
  • часть повторных клиентских проверок боевой системы объединена;
  • лишние проверки коллизий пропускаются.