Gamedev chelovekbeznika
2 307

"Объясняю каждую строчку" - отчёт за март месяц

chelovekbeznika В динамике выглядит чуть лучше, правда. Придётся учиться пилить гифки.
В закладки
Аудио

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

Что тут происходит?

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

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

Присоединиться к веселью:

Присоединиться к веселью по настоящему:

Присоединиться к сообществу:

Следующий эфир в понедельник, в 20:00.

И что есть на данный момент?

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

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

Чё так мало?

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

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

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

Статистика

  • 12 стримов и один маленький, тестовый, на полчасика
  • 1 день, 8 часов, 13 минут, 23 секунды видео, где я отважно программирую, борясь с особенностями языка, особенностями фреймворка и своей глупостью
  • 2 часа, 28 минут, 43 секунды - средняя длительность видео
  • 646 строк кода на данный момент есть в проекте, если не врёт Visual Studio
  • файлов с кодом
  • 26 юнит-тестов, что не очень много, но они все пригодились
  • 46 коммитов в репозитории на гитхабе
  • 46 комментариев к коммитам со ссылкой на видео, где я делаю этот коммит
  • 1 статья на хабре написана по итогам уже случившегося веселья. Если вам интересен язык C#, то вот она: https://habr.com/ru/post/445804/
  • 1 баг на DTF, оказывается, был исправлен. Я о том, что АЛЛИЛУЙЯ, РЕШЁТКА БОЛЬШЕ НЕ ПРЕВРАЩАЕТСЯ В СРАНЫЙ ХЭШ-ТЕГ
  • 1 день рождения на стриме отмечен
  • 1 конкурс проведён
  • 2 сигны выписаны
  • 1 безумный челлендж за донаты назначен. Потому что глупо игнорировать такой инструмент маркетинга. Ну, и потому что это весело.
  • 2 000 000 рублей - цена этого челленджа.
  • 17854 буквы "А" подряд содержит книга, которую я прочитаю полностью вслух на стриме, если случится чудо и эта сумма будет собрана. Хотя вряд ли, конечно, это случится в ближайшее время.

Умные слова, которые услышали те, кто не испугались и не разбежались

Я ещё стрима два назад хотел дать где-нибудь вконтакте список того, что я успел пообъяснять на этих стримах. А тут такой повод. Сразу скажу: за указанными вещами следуйте в описание. Там всё самое интересное отмечено тайм-кодами.

Плейлист на ютубе с уже прошедшими стримами:

  • 1 выпуск - Что такое объект и класс (очень коротко и криво), инкапсуляция, Single responsibility principle.
  • 2 выпуск - Полиморфизм и наследование (тоже так себе, на последующих стримах, на практике было объяснено лучше), обработка исключений
  • 3 выпуск - Наследование (примеры использования + некоторые вопросы с ним связанные), свойства (кусочно)
  • 4 выпуск - Использование уже имеющихся атрибутов в C#, введение в юнит-тестирование, Reference-типы и Value-типы в .NET (ключевое слово struct в C#)
  • 5 выпуск - События и делегаты, перегрузка методов
  • 6 выпуск - Дженерики, которые, увы, начались в этом проекте с немного мозгодробильного примера. И рефлексия, которая в итоге нам не понадобилась.
  • 7 выпуск - Code-convention связанные с событиями, методы расширения и LINQ (Select, Where и чуть-чуть SelectMany).
  • 8 выпуск - Первый стрим, на котором мне не пришлось объяснять ничего нового. Но ссылку на пару мелочей с тайм-кодами я оставил.
  • 9 выпуск - Тоже мелочь. Nullable, опетор ? : и кое-чего нового о делегатах.
  • 10 выпуск - Ошибки округления в вещественных числах.
  • 11 выпуск - Где и как лучше хранить данные, о том, почему предпочёл JSON, о некоторых нюансах глобализации, которые могут больно стукнуть по лбу. Ну и попытался порассказывать о SOLID, (конкретно, о буквах O и L)
  • 12 выпуск - Тронули буквы I и D из SOLID. Натолкнулись на ограничения, связанные с дженериками. К букве I оттуда мы ещё вернёмся на следующем стриме.

Ещё что-нибудь?

Да, хочу спросить у народа, который тут в этих делах более-менее опытный. Где можно набрать звуковых эффектов? Я знаю, что есть места, где можно скачать какой-нибудь прилично звучащий "пыщь-пыщь", за который потом к тебе не приедет зондер-команда копирастов. Но какие из этих мест вы мне посоветуете?

ПыСы: Следующий стрим тут, в понедельник, в 20:00:

Материал опубликован пользователем. Нажмите кнопку «Написать», чтобы поделиться мнением или рассказать о своём проекте.

Написать
{ "author_name": "chelovekbeznika", "author_type": "self", "tags": [], "comments": 50, "likes": 50, "favorites": 77, "is_advertisement": false, "subsite_label": "gamedev", "id": 44921, "is_wide": false, "is_ugc": true, "date": "Sun, 31 Mar 2019 00:22:41 +0300" }
{ "id": 44921, "author_id": 105160, "diff_limit": 1000, "urls": {"diff":"\/comments\/44921\/get","add":"\/comments\/44921\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/44921"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 64954, "last_count_and_date": null }

50 комментариев 50 комм.

Популярные

По порядку

Написать комментарий...
2

Где можно набрать звуковых эффектов?

pikabu.ru/story/16_chudosaytov_s_besplatnoy_muzyikoy_i_zvukami_dlya_razrabotchikov_igr_3977453

/* еле удержался от того что бы топить в этом посте за С/С++ */

Ответить
5

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

Ответить
0

Немного смущает когда тебе рассказывают то что ты и так знаешь 🤔

Ответить
2

Блин, сорян, чё-то меня понесло, да. Но вообще, комментарий не только для тебя писался.

Ответить
0

Надеемся на раст! Он придет!

Ответить
0

разве именно из-за этих причин не юзают шарп?

Ответить
0

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

Ответить
0

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

Ответить
–2

жизнь слишком короткая, чтобы тратить ее на изучения С.

Ответить
3

Чистый Си в сочетании с ассемблером кое-чего мне дал в плане понимания того, как всё на самом дне, или около того работает.

Ответить
0

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

Ответить
0

А, ну в качестве первого, конечно, да =D Хотя, если на каких-нибудь микроконтроллерах поиграться, где вся эта низкоуровневая кухня мала, уютна и близка, может неплохо подойти.

Ответить
0

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

Ответить
0

Не согласен. Свой первый 1000страничный труд по плюсам освоил в 10 классе (первый язык программирования, по сути) без особых проблем, что сильно помогло в учебе в правильном месте. Главное - время + желание, да не пытаться освоить все с наскока по чаще всего дурным статьям в интернете

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

Ответить
0

Си довольно прост и понятен + хорошо вправляет мозги как первый ЯП.

Ответить
1

А можно узна́ть зачем в играх юнит тесты?

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

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

Ответить
4

А как ты ещё проверишь те же столкновения? Чисто на глаз? Чисто на всякий случай: под юнит-тестами понимается код, которые проверяет небольшие части другого кода. И вот для того, чтобы проверить, что код столкновений работает правильно, как ты не распологай два хит-бокса, юнит-тесты идеальны. Ещё один случай: убедиться, что перезарядка работает правильно даже в тех случаях, когда у нас пять-десять кадров в секунду. Да и просто убедиться, что важные тебе части кода работают правильно, перед тем, как их использовать, явно будет не лишним.

Ответить
–4

Отлично т е вы считаете что любой код нужно проверять другим кодом? Тогда нужны юнит тесты которые будут проверять правильно ли работают другие юнит тесты, ведь это тоже код.

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

Что касается столкновений при низком фпс, то конечно интерполяция позиций.

Если все написано правильно, то будет работать при любом раскладе.

Ответить
3

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

Ответить
0

А как вы будете проверять, правильно ли написано-то?

Ответить
0

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

Ответить
–1

Прочитать то я прочитал, но где это использовать в играх? Допустим я пишу походовую стратегию.

Ошибки бывают либо синтаксические, просто не компилится,

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

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

Причем это "действует не так как нужно" не потому что что то добавили и испортили то что уже есть, а потому что какой то функционал только начали писать и свои хотелки не правильно сформулировали в код.

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

Где мне в подобном проекте применить юнит тесты?

Ответить
2

"Хотелки" -> "Я хочу, чтобы мой код работал вот так" -> "Я хочу, чтобы этот класс работал вот так" -> "Я пишу юнит-тесты, которые проверят, что класс работает именно так" -> "Я пишу код, который проходит юнит-тесты" -> "Мой код работает именно так, как я хочу". Если вы плохо подумали над той частью, где ""Хотелки" -> "Я хочу, чтобы мой код работал вот так" -> "Я хочу, чтобы этот класс работал вот так"", то вы обречены и вас не спасёт никто и ничто. Придётся думать снова, и сильно тщательнее. А вот последние этапы могут стать сильно проще, если юнит-тестирование таки использовать. Что верно для любого ПО, включая, но не ограничивась видеоиграми.

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

Ответить
–1

Я не понимаю как проверить что класс работает правильно?

Например я написал юнита, он ходит стреляет и ищит аптечки. Его поведение правильное или косячное я вижу на экране.

Какие юнит тесты мне в этом помогут?

Ответить
0

Ищет аптечки (простите за топорный русский псевдокод):
1)
Поставить аптечкоискателя на пустой уровень
Поставить аптечку на одну линию с аптечкоискателем
Assert.That(аптечкоискатель.МаршрутДоАптечки == ПрямаяЛиния)
2)
Поставить аптечкоискателя на уровень с одной стеной
Поставить аптечку на одну линию с аптечкоискателем, но за спиной
Assert.That(аптечкоискатель.МаршрутДоАптечки == КриваяЛинияОгибающаяСтену)
3)
Поставить аптечкоискателя на уровень, где четыре стены образуют замкнутый прямоугольник
Поставить аптечку за четыре стены, куда добраться нельзя
Assert.That(аптечкоискатель.МаршрутДоАптечки == null)
4)
Поставить аптечкоискателя напротив лабиринта из кучи стен
Поставить аптечку в центр лабиринта
Assert.That(аптечкоискатель.МаршрутДоАптечки == ИзвилистаяЗагогулинаВедущаяВЦентрЛабиринта)

Да, выглядит странновато, но ничего лучше в 4 часа утра сочинить уже не могу, простите -_- А кайф от юнит-тестов в том, что вам не надо запускать игру, чтобы убедиться, что аптечкоискатель работает правильно. Достаточно просто нажать одну кнопочку "запусти все мои юнит-тесты".

В пошаговых стратегиях, кстати, для юнит-тестов раздолье наивеличайшее. Можно проверять, что у отравленного персонажа всегда уменьшается здоровье в течении как минимум трёх ходов. Можно проверять, что даже в самых диких условиях броня не будет блокировать больше 100% урона. Можно продолжать до бесконечности этот список. Но я уже пойду спать, пожалуй -_-

Ответить
–1

Ну, знаете, я тут не увидел надобности в юнит тестах.

Про броню, пишется метод нанесения повреждения и в ней рассматриваются ситуации каким образом юнит получает повреждение..

Написав ее один раз, как ее можно поломать, просто не представляю.

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

Я не вижу никаких возможных поломок того что написано.

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

Как это можно поломать дописав код?

Ответить
3

Важность юнит тестов как раз в том, что если ты через какое то время захочешь поправить алгоритм поиска аптечек (ну например у тебя был один алгоритм нахождения пути, а потом ты переписал на а* или другой какой то), то тесты тебе помогут не уйти В РЕЛИЗ с неправильным функционалом. Ну или хотя бы не уйти к тестировщикам (ибо зачем тестить то, что заведомо работает не правильно?)

Для тестирования человек сам создаёт какие то условия и предполагает ожидания. Например он сам кодом поставил аптечку в координатах 8,9. Вот и от успешного выполнения ожидаем что найдём аптечку в этом пути, а не где нибудь ещё. + можно заменить аптечку другим объектом в этом же месте, и при этом путь не должен быть найден. Можно прописать какие то препятствия и сделать тест, который будет проверять нахождение именно заведомо правильного пути. Это второй плюс тестов - АВТОМАТИЗАЦИЯ. То есть тебе не надо самому тестить какие то банальные вещи/тебе не надо самому менять аптечку на какой то другой предмет/не надо самому создавать какой то, условно, тестовый уровень/полигон, чтобы проверить что твой алгоритм поиска аптечек найдёт ее в лабиринте. Главное - не надо создавать 4 разных билда для тестировщиков, чтобы они это протеснились. Ну или самому не переключаться на разные сцены/программы

Тесты пишутся для каких то core вещей, все правильно, для физического движка или какой то его части, для нахождения пути, для работы с файловой системой и тд.. Можно конечно сказать - вот я написал, оно точно не отвалится. Да, это верно, но для случая когда 1) ты один пишешь игру 2) ты ее пишешь несколько месяцев и потом забиваешь на неё. Если у тебя в команде 50 человек как ты можешь быть уверен в том, что какой то джуниор рак не поломал код? Можно ревьювить код, вчитываться и компилить в голове.. но это долго и ресурсоемко. Вместо этого написал тест, если он отпал - значит что то поломали. Так же и с временем разработки.. если долго пилишь большую игру всегда что то меняется и тд.. и вот тесты как раз призваны обезопасить. Если ты что то поменял нужное - ты подправил тест. Но если случайно что то задел и поломал например функционал в другом месте - ты уже увидишь ошибку и код не уйдёт в мастер.

Ответить
1

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

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

Ответить
0

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

Ответить
0

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

Ответить
0

Вот и задаюсь вопросом, что же может "что то " случится.

Я согласен конечно что для ручной павки бинарник не годится, но для этого и пишутся редакторы уровней

Ответить
1

На что уйдёт стримов этак пятьдесят. Особенно, если пока не ясно, как будут выглядеть уровни. Потом, возможно, и перекую эти данные в какой-нибудь хитрый бинарь. Но пока что JSON, который можно править прямо в VS/Notepad++

Ответить
0

2 основных правила IT :
1. Если что-то проблемное может случиться, оно случится.
2. С любой частью продукта может случиться что-то проблемное.

Ответить
0

Можно точную фразу?

Ответить
0

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

Ответить
0

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

Ответить
0

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

Ответить
–1

Вы заработали два миллиона в прямом эфире делая полеты и пострелушки кирпичика по шарикам?

Я вас верно понял?..

Ответить
3

Нет, не верно. Это то, что мне ещё предстоит заработать. Но я упёртый, может и выйдет =) А может и нет.

Ответить
0

Чувак, слишком долгие стримы. Ты все переписываешь постоянно. Я потерялся четвертом.
Пересматривать трансляху и смотреть гит - то еще удовольствие.

Смотрю все равно. Логические объяснения и рисунки на бумажке особенно доставляют )))
Писать в реальном времени/при просмотре трансляции - забил. Реально напрягает и запутанно.

Ответить
1

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

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

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

А стримы такие долгие, потому что иначе мы вообще никогда ничего не сделаем. -_-

Ответить
–1

646 строк кода / 1 день и 8 часов = 20 строк в час. Что так медленно?

Ответить
1

О молодой человек, вы из Индии?! (Думаю шуточку вы поймете)

Ответить
0

Вроде бы Макконнелл говорил, что несколько десятков строк в день — это норма. Программист большую часть времени думает. И переписывает.

Ответить
0

ага, думать - это хорошо, но писать то нужно
если взять Quake 3 Arena - 800 000 строк кода / 20 строк в час = почти 14 лет (каждый день по 8 часов)

Ответить
1

Вы кол-во человек забыли учесть.

Ответить
0

Звуковые эффекты можно взять у самого Ютуба. Для этого в творческой студии нужно навести(слева) на раздел другие функции. Там будет фонотека. В фонотеке есть раздел звуковые эффекты.

Ответить
0

Тоже сначала использовал MonoGame, потом пересел на юнити, разница в телодвижениях минимальная, зато картинка красивая и 3д)

Ответить
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": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "flbq" } } }, { "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, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "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" } } } ]
EA анонсировала DLC для DLC
для аддона для спин-оффа
Подписаться на push-уведомления