Статьи

Игровой баланс #3

Боевой баланс или расчет эффективности

Расчет эффективности

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

Напоминаю, мы делаем мобильный баттлер.
Как убедиться, что вот эта карта 23-го уровня равна по силе другой карте той же ценности того же уровня?
Как контролировать, что любая «редкая карта» на любом уровне ровно вдвое сильнее любой «обычной карты»?

В других жанрах похожие задачи: вот два строения в ситибилдере с похожей ценой, но разной функцией — как сделать их равными по «полезности»?

Просто: сводите всю параметры к одному.

Можете назвать его «эффективность», «полезность», «сила», как угодно.

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

Боевая эффективность

Сила юнита = HP * DMG.

Даже если в игре два десятках параметров, все они сводятся сначала к этим двум, а потом и к одному.
Иначе говоря: ОТНОСИТЕЛЬНАЯ ЭФФЕКТИВНОСТЬ ЮНИТА = HP [ СУММА УРОНА, КОТОРЫЙ Я ПРИМУ ] * DMG [ МОЕГОУРОНА ЗА ЕД.ВРЕМ. ]

Рассмотрим другие параметры.
Например, есть процентный шанс нанести двойной урон (CRIT).
Тогда DMG = DMG * ( 1 + CRIT% ). То есть, добавить 50%-й шанс крита на языке баланса то же самое, что увеличить базовый урон на 50%. Все просто и логично.

Или, например, есть шанс избежать атаку врага (DODGE).
Тогда HP = HP / ( 1 — DODGE%). То есть, 50%-й шанс увернуться равен увеличению здоровья вдвое: логично, т.к. уворот от половины атак позволит юниту вдвое дольше прожить в бою. Точно так же считаются эффекты типа PARRY и ABSORB.

Но если эффектов несколько, то надо смотреть, как они складываются. Например, уворот вместе с поглощением урона — поглощение срабатывает только тогда, когда не сработал уворот. Раз они действуют по очереди, их нельзя складывать. В таком случае формула будет выглядеть так:
HP = HP / ( 1 — ( DODGE%+ ABSORB%*(1-DODGE%) )
То есть, ABSORB надо уменьшать на вероятность уворота: больше уворот — реже поглощение.

Дальше — по аналогии — можно рассчитывать не только параметры юнитов, но также предметов, заклинаний, зданий и прочего.

1*9a8XUa57ZUGxldAPdrrtXg
Удалось свести расчетный баланс классов к 1% в игрушке с кучей абилок и шмоток 🙂

Пояснение 1: “эффективность” меняется НЕ пропорционально умножению параметров на общий множитель. Например, если умножить HP и DMG юнита на два, его эффективность вырастет более, чем вдвое.
Пояснение 2: если “эффективность” одного вдвое сильнее другого, значит. у сильного останется примерно половина здоровья после боя. И шанс победить второго слабого врага.
Пояснение 3: Но в сражении одновременно с двумя слабыми врагами побеждают двое, поскольку они наносят свой суммарный урон за единицу времени.

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

Та же логика работает для любого другого жанра, только вместо HP и DMG вы определяете другие параметры, из которых складывается эффективность юнитов/предметов/зданий и т.п.
Для фермы это может быть “польза”, поделенная на “скорость”, где польза — приносимый ресурс, умноженный на коэффициент ценности этого ресурса, а скорость — время, которое нужно для производства.

Параметры из эффективности

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

У этого чувака из Dark Souls должно быть много HP.
У этого чувака из Dark Souls должно быть много HP.

Проще всего это делать с помощью коэффициентов к средним значениям: например, для «танка» нужно будет указать, что его здоровье в 1.5 раза выше среднего.

Теперь подробно: допустим, сила (PW) юнитов 1-ого уровня = 100.
Тогда средние значения HP иDMG = SQRT(100) = 10(квадратный корень из эффективности).
Однако ранее мы решили, что здоровье должно быть в 6 раз больше урона.
Пересчитываем: среднее HP = SQRT(100) * SQRT(6) = 24
Соответственно, среднее DMG = 24/6 = 4
Проверяем: 24 * 4 = 96 (не ровно 100, т.к. до этого я округлил, но в рамках баланса такие погрешности допустимы)

Теперь мы хотим сделать «танка».
Нам надо умножить средний HP на ранее выбранный множитель = 24 * 1.5 = 37
соответственно DMG = 4 * ( 1 / 1.5 ) = 4 * 0.7 = 3
Проверяем: 37 * 3 = 111 (Все получилось, хоть и с погрешностью округления).

В итоге наши расчеты будут выглядеть примерно так:

В этой таблице единственное вручную задаваемое число — коэффициент к HP.
В этой таблице единственное вручную задаваемое число — коэффициент к HP.

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

Заполнение вручную

Параметры можно вписывать и вручную, а формулой только «проверять», чтобы вписанное не сильно отличалось от расчетного.

Как это может выглядеть:

Теперь все значения внесены вручную, а под каждым юнитом есть столбик с проверкой. В нем — относительная разница между полученным PW и расчетным, которая подсвечивается красным (conditional formating), если превышает 10%.

  • Плюсы вписывания: значения лучше смотрятся, их можно связать с эмоциями, например «Адская бомба с уроном 666″.
    Еще я люблю использовать четные числа для «толстых» юнитов и нечетные для дамагеров.
    А эпические юниты хорошо смотрятся с круглыми числами.
  • Минусы вписывания: больше работы, больше мусора в таблицах и выше риск ошибки.

Aвтоматическое заполнение с коэффициентами или ручное с проверкой — выбор за вами.
Если ваши юниты и способности могут прокачиваться на десятки уровней, в эмоциональных числах нет никакого смысла, все равно их почти не будет заметно.
Зато, если речь о каком-то уникальном контенте, который не меняется и не имеет сотню состояний, задумайтесь о ручном заполнении, с ним красивее.

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

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

Хардкорная часть баланса

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

1. (Не)очевидные параметры

Да, все параметры сводятся к HP и DMG, это чистая математика.

Но в балансе всегда есть здоровая доля «магии» из-за невозможности предсказать и посчитать все возможные события и комбинации.
И не везде есть прямое математическое решение — иногда вам придется вносить изменения «на глаз» и проверять в прототипе.

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

Вот некоторые примеры.

Самый простой: лечение.

Легко догадаться, что для целителя DMG = силе исцеления. Однако, атакующий всегда найдет цель, а целитель может быть неэффективен, когда он один на поле или когда все здоровы. Плюс он не лечит выше максимального здоровья.
Поэтому при сравнении целителя и дамагера с одинаковыми параметрами расчетная эффективность целителя должна быть ниже.
Я обычно использую коэффициент 0.7–0.8 к DMG.

Другой пример: лучник атакует летающие цели, рыцарь — нет.
Лучник, очевидно, «эффективнее» и для правильного баланса ему надо заложить коэффициент к урону.
Но подбирать коэффициент придется «на глаз», опираясь на тестирование и некоторые соображения. Например:

  • Количество летунов в игре. Если летун, допустим, всего один — к-т должен быть минимален.
  • Эффективность самих летунов. Если все летуны заведомо слабые и легко выносимые, а «лучников» в игре много — к-т так же не должен быть слишком высоким.

Этот пример относится ко всем параметрам, подразумевающим определенный фильтр характеристик (у Шрайбера это зовется интранзитивными механиками).
Например, к «пробитию брони», при условии, что броня есть не у всех персонажей. Или к повышенному «урону по зданиям». Или к «стойкости против гоблинов».
В некоторых случаях есть возможность посчитать коэффициент математически: умножив чистую эффективность свойства на вероятность его использования. Например “+100 к урону против гоблинов” надо считать как “+100 * вероятность ударить по гоблину”, иначе говоря, “+100 * долю гоблинов среди ожидаемых врагов”.

Другой пример: атака на расстоянии.

В игре с перемещением или позиционированием побеждает тот, кто начал атаковать раньше; соответственно, ему нужен коэффициент к урону.

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

И в этом даже есть смысл. Но нельзя забывать:

  • Во-1-х, далеко не всегда столкновение будет начинаться с максимального радиуса атака. В играх типа Clash Royal можно скидывать юнитов с ближней атакой прямо на юнитов с дальней — тогда весь эффект дальнего боя сводится к нулю.
    В каждой игре свои ограничения — считая по максимуму, мы, скорее всего, завысим эффективность.
  • Во-2-х, мы не учитываем тактику комбинирования «жирных» юнитов спереди и дальнобойных сзади. В зависимости от игры эта тактика может быть выгодна по-разному, от «вообще не имеет смысла» (к-т минимальный), до «только так и нужно играть» (к-т максимальный). Определитесь, что нужно для геймплея, и подкрепите этот вариант коэффициентом.

Этот же пример можно отнести ко всем вопросам позиционирования, включая, например, преграждение пути, замедление, другие формы crowd-control’a.

1ibe42bigo5dwv_swytjn8wИ в каждом случае есть логичное, но не полное математическое решение: например, для мага с «заморозкий» можно посчитать среднее число поражаемых целей, умножить на среднюю атаку и на его силу замедления — получится обоснованное число «урона, который цели не смогли нанести из-за эффекта замедления», и это число смело можно плюсовать кDMG мага.

Но — в зависимости от механик и тактик игры — реальная эффективность может сильно отличаться от наших расчетов.
Так что без тестирования и правок «на глаз» не обойтись.

2. Эффективность группы

Этот вопрос уже упоминался: если в игре есть битвы с разным количеством юнитов или юниты типа «отряд из N персонажей» — мы должны знать, как посчитать их эффективность с учетом количества.

Просто умножить «силу» на количество недостаточно — наше число будет отражать «силу» отряда, в котором одновременно сражается только один юнит.

На количество (N) следует умножить отдельно HP, отдельно DMG:
PW(N) = ( HP*N ) * ( DMG*N )
Иначе это можно записать HP*DMG*N², что кажется даже логичнее — но мы так делать не будем, и вот почему: эта запись отражает эффективность отряда, который имеет общее здоровье и постоянный урон, не меняющийся от гибели членов отряда.

В реальности такое встречается редко, поэтому DMG надо понизить на коэффициент, отражающий смертность. А это уже зависит от конкретных механик игры: например, от распространенности AoE атак, от возможности отряда атаковать на расстоянии и т.д.

Возьмем навскидку коэффициент 0.7, и тогда формула выглядит так:
PW(N) при N>1 = ( HP * N ) * ( DMG*0.7*N )

Но если вы хотите использовать одну формулу и для отрядов и для одиночных героев, то её надо переписать:
PW(N) = ( HP*N ) * ( DMG + DMG * 0.7 * (N-1) )

3. Синергия

Очевидно, что с умом собранная колода сильнее, чем суммарная сила карт, из которых она состоит. И дело не только в эффекте группы: смысл декбилдинга (подбора колоды) в хорошем взаимодополнении. Например, мощные, но уязвимые карты можно сочетать с “защитниками”, которые принимают на себя урон.

Теоретически синергию можно посчитать в балансе — но зачем?

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

Сама по себе “синергия” — не проблема.
Проблема наступает тогда, когда выгода небольшого числа комбинаций настолько явная, что значительная часть игроков пользуется одинаковыми колодами. Это уменьшает разнообразие и снижает фан от находки хорошего сочетания.
Но “явная” — не математическая категория. К тому же поведение игроков часто не связано с реальным балансом. Например, они нередко считают какую-то комбинацию или стратегию “имбой” — от imbalanced, несбалансированной — только потому, что ею пользуется популярный киберспортсмен.

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

Рейтинги вместо процентов

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

Начну с проблемы: допустим, мы делаем классический World of Warcraft и хотим, чтобы рыцарь-защитник в нормальной броне поглощал 40% урона.
Это правильная логика: она закрепляет за классом определенную роль на протяжении всей игры, что гораздо лучше, чем если бы в начале было 10%, а в конце — под 80%.

1bm9zv7jrv3mxadgjixx2lw
Танкующий класс из Терры. Тяжелая броня символизирует сохранность и надежную защиту героя. По крайней мере интимных зон.

Но вот проблема: все параметры в MMO должны расти. Зачем нам ходить в рейды и валить боссов, если первая броня дает 40% и последняя — тоже 40%?
А если давать больше — есть риск превысить 100%.

У проблемы есть решение: пусть броня 5-го уровня дает 40% защиты только против врагов 5-го уровня.
А против врагов 6-го уровня та же броня даст, скажем, 36%. Против 7-го всего 32% — и так далее. Так мы сохраним роль классов и обеспечим потребность в постоянном росте.

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

Недостаток у такого метода ровно один: все это придется объяснять игроку. И вместо простых и удобных процентов показывать, в довесок, непонятный «рейтинг брони».
К счастью, тот же World of WarCraft уже воспитал поколение привычных к этому игроков.

Впрочем… WoW это точно образцовый пример?
Впрочем… WoW это точно образцовый пример?

Теперь: как это делать.
Рассматриваем на том же примере: 40% защиты против врага того же уровня.

Сначала нам нужна прогрессия нормальных значений брони для этого класса. То есть: сколько «рейтинга брони» (ARMOR) должно быть у игрока на каждом уровне, чтобы его поглощение (ARMOR%) было = 40%.

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

Формула, которая превратит рейтинг в процент, выглядит просто:
ARMOR% = ARMOR / ( ARMOR + PENETRATION )
Легко догадаться, что за счет деления числа на его сумму с другим положительным числом мы никогда не получим > 100%

Теперь разберемся с PENETRATION.
В самом простом сценарии — это значение из той же прогрессии, взятое по уровню врага.
Тогда против равного врага мы будем иметь:
ARMOR / ( ARMOR + PENETRATION ) = 50% поглощения.
Нам, однако, требовалось 40%.
Для этого мы должны сделать еще одну прогрессию: пенетрации. И значения в ней должны быть в 1.5 раза выше, чем в предыдущей прогрессии.

Таким образом: у нас 10-й уровень, для которого требуется, допустим, 300 брони. Нас бьет враг 10-го же уровня, с пенетрацией 300*1.5=450.
Считаем: 300 / ( 300 + 450 ) = 40%
То, что надо.

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

И последнее: в нашей ММОRPG полученный урон будет рассчитываться на сервере по той формуле, с которой сделаны прогрессии брони и пенетрации. Если для прогрессии вы использовали фибоначчи — вас, скорее всего, засунут в блендер и порвут на сотню маленьких геймдизайнеров.

________________

В следующем посте: модели и экономика.

Краткое содержание цикла про баланс:
— Введение и подготовка к работе
— Начало работы: константы и прогрессии
— Боевой баланс или расчет эффективности
— Матмодели и простая экономика
— Комплексная экономика: поведение и цикл
— Монетизация и экономика
— Дополнительно: тервер, кривая обучения, заключение

4 комментария

Добавить комментарий