Баланс оружия и врагов в топ-даун шутере: практический опыт

Привет, ДТФ! Как геймдизайнер команды Pigeon Slayer, я пытаюсь спроектировать драйвовый, «мясной» и разнообразный геймплей для нашей игры. В статье попробую передать свой подход к балансу оружия и врагов для достижения этой цели. Надеюсь, он будет полезен другим разработчикам, и буду рад, если породит полезную тематическую дискуссию.

Осторожно – это технический лонг почти без сахара.

Дааа, таблиички!
Дааа, таблиички!

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

В свою очередь, сам я вдохновлялся этим отличным видео, рекомендую:

Артём Волков рассказывает и показывает

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

Рабочая таблица

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

Постарался причесать её до приемлемого состояния (надеюсь, получилось, если нет – пишите в комментах, учту).

Легенда классическая: желтые ячейки – для внесения данных из движка и редактирования, белые – расчётные параметры, не вбиваемые вручную.

Сейчас доступно 3 листа: дальнобойное оружие, оружие ближнего боя (принцип работы сильно различается, о чем подробнее дальше), и враги.

Смотрите, копируйте, пользуйтесь, как будет удобно. А пока разберём посчитанное по порядку.

Дальнобойное оружие

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

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

Сначала необходимо было определить общий подход к балансу оружия. Так, для условного одиночного шутера с линейной прогрессией мощь нового оружия должна постепенно возрастать – т.н. «вертикальный» баланс. Оружие балансируется относительно возрастающей сложности препятствий. Для условного сетевого аренного шутера, в котором оружие доступно практически одновременно, оружие в большей степени балансируется друг с другом, чем с окружающими условиями – «горизонтальный» баланс.

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

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

Определившись с принципом баланса, пришло время подобрать центральный параметр сравнения эффективности оружия, вокруг которого и строить баланс. Таким параметром был выбран Time to Kill - время на убийство врага данным видом оружия.

Time to Kill представляет собой отношение здоровья врага к урону оружия в секунду (Damage per Second, далее DPS). Благодаря прямой связи с характеристикой врагов параметр очень удобен для дизайна уровней и кривой сложности, чтобы определить подходящий каждому виду оружия уровень угрозы и реализовать ее на уровне. Одновременно параметр использует значение эффективного урона оружия, что делает его надежным индикатором «мощи».

Итак, «балансить» решено вокруг Time to Kill. Как же его рассчитать?

В расчете участвуют параметры, которые мы прямо задаём в движке: урон от проджектайла Damage, частота выстрелов UseRate, размер обоймы оружия Clip Size и время перезарядки Reload time.

Сперва рассчитаем «классический» DPS – умножив дамаг проджектайла на количество проджектайлов в секунду. Этого было бы достаточно, не будь в игре перезарядки – но она есть (кроме базового импланта), она занимает время, а потому её необходимо учесть. Для этого рассчитываем Clip Waste Time, который состоит из времени на опустошение обоймы и времени на перезарядку. Теперь необходимо пересчитать DPS с учетом поправки на перезарядку (я не силен в математике и сделал это тривиально, через пропорцию). В итоге получаем параметр эффективного DPS с учетом перезарядки (DPS with reload correction) – более презентативный показатель. Его и будем использовать при расчете Time to Kill.

Спойлер: в конце приходим примерно к этому
Спойлер: в конце приходим примерно к этому

Второй нужный параметр – HP врага – относится к первичным, определяемым дизайном. Мы целимся в мясной геймплей с толпами врагов, поэтому в нашем случае здоровья у врагов относительно мощности оружия мало. Техническая сложность здесь в следующем: видов врагов много, их параметры отличаются. Я вышел просто – взял самого слабого и многочисленного врага, голубя, за «мерило». Именно его параметры участвуют во всех расчетах. В дальнейшем, уже при балансе врагов, отдельным коэффициентом я выводил количество «голубей» в каждом враге для удобного пересчета показателей оружия относительно других врагов. Подробнее об этом – позже.

Итак, Time to Kill посчитать уже возможно. При попытке, однако, оказывается, что из-за низкого HP нашего голубя показатель часто получается меньше, чем частота огня оружия, чего не может быть физически. Итак, для адекватного сравнения возьмем не одного голубя, а сразу 10, что отлично соответствует духу «мясного» шутера. Теперь показатель работает, как задумано.

Однако у Time to Kill сохраняется ряд проблем. Легко заметить, что группа дробовиков сильно выигрывает у автоматического оружия, а то в свою очередь – у единичного. А все потому, что мы напрочь игнорируем показатель точности.

Точность в нашей механике работает так: задаётся максимальный угол оффсета траектории полёта проджектайла от требуемой (т.е. линии перс – прицел). Угол «отражается» в обе стороны от требуемой траектории. Реальная траектория полёта проджектайла определяется случайно в этих рамках. Само значение точности в движке – обратная углу величина.

Негативное влияние низкой точности очевидно; таким образом, точность можно учесть как коэффициент к DPS, таким образом сбалансировав неточное оружие. Но в мясном шутере с точностью не всё так однозначно: при огне по толпе врагов, проджектайлы, летящие мимо цели, с большой вероятностью попадут в соседнего врага. В итоге, низкая точность порождает своего рода АоЕ-эффект, что может стать даже преимуществом. Для учета этого показателя я рассчитал долю сектора возможного поражения оружия от общего пространства в 360 градусов (Angle coef). Умножив эту долю на эффективный DPS, получил некий показатель эффективности оружия по площади (Area Effectivness).

Да кому вообще нужна эта точность?

Как итог, точность имеет две фактора влияния на геймплей, и пока что мне не удалось найти способ учёта обоих факторов в едином показателе – то есть, создать некий общий параметр «мощи», учитывавший бы точность в полной мере. Буду рад, если более опытные коллеги поделятся своими подходами к этой задаче. Сейчас же, я использую эти параметры эмпирически – сопоставляю с Time to Kill, испытываю на плейтесте и подгоняю по ощущениям.

С Time to Kill есть и другая проблема: он замкнут в моменте и не учитывает реальное поведение оружие в игровой сессии. Не знает, как долго игрок сможет стрелять, молчит об – что, безусловно, важная часть баланса и пользовательского опыта. Несмотря на всю мощь, миниган, растративший все снаряды за 2 секунды, стал бы для игрока большим разочарованием.

Здесь мы подходим к балансу боезапаса оружия. От количества доступных патронов (Ammo Max) зависит, насколько долго игрок сможет наслаждаться оружием. Для баланса этого показателя используем параметр общего потенциального урона оружия Full Damage – произведение дамага от проджектайла на объем боезапаса. Он поможет сбалансировать боезапас с точки зрения игровых показателей, но мало что говорит о пользовательском опыте. Для этого лучше подойдет Empty Time - параметр, определяющий минимальное время, необходимое игроку для растраты всех патронов. Особенно важно учесть его для автоматического оружия с высокой скорострельностью – чтобы патроны не закончились раньше, чем игрок привык к оружию.

Есть и ещё один аспект пользовательского опыта – соотношение длительности перезарядки к длительности огня. Чем дольше перезарядка, тем больше время «безоружности» игрока, и тем слабее оружие. Для учета этого фактора я посчитал отношение Empty Time к длительности перезарядки. Из этого показателя видно, что несмотря на очень высокий высокий Empty Time и Full Damage минигана оружие имеет крупный недостаток: большая часть времени его эксплуатации приходится на перезарядку.

Шотган - один из главных жертв баланса по перезарядке
Шотган - один из главных жертв баланса по перезарядке

Другие характеристики, которые вы можете найти в таблице, я сделал для наглядности и своего удобства – некоторые удобнее для одиночного оружия, иные для автоматики. Здесь уже на вкус и цвет.

Итак, несмотря на то, что Time to Kill – достаточно комплексный показатель, он имеет определенные недостатки. Сейчас я использую несколько дополнительных показателей и эмпирический подход плейтестов для определения финальных показателей оружия.

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

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

А пока перейдём к оружию ближнего боя.

Оружие ближнего боя

By design, ближний бой – вспомогательная фича в игре, призванная разнообразить ганплей. Мили атака всегда доступна по отдельной клавише и не заменяет обычного оружия. Она бьёт по площади, имеет уникальные способности и обладает кулдауном, ограничивающим использование.

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

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

Начнем с общих для всех видов оружия показателей. Каждое оружие ближнего боя имеет следующие общие характеристики: урон Damage, размеры зоны поражения Attack Length и Attack Radius, время проведения атаки Attack Time, величину кулдауна Cooldown. Рассчитаем DPS с учётом кулдауна и времени проведения атаки. Но этого мало: мили-оружие поражает всех врагов на определённой площади, следовательно, нужно посчитать эту площадь – Attack Zone. Перемножив DPS на площадь атаки, получим «базовую» мощь Basic Power.

Однако, вся «соль» мили – в уникальных абилках. Разберём их влияние по очереди.

Базовый рабочий инструмент
Базовый рабочий инструмент

Гаечный ключ отбрасывает врагов, попавших под удар, на существенное расстояние (Repulsion Distance). С точки зрения механики, отбрасывание это деактивация врагов, атакующих вблизи, на время, которое им потребуется, чтобы вернуться к игроку. В таблице это показатель Enemy Deactivation Time, равный отношению Repulsion Distance к средней скорости перемещения врагов. Так как отбрасывание применяется ко всем врагам в определенной площади, умножаем эту величину на площадь, а получившийся коэффициент на DPS – и получаем Power Coef, итоговый сравнительный показатель мощности оружия. Самое слабое (но все равно интересное и играбельное) оружие готово.

Перейдем к серпу. У него наибольшая зона поражения; он так же отбрасывает врагов (хоть и гораздо слабее), а еще наносит дополнительный урон от кровотечения. В дополнение к деактивации считаем Additional DPS – умножаем урон от кровотечения, количество и интервал повреждений от кровотечения (см. рамку (Individual Calculations), умножаем на площадь поражения и приводим к секунде. Получившуюся величину складываем с DPS от самого удара, получаем итоговый Full DPS, а затем и Power Coef.

Гидродомкрат может поднимать не только авто!
Гидродомкрат может поднимать не только авто!

Гидродомкрат уже хитрее. Он не отбрасывает врагов, а подкидывает их вверх. Падая, они получают дополнительный урон от столкновения с землей. Те, кто пережил урон от удара и падения, через некоторое время встают и возвращаются в бой. Итого – аналогично предыдущим учитываем Enemy Deactivation Time (здесь он замерен эмпирически и введен вручную), а кроме того считаем Additional DPS от падения. По Power Coef домкрат занимает уверенное второе место благодаря неплохому урону и высокой деактивации врагов.

Черёд адской дрели. При ударе она насаживает врага на сверло и вращает определенное время. Задевая других врагов, тушка жертвы наносит им дополнительный урон. Отбрасывания у дрели нет, поэтому за Deactivation Time принимаем время, которое моб «висит» на сверле – если у него достаточно здоровья, он переживёт эту манипуляцию. Считаем Additional DPS от урона по окружающим врагам: умножаем урон от столкновения на длительность «сверления» и зону поражения способности. Получившийся в итоге Power Coef – лучший из всех; и действительно, при умелом использовании дрель легко разбрасывает толпы врагов. Но есть и минусы: опасная необходимость быть в тесном контакте с врагами и высокий шанс промаха – атака дрелью точечная. Эти недостатки, ярче проявляющиеся в игре, чем на бумаге, позволяют держать высокие показатели дрели, сохраняя общую «сбалансированность».

Слабых врагов дрель раскидывает на ура

Для дополнительной балансировки я так же посчитал Time to Kill, использовав финальный DPS. Он даёт несколько другую перспективу, выводя серп в лидеры по урону, но совсем не учитывает деактивацию. Комбинируя оба показателя, я и выстраиваю игровой баланс.

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

Перейдём же к заключительной и наиболее простой части таблицы.

Враги

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

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

На что только не пойдешь, пока на врагов нет моделек - на манекен гопника "натянули" материал голубя. Получилось неожиданно)
На что только не пойдешь, пока на врагов нет моделек - на манекен гопника "натянули" материал голубя. Получилось неожиданно)

Наибольшей трудностью в балансе врагов для меня стала задача сопоставления врагов-милишников со стрелком. Классический подход балансирования игровых сущностей – по мощи, представляющей собой произведение здоровья на DPS. В эту формулу необходимо ввести поправку, которую я назвал «задержкой атаки». Это время, которое требуется врагу от активации до атаки персонажа. И если стрелок начинает стрелять немедленно / на определенном расстоянии, то милишнику необходимо добраться до персонажа (что чаще всего и становится для него фатальным).

Итак, наш мент начинает стрелять, появившись в пределах игрового экрана – его Time to Attack примем за 0. Для милишников произведём простой расчет – 15 м (полученное эмпирически среднее расстояние от игрока до края экрана) поделим на скорость перемещения. Для дальнейшего расчета я перевел время в коэффициент (Attack Delay coef) с единственным изменением – приняв нуль за возможную для пересчета единицу.

Теперь рассчитаем Power, умножив HP на DPS и поделив на Attack Delay coef. Получившаяся величина ясно определяет различия между пушечным мясом и более серьезными врагами.

Исходя из мощи врагов логично высчитать и количество очков, полагающееся за их убийство. Для этого я привел мощь врагов к мощи базового голубя (Pigeon Power Coef), назначил последнему гордые 5 очков – а очки за остальных посчитал в зависимости от этого коэффициента.

Конечно, этот расчет далек от идеала; в будущем, с доработкой врагов, в нём нужно будет учесть особенности перемещения, уклонения и абилки врагов.

Как-то так, отчасти обоснованно, а где-то костыльно и по ощущениям, сейчас собран баланс Pigeon Slayer. Полагаю, без доли «интуиции» и плейтестов здесь не обойтись в любом случае – реальный геймплей подбрасывает слишком много ситуаций, учесть которых в расчете вряд ли возможно. Между тем, всегда стоит стремиться к контролю хаоса – отчего буду благодарен за любые продуктивные комментарии и предложения по улучшению.

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

А попробовать, что получилось в результате моих вычислений можно, поиграв в билд Pigeon Slayer, который участвует в конкурсе:

О самой игре я писал здесь:

А о своем подходе к управлению разработкой – здесь:

За судьбой проекта также можно следить в группе ВК:

8484
19 комментариев

Таблицы и статистика для одиночной игры? 
Для одиночной игры важно веселье 
Это мультиплееров нужнен баланс

1

таки математика дает инструментарий для работы с "весельем" , кривая сложности/интереса в это и упирается

7

Баланс - в том числе инструмент для достижения веселья. Чтобы не было слишком просто или слишком сложно.

4

Ну не скажи, баланс тоже должен быть. Играю сейчас в биошок на макс сложности и пройдя чуть больше половины игры использую 2-3 типа оружия, это арбалет + гранатомет(только против папочек) + распылитель. Другое оружие даже с прокачкой в разы слабее. Что уж говорить про плазмиды(стихийное оружие), я всю игру с не прокаченным электричеством для стана прохожу, а другие вообще не использую, т.к. они в разы слабее основного оружия, даже если использовать улучшенные версии + бафы стихий. К чему тогда такое количество оружия - вопрос еще тот, а ведь на нем еще есть 3 типа боеприпасов... Поэтому и должен быть баланс чтобы всем оружием можно было играть, вообще с этим хорошо в перезапуске дума, вот там реально все оружие используешь и все кроме пистолета имеет импакт.

2

Куда инвестировать?

2

Да как удобно - сбербанк, тинькоф, western union..:)