Рубрика развивается при поддержке

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

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

В закладки
Аудио

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • враг ждёт;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Задержка

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

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

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

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

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

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

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

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

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

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

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

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

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

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

{ "author_name": "Андрей Верещагин", "author_type": "editor", "tags": ["\u0438\u0438","\u0433\u0435\u0439\u043c\u0434\u0438\u0437\u0430\u0439\u043d"], "comments": 22, "likes": 62, "favorites": 90, "is_advertisement": false, "subsite_label": "gamedev", "id": 61808, "is_wide": false, "is_ugc": false, "date": "Wed, 31 Jul 2019 18:18:49 +0300", "is_special": false }
0
{ "id": 61808, "author_id": 22254, "diff_limit": 1000, "urls": {"diff":"\/comments\/61808\/get","add":"\/comments\/61808\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/61808"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 64954, "last_count_and_date": null }
22 комментария
Популярные
По порядку
Написать комментарий...
17

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

Ответить
11

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

Ответить
1

Во многих топовых играх такое делается на уровне мачмейкинга.

Ответить
1

Внёс трудовую копеечку - ии тебя прощает

Прощает, но не надолго. Донатил и помогает слабо. Через маленькое количество времени ИИ снова требует денег)))
Зашёл к ним в гугл плей и там по ходу всё по старому и возможно даже хуже, так как куча коментов что всё похерили с балансом и сложность.

Ответить
0

Поржал :)
Евгений, приходите к нам геймдизом монетизации

Ответить
0

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

Ответить
6

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

Ответить
2

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

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

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

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

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

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

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

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

Ответить
2

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

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

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

Ответить
3

По пункту 2) я так понял что речь идет не о компании, а об имитации онлайна на основе статистики боев которые проводят реальные игроки. Если это так, то теперь все ясно, спасибо.

Ответить
1

Насчет 3-его вопроса, я думаю подразумевалось следующее:

Вот есть слабый игрок, с плохим скиллом. Он, допустим, наносит 100 урона. И, предположим, компьютер поставил ему сильного бота, который его делает на раз. У игрока получается снять боту только 10-30 процентов хп.
Разозленный игрок идет в магазин и покупает предмет, который добавляет ему +50 урона, или даже 100. Это крутой предмет, потому что усилил игрока аж в 2 раза.
И теперь возвращаемся обратно в бой. При точно таких же обстоятельствах, которые были до покупки, бот бы опять победил, но ему бы уже было нанесено 60 процентов урона. НО ПРОИСХОДИТ НЕ ЭТО. Происходит то, что бот видит, что прошлая игра была проиграна, СНИЖАЕТ сложность - благодаря чему игрок побеждает. И ВЫГЛЯДИТ это таким образом, что игрок купив шмотку сразу же на изи победил - Pay to win, хотя на самом деле (судя по вашей статье) это совсем не так.

Как это решать?

Ответить
5

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

Давайте сперва определимся о каких боях идет речь. У нас есть:
- кампания (бои против противников с заданной силой);
- дуэли (бои против персонажей других игроков под контролем ботов);

Рассмотрим среднего игрока — DESTROER_228, у него 1000 рейтинга, сила 100

1. Кампания. Наш DESTROER всегда знает с кем будет сражаться. Например, застрял на боссе, за которого играет БОТ#3. Не важно выиграл или проиграл игрок, купил он предмет или нет, каждый раз игрок будет идти в бой против соперника той же силы, с тем же БОТОМ#3.
Просто если игрок меняет тактику, бот будет тоже немного менять тактику, но его сложность остается постоянной. Это значит, что DESTROER пройдет дальше только если у него вырастет скилл или сила со 100 поднимется до 120, например.
Скилл бота при этом остается прежним.

2. Дуэли. Тут заранее не знаешь кого тебе подберет матчмейкинг.
Решил наш DESTROER_228 поиграть в дуэли, чисто сундучков пофармить.
Ему подбирают противника — 1010 рейтинга, сила 80 (так получилось, были другие противники, но рандом выпал именно на этого). Это значит, что есть какой-то скилованный игрок, который со своими 80-ю единицами силы дошел до 1010 рейтинга. В этом случае, мы говорим: окей, это крутой противник, значит за него будет играть крутой БОТ#6.
Начинается бой, наш DESTROER проигрывает. Злится, идет покупает шмотку, становится 120 силы. Идет снова в дуэли, а там подбирают игрока 990 рейтинга, 120 силы. Мы говорим — это вполне стандартный игрок, может даже чуть ниже среднего, значит за него будет играть БОТ#2.
DESTROER его выигрывает на скилле.
Значит ли это, что мы подстроили что-то? Значит ли, что тут есть pay2win? Думаю нет, потому что точно также ему мог снова попасться скилованный противник и снова победить игрока.

Такие дела :)

Ответить
3

Спасибо за столь подробный ответ!

Да, я со своей стороны прекрасно понимаю, что ситуация 2 совершенно не является Pay2Win. Я лишь хочу сказать о том, что это может ВЫГЛЯДЕТЬ как pay2win со стороны этого нескилованного игрока, который купил шмотку.
Он же потом друзьям будет рассказывать, "вот, я пошел в дуэльки играть, победить не мог, а тут купил шмотку, и сразу размотал"
Я думаю, в такой ситуации сильно помогает, если DESTROER видит рейтинг и силу противника: "Ага, вот у меня рейтинг 700, а у этого чувака 1000, ппц он катает! Но у него силы 100, а у меня 120, может я его и завалю!".

Ответить
2

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

Ответить

Комментарий удален

1

Зашёл глянуть на отзывы в гугл плее и не ожидал что там прям так гнобят разработчиков. Хм, наверное правильно что я в игру больше не играл.

Ответить
4

Хз что там с игрой, но смотреть отзывы на гугл плее такое себе) Там большая часть будет от детей, которые даже писать правильно не умеют)
Большинство претензий вообще сводится к тому, что "всё классно, только вот сделайте мне полную версию бесплатной/без рекламы, а раз предлагаете мне игру купить, то вот вам единица"

Ответить
0

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

Ответить

Комментарий удален

1

Редакция, у вас джинсы порвались!
А вообще - сейчас на мобилках катаю в RAID, нормальная такая игра. ПоЕ напоминает

Ответить
0

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

и получает переворот с прогиба. Эти боты вообще не дают к ним приблизиться, ДЖОННИ, бей их издалека и так весь матч. На этом конец

Ответить
0

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

Мы сделали несколько доработок, чтобы сгладить негативные ощущения:
- задержка в принятии решений (она распространяется и на броски тоже);
- сокращенная дистанция броска для бота;
- кулдауны на броски у бота.

Ответить
0

Гифки с кошками супер

Ответить
0

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

За статью спасибо, полезная инфа.

Ответить

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fizc" } } }, { "id": 4, "label": "Article Branding", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "cfovz", "p2": "glug" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-250597-0", "render_to": "inpage_VI-250597-0-1134314964", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=clmf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Баннер в ленте на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudo", "p2": "ftjf" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvc" } } } ]