Мастер оружия в Battlefield 2042. Часть вторая

Баг или фича — решение главной проблемы воссозданного режима.

Текущее состояние редактора — больше проверок, больше кода. Оптимизировать не стал, так как неудобно. Обратите внимание на правила и блоки (не подпрограммы), висящие вне MOD — они в работе не участвуют.
Текущее состояние редактора — больше проверок, больше кода. Оптимизировать не стал, так как неудобно. Обратите внимание на правила и блоки (не подпрограммы), висящие вне MOD — они в работе не участвуют.

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

В предыдущих сериях

После выхода Battlefield 2042 мною в редакторе Portal был разработан режим Gun Master (Мастер оружия) из Battlefield 3. Основная загвоздка была в том, что невозможно узнать, из какого оружия был убит игрок. Это породило изменение концепции (два убийства откатывают игрока назад), которое сильно сказалось на сложности режима. Было решено во что бы то ни стало найти решение.

Мастер оружия в Battlefield 2042. Часть вторая

15 часов спустя…

28 часов в итоге…

Когда документация стреляет тебе в ногу

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

Самый простой и приземленный пример: массивы (Arrays). Редактор предоставляет возможность создавать список данных в форме массива и выполнять огромное количество операций над ними, в том числе фильтровать, сортировать, разделять, перемешивать, и так далее — всё как в обычных языках программирования. Однако реализация страдает от некорректной документации.

Предположим, мы создали переменную, в которую хотим загнать список вооружения по стадиям. Мы это делали в прошлый раз — с помощью блока SetVariableAtIndex добавляем элементы один за другим на индексы от 0 до n (опыт программиста не дает покоя + мне важно контролировать индексы). Создали, проверяем — всё работает!

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

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

Редактор предоставляет вставку CountOf, описание которой звучит следующим образом:

CountOf возвращает Число элементов в указанном Массиве.

Документация Battlefield Portal

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

Создаем массив из двух(!) элементов, ожидаем цифру 2 в уведомлении
Создаем массив из двух(!) элементов, ожидаем цифру 2 в уведомлении
...Ты должен был бороться со злом, а не примкнуть к нему!
...Ты должен был бороться со злом, а не примкнуть к нему!

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

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

Количество стадий - CountOf массива с оружием минус 1. Счет для победы - количество стадий, помноженное на два, минус один.
Количество стадий - CountOf массива с оружием минус 1. Счет для победы - количество стадий, помноженное на два, минус один.

Баг или фича?

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

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

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

Мастер оружия в Battlefield 2042. Часть вторая

Подпрограмма PrepareAllWeaponSlots создает массив со всеми известными игре слотами инвентаря. Вставка IsTrueForAny проходит по массиву и определяет, не возвращает ли истину вставка из аргумента, а CurrentArrayElement используется для указания на текущий элемент массива. Вставка Not возвращает противоположное значение аргумента. Говоря простым языком, если хотя бы один из слотов будет активен, код выведет ложь.

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

К сожалению, ближний бой в игре реализован очень неудачно — добить сзади не составляет проблем (spam F to pay respects), а дистанция атаки с других сторон очень велика. Возможно, сказываются проблемы с сетевой составляющей. Поживем — увидим.

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

Правки баланса

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

  • Скорость регенерации здоровья возросла в 3 раза. Долгое восстановление побуждало игроков оставаться в защищенных местах до момента полного исцеления, так что теперь поводов ныкаться будет меньше.
  • Таймаут высадки после смерти уменьшен до 5 секунд, включая экран смерти. Почти моментальное воскрешение не дает игроку расслабиться.
  • Ведется аудит карт на предмет пригодности к режиму. На данный момент убрана только карта «Возрождение» — на ней большую часть занимает открытое поле.

Планы на будущее

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

К сожалению, некоторые части опыта Gun Master пока невозможно реализовать:

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

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

Редактор правил Battlefield Portal — очень недружелюбная вещь для новичка, не знающего азов программирования. Огромный порог вхождения загоняет пользователя в жесточайшие рамки, в которых можно развернуться только имея нестандартный склад ума и желание испытывать каждое незначительное изменение в коде в надежде на положительный результат. Документация скудна, сообщения об ошибке имеют мало толка, а любой чих может крашнуть сервер.

Если вам такая постановка вопроса по душе и ваши ожидания не завышены, то Battlefield Portal — отличная песочница с огромной свободой в рамках игрового процесса. Здесь можно сделать режим своей мечты, параллельно нехило поразмяв мозг. Возможности редактора сильно ограничены, но это только подстегивает креатив и мышление за рамками. Ripple Effect сделала ставку на ветеранов серии и не прогадала — сообщество Battlefield всегда мечтало о полноценной песочнице, и она совсем рядом!

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

5353
16 комментариев

история интереснее игры

9
Ответить

Это точно - сам процесс интереснее игры.

4
Ответить

Это массив - значит, для того, чтобы там был элемент с индексом 1000, в нём должно быть хотя бы 1001 элемент. Не Map, а Array. Так что не вижу причины для удивления.

1
Ответить

Я пришел из PHP/JS, в котором массивы работают не так.

Ответить

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

Ответить

Да, тоже такое замечаю, но не то что бы слишком часто.

По ресу - согласен. В BF3 была галочка автодислокации.

Ответить

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

Ответить