15 ноября 2021 15.11.21 5 1368

Мастер оружия в Battlefield 2042? Да!

Воссоздал режим Gun Master в Battlefield Portal и делюсь впечатлениями

Снимок из редактора. Да, чет запутано всё.
Снимок из редактора. Да, чет запутано всё.

Что за режим такой?

Формула Battlefield 3: 32 игрока на маленькой карте. Список из 16 единиц вооружения и ножа. Убейте противника из каждого ствола по два раза, а затем завершите раунд убийством ножа для победы. Если вас убьют ножом посреди раунда (добивания никто не отменял) — откатитесь на одно убийство назад.

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

Как поиграть?

Режим называется «Gun Master — BF2042 Rendition [HARD]»

Для этого можно воспользоваться моим кодом подборки. В главном меню игры выберите Portal, далее сверху Сервер, далее Код подборки и вставьте нижеследующий код.

aadxg1

Либо можете подписаться на меня в игре (хз, как это работает, но мой ник CJMAXiK)

Технически, это платная подписка, ведь игру вы купили :)
Технически, это платная подписка, ведь игру вы купили :)

Вместо предисловия

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

Для своей подборки (англ. experience) я выбрал следующие настройки:

  • Режим «Каждый сам за себя» (aka Free-For-All)
  • Карты с маленькой боевой зоной (за исключением Renewal — там бой происходит посреди открытого поля, что никак не вяжется с режимом)
  • 32 игрока
  • Бойцы из Battlefield 3 (к сожалению, все доступные игры сразу выбрать нельзя)
  • Всё оружие и гаджеты отключены (это важно)

Немного теории

Редактор правил (англ. Rules Editor) использует визуальное программирование, основанное на урезанной версии библиотеки Blockly. В основе игрового режима (англ. gamemode) — блок MOD (серый). В нем должны содержаться правила (англ. rule) — блоки RULE (фиолетовый). Всё, что не находится в блоке MOD, не применяется в игре и может быть использовано как чистый лист для идей. У каждого правила есть событие, при котором оно выполнится — по факту смерти, высадки на карту, при убийстве другого игрока и так далее.

Также в правилах есть две секции:

  • conditions содержит одну или несколько условий (синие блоки condition). Все условия должны возвращать истину (true) для выполнения инструкций правила
  • actions содержит блоки с конкретными инструкциями — действия (желтые) и контроль выполнения (синие блоки)

Инструкции могут содержать т. н. вставки. Они возвращают какие-либо данные.

Давайте на простом примере:

Правило StopGameRu будет вызвано при каждой высадке игрока на поле боя. Производится проверка счета у данного игрока — если он равняется нулю, всем на сервере будет отображено большое сообщение «Обзор Portal на! StopGame.ru… и {никнейм} пришел!».

А вот он я :) Обратите внимание на пинг — выбора страны пребывания сервера нет.
А вот он я :) Обратите внимание на пинг — выбора страны пребывания сервера нет.

Теперь по блокам:

Правило начнет проверять условия. В нашем случае, равен ли счет игрока нулю. EventPlayer — это игрок, который вызвал данное событие. GetGameModeScore возвращает текущий счет, в данном случае нашего игрока. Equals проверяет, равны ли оба аргумента.

Если условия вернули true, выполняется блок инструкций. В данном случае, будет отправлено т. н. сообщение игрового режима. Message — вставка, позволяющая создать сообщение. Первый аргумент — строка, остальные — подстановки. Вы можете подставить до трех значений в текст, используя {}. Это может быть всё, что возвращает текст, число или игрока. DisplayGameModeMessage выполняет отправку сообщения игрового режима на всех игроков. Обратите внимание на последний аргумент — используя его, можно отправить сообщение только на Игрока или Команду.

Можно использовать переменные и подпрограммы, о чем позже.

Всего доступно 16 глобальных и 16 объектовых (для игрока или команды) переменных. Локальных переменных нет.
Всего доступно 16 глобальных и 16 объектовых (для игрока или команды) переменных. Локальных переменных нет.

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

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

Создание режима Gun Master

Я — большой фанат режимов Gun Master, Gun Game и тому подобным. В них очень большую роль играет скилл игрока, мастерство владения оружием и умение быстро приспособиться к новому по ходу боя. А еще это хороший вариант оружие прокачать. И не сосчитать, сколько я провел раундов Gun Master в BF4 и BF3… В общем, решение воплощать именно Gun Master было очевидным.

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

Для начала, нельзя отобрать оружие у игрока. Сказать, что я был в шоке — ничего не сказать. Оружие можно только заменить в конкретном слоте. Также нельзя запретить игроку менять оружие по ходу боя (технически можно, но это может привести к вылету сервера и выглядит не так элегантно).

Мое решение было нетривиальным:

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

И с этим всё не так просто. Взгляните, как выглядят все подпрограммы (англ. subroutines), необходимые для достижения цели.

На формулировку этих правил ушло 6 часов тестирования
На формулировку этих правил ушло 6 часов тестирования

В итоге, код выдачи оружия состоит из трех подпрограмм:

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

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

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

Так выглядит список оружия, слотов и названий. Кстати, это пресет Normal из BF3 с некоторыми изменениями
Так выглядит список оружия, слотов и названий. Кстати, это пресет Normal из BF3 с некоторыми изменениями

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

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

Сообщения на любой вкус и цвет. Некоторые даже с анимацией и звуковыми эффектами
Сообщения на любой вкус и цвет. Некоторые даже с анимацией и звуковыми эффектами

Единственное, что вы можете делать с интерфейсом в коде — отправлять различные сообщения. Я решил использовать максимум:

  • GameModeMessage привествует игрока при первой высадке и предупреждает об игроке, который достиг последней стадии
  • NotifcationMessage находится поверх всех остальных элементов, поэтому я использую его для уведомлений после смерти
  • HighlightedWorldLogMessage, помимо сообщений самой игры, использую для вывода сообщений о возвращении игрока на предыдущую стадию, с никами убитого и убийцы
  • HeaderText используется мной для сообщений о продвижении по стадиям
  • MessageText1-4 я использовал для отображения статуса игрока: текущая стадия и сколько осталось, сколько убийств до следующей стадии и следующее оружие. Скриншот с тестирования — ниже.
Удобно, практично
Удобно, практично
А вот сам код не то чтобы локаничен.
А вот сам код не то чтобы локаничен.

Пример выше — квинтэссенция редактора. Чтобы сделать довольно простую вещь (вывести 2-3 сообщения с данными из нескольких переменных), нужно построить монструозную цепочку из блоков и вставок. В этом очень сложно разобраться с наскоку, и достаточно проблематично отлавливать ошибки. А корректность работы режима можно проверить только в игре, причем вам нужно постоянно тушить и запускать сервер заново. Это хоть занимает минуту-полторы, но эти минуты складываются в часы. В настройках рабочего сервера есть сообщения об ошибках, но ты никогда не сможешь узнать, какой именно блок их отправляет. Они еще и некстати локализованы, хотя сам Portal русского языка не имеет.

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

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

И в Portal это реализовать нельзя!

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

В итоге, моим решением стал откат на предыдущий этап после двух смертей.

Тестирование

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

Игра была постоянно открытой на втором экране в режиме Без рамок, так что переключаться из игры в редактор было просто (кто еще не понял или не в курсе — редактор сделан в виде Web-приложения).

Экран выбора подборки Portal
Экран выбора подборки Portal
Экран создания сервера. Ничего лишнего.
Экран создания сервера. Ничего лишнего.

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

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

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

Итоги тестирования и планы

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

Что я планирую предпринять:

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

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

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

Вместо итогов

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

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

Пример подсказки по блоку
Пример подсказки по блоку

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

Уже сейчас есть большое количество других подборок: гонки на вингсьютах, Джон Уик (1 против 50), Войны покеболов (что бы это ни значило), Зомби-моды, Джаггернауты и тому подобное. Вроде даже батл-рояль делают (простите). Часть из них сообщество публикует на официальном Disсord-сервере в канале portal-sharing. Кстати, рядом есть канал portal-builder, в котором можно получить помощь по редактору (в основном, от других игроков, в том числе и от меня). Также мы потихоньку создаем инструменты сообщества: расширение браузера, которое позволяет копировать/вставлять любые блоки извне; сайт с полной документацией, заметками по использованию и примерами внедрения тех или иных функций, и так далее.

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


Лучшие комментарии

iGramp 16 ноября 2021, 11:54

На пс4 кроссплей только с хуаном. С пекарней и следующими поколениями консолей кроссплея нет =(

iGramp 16 ноября 2021, 12:21

Да, можно. Вот сижу вникаю. Очень подробно и наглядно все описано! Спасибо!

Как по мне, зря они не включили в Глобальную войну парочку дефолтных пехотных режимов. Вот и приходится скакать по Порталу в поисках нормального дефматча =(

Хазард зон я не считаю за пехотный режим. Но это так: оффтопное нытье!

Читай также