Достойный противник: как устроен ИИ в файтинге Shadow Fight 3

Расчёт оптимальных ударов и система обиды и прощения.

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

Старший геймдизайнер Banzai Games Михаил Драговаловский в колонке для DTF рассказал про опыт работы над искусственным интеллектом для мобильного файтинга Shadow Fight 3.

Достойный противник: как устроен ИИ в файтинге Shadow Fight 3

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

Отличие Shadow Fight 3 от большинства файтингов

Серия Shadow Fight сразу создавалась с рядом фич, которые отличают её от многих файтингов:

  • наличие автоблоков. Если персонаж просто передвигается и не атакует, он автоматически блокирует любую обычную атаку противника;

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

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

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

ИИ в предыдущих играх серии

Мы уже работали над ИИ в нашем предыдущем файтинге — Shadow Fight 2, но из-за перехода в 3D, появления коллизий между игроками и добавления теневой формы мы смогли перенести только часть логики ИИ, а остальное пришлось создавать заново.

С чего стоит начать работу над ИИ

Если вы не делаете бота с помощью машинного обучения, я бы выделил два «капитанских» подхода:

  • сделать слабого бота, потом усилить до нужного уровня новыми фичами;

  • сделать непобедимого бота и потом ослаблять.

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

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

Как устроен наш ИИ

Триггеры или правила поведения

В основе лежат правила, в рамках которых бот совершает случайные действия. Эту систему правил мы называем триггерами. Например:

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

  • бот не спамит метательным оружием;

  • бот получает в лоб метательным оружием врага, а затем начинает гарантированно уклоняться в течении какого-то времени;

  • и ещё куча вещей, которые бот должен или не должен делать.

Если выпустить такого бота против новичка, при равном уровне прокачки исход будет зависеть от оружия, которыми вооружены оппоненты. У кого быстрее анимации, тот и победит. Потому что, по сути, оба жмут на все кнопки. Ну разве что бот делает это чуть более осмысленно.

Принятие решений

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

  • враг ждёт;

  • враг атакует.

Решения тоже два:

  • нужно бить, когда гарантированно попадёшь;

  • нужно блокировать, когда по тебе бьют и ты не можешь контратаковать.

Получается, что для победы ИИ должен прерывать вражеские удары своими контратаками, либо блокировать, если не может их прервать.

Мы сделали две группы решений, которые принимает бот: одна — если противник стоит, другая — если противник атакует. Чтобы ИИ знал, чем именно контрить, мы придумали таблицы коллизий.

Таблицы коллизий

Помните, как Доктор Стрэндж просматривал все возможные варианты исхода битвы с Таносом? Примерно так и работают таблицы коллизий: компьютер заранее просчитывает исходы для каждой атакующей анимации в игре на каждой возможной дистанции.

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

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

В результате ИИ эффективно реагирует на действия игроков. То есть с контратаками разобрались. Теперь нужно научить бота самого атаковать оптимальным способом, а не рандомными ударами.

Выбор дистанции и правильного удара

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

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

  • собираем статистику всех ударов игрока;

  • смотрим, на какой дистанции у нас больше всего эффективных контратак против типичных его ударов;

  • передаем эту дистанцию боту и заставляем его держаться на ней на протяжении всего боя.

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

Достойный противник: как устроен ИИ в файтинге Shadow Fight 3

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

Обида и прощение

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

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

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

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

Задержка

У каждого бота в Shadow Fight 3 есть задержка при принятии решения. Это параметр, который заставляет бота делать паузу в некоторое числокадров перед выбором варианта действия.

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

Проверка условий

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

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

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

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

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

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

Сейчас мы более-менее довольны результатом: боты ведут себя разнообразно, адаптируются под стиль игры пользователей, иногда наказывают, иногда тупят. Почти как люди.

Три совета на случай, если будете разрабатывать ИИ

  • Разложите кор-геймплей вашей игры на ситуации и решения. Это задаст вам направление, в котором стоит придумывать фичи для создания ИИ.

  • Много плейтестите бота. Без этого вы будете двигаться вслепую и допускать много ошибок.

  • Закрывайте сперва самые частые ситуации. Не нужно углубляться в специфические случаи, пока не решены самые часто встречаемые ситуации.

8181
23 комментария

Не знаю что там с ИИ, но год назад в неё невозможно было играть практически с начала игры из-за то ли повышенной сложности, то ли прокачки через лутбоксы. Выиграл такой у пары противников в режиме истории, но следующий тебя выносит за три удара, а тебе надо нанести штук 30. Идёшь в рандомные бои что бы доставать лутбоксы и открывать их ради карточек вооружения, которыми и качаешься. У меня сложилось впечатление что от меня чуть ли не в начале игры требуют покупать лутбоксы, даже толком не давая поиграть спокойно. Геймплей, анимация и графика прям понравились, но прокачка лутбоксами и требования денег уже в начале игры прям расстроили. Естественно удалил и больше не играл. Зачем так было делать я хз. Вот вторая часть денег начинала просить плавно, а это прям в начале тебе говорит мол купи лутбоксов, а то дрочить рандомные бои придётся долго.

17
Ответить

Вот, явно ты статью не так внимательно читал :)
Не вдонатил - ии на тебя обиделся и лупит почём зря.
Внёс трудовую копеечку - ии тебя прощает.

11
Ответить

Не, это та же система, что и в новых Ассасинах - уровень шмота. Для прохождения истории нужно постоянно и долго неистово дрочить другие режимы по возможности, повышая карточки с лутбоксов, и потом уже, смотря какой уровень сложности тебя устроит, идти дальше по истории. Или куплять "экономию времени". Жоско там все на этом заточено, но, с другой стороны, рандом бои всегда открыты и подбирают там почти всегда оптимальных по силе ботов, так что все уравновешено в наш 21 век донатов

Ответить

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

6
Ответить

Может не внимательно читал, но не нашел ситуации когда ии бьет на опережение.

Например игрок бежит к ии. Ии заранее начинает делать удар зная что игрок сам подскочет в нужное место там где будет кулак.

Таблицы коллизий разочаровали. Часто играя в файтинги против ии создается ощущение что тебе просто разрешили выиграть.

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

Так же не понятна градация степени сложности на 9 классов. В Шадоу файт же есть прокачка. Мне кажется что ии должен играть всегда одинакого т е например ии гарантировано наносит 10 ударов +-3 случайных и +-5 в зависимости от мастерства игрока. Тогда слабо прокачанный игроки сольются после определенного момента и выглядеть это будет так как будто просто не повезло.

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

Получается игроку купил не доспех, а заказал лоботомию противнику.

Игру играл мало и давно, но впечатления тогда были такими.

2
Ответить

1) На счет атак на опережение: ИИ учитывает статистику ударов игрока и предполагает какие из его собственных ударов скорее всего будут успешными и наносит их. При этом если игрок просто блокирует, то ИИ не получит какого-то преимущества, а вот если игрок будет отвечать своим типичным ударом, ИИ скорее всего прервет его атаку.

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

3) На счет связи прокачки и ИИ: её нет, т.е. если игрок покупает новые доспехи и оружие он побеждает потому что стал сильнее бить, а не потому что бот стал тупее. Если вы это имели ввиду, конечно :)

2
Ответить

Я проставил всем плюсики за очень интересный кейс, который не был освещён в рамках статьи, но оказался "разложен по полочкам" в комментах.
Спасибо.

2
Ответить