Баланс оружия и врагов в топ-даун шутере: практический опыт
Привет, ДТФ! Как геймдизайнер команды 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, который участвует в конкурсе:
О самой игре я писал здесь:
А о своем подходе к управлению разработкой – здесь:
За судьбой проекта также можно следить в группе ВК:
Таблицы и статистика для одиночной игры?
Для одиночной игры важно веселье
Это мультиплееров нужнен баланс
таки математика дает инструментарий для работы с "весельем" , кривая сложности/интереса в это и упирается
Баланс - в том числе инструмент для достижения веселья. Чтобы не было слишком просто или слишком сложно.
Ну не скажи, баланс тоже должен быть. Играю сейчас в биошок на макс сложности и пройдя чуть больше половины игры использую 2-3 типа оружия, это арбалет + гранатомет(только против папочек) + распылитель. Другое оружие даже с прокачкой в разы слабее. Что уж говорить про плазмиды(стихийное оружие), я всю игру с не прокаченным электричеством для стана прохожу, а другие вообще не использую, т.к. они в разы слабее основного оружия, даже если использовать улучшенные версии + бафы стихий. К чему тогда такое количество оружия - вопрос еще тот, а ведь на нем еще есть 3 типа боеприпасов... Поэтому и должен быть баланс чтобы всем оружием можно было играть, вообще с этим хорошо в перезапуске дума, вот там реально все оружие используешь и все кроме пистолета имеет импакт.
Куда инвестировать?
В нефть
Да как удобно - сбербанк, тинькоф, western union..:)