Найти тему
Tracher

Балан в WoT blitz

Оглавление

Как устроен балансировщик команд в World of Tanks Blitz

WoT Blitz — это мобильный танковый шутер, в котором игроки сражаются в формате 7 на 7.

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

У танков есть следующие важные для матчмейкинга параметры:

  • Уровень. В зависимости от уровня, у танков меняются различные характеристики (например, скорость, бронепробитие). На 1-ом уровне — самые слабые танки, на 10-ом — самые сильные.
  • Тип. В WoT Blitz существует 4 типа танков: лёгкий, средний, тяжёлый и ПТ-САУ (противотанковые самоходные артиллерийские установки)

Самая простая реализация матчмейкера — закидывание игроков в команды случайным образом. Но в данном случае у игроков на низких уровнях не будет никаких шансов нанести хоть какой-то урон, и играть станет неинтересно.

Требования

Список требований к балансировщику был сформирован на основе фидбека от игрового сообщества и периодически обновляется по сей день.

На момент написания статьи для обычных боёв список состоял из следующих пунктов:

Список требований к балансировщику

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

Балансировщик формирующий пары игроков

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

Начало боя

Поэтому был написан другой балансировщик, который работал по следующему алгоритму:

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

Получившийся балансировщик работал быстрее прошлой версии в 5-10 раз и изначально собирал команды, которые соответствовали всем имеющимся на тот момент требованиям. Новые правила добавлялись путём написания дополнительных проходов перебалансировки.

В начале всё работало хорошо. Но со временем, чем больше правил добавлялось, тем сложнее было написать перебалансировку. Новые перебалансировки должны были в результате своей работы не поломать работу предыдущих. Стало понятно, что это путь в никуда.

Балансировщик на основе имитации отжига

В конечном варианте мы остановились на балансировщике, который работает по следующему алгоритму. Все игроки, которые нажимают кнопку «В бой», попадают в общую очередь. Балансировщик в бесконечном цикле делает следующее:

  • Выбирает случайные параметры боя (случайный уровень боя (от 1 до 10), случайный режим, случайную карту);
  • Находит в очереди всех игроков, которые подходят по выбранным выше критериям (зашли в бой на танке подходящего уровня, имеют включённым выбранный режим, имеют загруженную выбранную карту);
  • Пытается сформировать команды, удовлетворяющие всем перечисленным выше требованиям (описание ниже);
  • Если удалось сформировать команду, выкидывает этих игроков из очереди ожидания и стартует бой.

Для формирования команд из списка подходящих игроков используется метод имитации отжига. Подробнее про сам метод можно почитать тут.

Поиск глобального максимума методом имитации отжига

В контексте применения к формированию команд алгоритм следующий:

  • Стартует с двух пустых команд;
  • На каждой итерации случайным образом изменяет состояние команд. Для этого делает одну из следующих операций:
  • Добавляет случайного игрока из списка подходящих игроков в первую или вторую команду (команду тоже берём случайную);
  • Удаляет случайного игрока из случайной команды;
  • Заменяет случайного игрока из списка подходящих на одного из существующих в первой или второй команде;
  • Меняет случайного игрока из первой команды на случайного игрока из второй команды.
  • Получает оценку получившегося состояния. Для этого вызывает оценочную функцию. Функция проходит по списку требований и за нарушение каждого из пунктов увеличивает штраф. Чем сильнее нарушен пункт, тем выше штраф. Например, штраф за команду размером 2x2 будет выше, чем штраф за команду размером 6x6;
  • В зависимости от изменения значения оценочной функции и текущей температуры, определяем вероятность перехода в новое состояние;
  • Продолжаем процесс, пока либо температура не достигнет заданной минимальной, либо значение оценочной функции не достигнет нуля (в этом случае все требования удовлетворены и можно запускать бой).

Основное преимущество данного подхода: для добавления новых требований достаточно модифицировать оценочную функцию. Нет необходимости писать код, который будет описывать, как именно получить то, что мы хотим. Достаточно добавить правило, которое смотрит на сформированную команду и говорит, хорошо ли она сбалансирована или нет.

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

  • Команды должны быть сбалансированы по рейтингу (разница в суммарном рейтинге игроков между командами не должна превышать заданного значения);
  • Разница в рейтинге между игроками должна быть минимальна (игроки из бронзовой лиги не должны попадать в бои с игроками из бриллиантовой).

Пример профиля игрока из бриллиантовой лиги

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

Недостаток данного подхода — медленная скорость работы. По сравнению с предыдущим вариантом, текущий стал работать приблизительно в 10 раз медленней, даже несмотря на ряд оптимизаций. Кстати, про оптимизации. Большая часть сервера (кроме сети и физики) для игры написана на Python. Балансировщик был переписан на C++ и распараллелен на много потоков. Из Python в плюсовый код прилетает запрос на формирования команды. Далее каждый из потоков независимо стартует метод отжига. Как только какой-то поток находит решение, остальные потоки останавливают процесс поиска, и найденное решение возвращается в Python.

Время ожидания и размер очереди на RU сервере (5 секунд в обычных боях и 10 в рейтинговых)

По мере роста онлайна росла и нагрузка на балансировщик. Этой осенью, когда онлайн на RU сервере добрался до 120 тысяч (во время ивента Mad Games), балансировщик перестал справляться. В качестве временной меры мы отключили часть правил, это позволило уменьшить нагрузку. Чтобы избежать подобных проблем в будущем мы сделали матчмейкер распределённым.

Рейтинговая система

Лучшие игроки в бриллиантовой лиге, 21 апреля 2019

Во многих ММО играх, кроме случайных боёв, существуют также и рейтинговые / ранговые / etc. Основная идея данного режима: противники ищутся не случайные, а подходящие по скилу. Если ты скиловый игрок, ты будешь играть с такими-же скиловыми игроками, и наоборот, если ты не умеешь играть, ты будешь попадаться против таких же новичков.

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

Для реализации рейтинговых боёв понадобилось решить сразу две задачи. Во-первых, нужно было выбрать рейтинговую систему (по какому принципу начислять игрокам рейтинг). Во-вторых, нужно было доработать балансировщик, чтобы он собирал бои с учётом ограничений по рейтингу.

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

Точность считалась следующим образом:

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

Наиболее популярные системы расчёта рейтинга: winrate, Elo, Glicko, TrueSkill. Winrate — обычный процент побед. Elo — система подсчёта рейтинга, изначально созданная для игр с участием двух человек (шахматы, etc). В этой системе игроку за победу / поражение даётся / отнимается некоторое количество очков в зависимости от рейтинга противника. Glicko в целом похожа на Elo, но кроме этого учитывает, сколько времени игрок был не активен. TrueSkill — запатентованная рейтинговая система от Microsoft, в которой у каждого игрока есть два параметра: рейтинг и уверенность системы в этом рейтинге.

Во время разработки первой версии рейтинговых боёв мы рассматривали winrate и Elo (несколько вариантов, адаптированных к командной игре), а также простую систему Score (в которой игрокам всегда давалось фиксированное количество очков рейтинга за победу и отнималось за поражение).

Наилучшие результаты показала система Elo, в которой Ra — рейтинг игрока, а Rb — разница между суммарным рейтингом команды противника и суммарным рейтингом команды игрока за исключением самого игрока.

Основные трудности, с которыми мы столкнулись после запуска:

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

Первую проблему полностью решить не удалось из-за того, что скиловых игроков слишком мало, им приходится долго ждать, пока начнётся бой, и очень часто видеть в своих командах игроков послабее. Для смягчения эффекта мы сделали доступными рейтинговые бои только в прайм-тайм (то есть в то время, когда на серверах играет максимальное количество людей).

Вторую проблему мы решили, введя замедляющий коэффициент (то есть чем дальше игрок от среднего рейтинга, тем сложнее ему подниматься или опускаться ниже).

  • Также мы пробовали различными способами улучшить качество рейтинговой системы. В первых версиях для изменения рейтинга мы использовали только информацию о победе / поражении. Но у нас командная игра, и не всегда хорошие действия одного конкретного игрока приводят к победе всю команду. То есть даже в случае, если игрок хорошо играл, а команда проиграла, этот игрок получал такой же минус к рейтингу, как и все остальные игроки. Чтобы это предотвратить, мы стали пробовать учитывать индивидуальные действия игрока в бою.

Для этих целей мы пробовали применить машинное обучение: собрали различные факторы и пытались обучить модель предсказывать победу / поражение команды по действиям игрока в бою, чтобы потом использовать эту модель для определения коэффициента бонуса к рейтингу (то есть если команда проиграла, но поведение игрока было похоже на поведение игроков-победителей, давать таким игрокам дополнительный бонус).

Игрок из победившей команды который сыграл хорошо получил +40 к рейтингу. А который плохо всего +10

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

В итоге мы отказались от ML-модели и взяли более простую ручную формулу. Эта формула учитывает только боевой опыт без учёта бонусов за победу, x2 и прочих. Она даёт весьма достойный результат, хоть он и слегка ниже, чем у ML модели.

Заключение

  • Балансировщик на основе метода имитации отжига позволил нам перейти от описания решения (как именно собирать команду) к описанию требований (какие условия не должны нарушаться);
  • В командных рейтинговых боях хорошо себя показала модифицированная система Эло, учитывающая индивидуальные действий игрока в бою;
  • Не всегда стоит применять сложные методы машинного обучения (особенно, когда важна интерпретируемость и понятность результата человеком).