Метагейм

Матчасть: Реверсный инжинеринг баланса (ч. 2)

Сергей Ананькин, продюсер
28 мая 2014

5. Масштабирование

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

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

Здесь нужно понимать важную вещь: меняя уравнение с помощью различных чисел (слагаемых, множителей) мы можем модифицировать наш график, сохраняя его базовую форму. Ниже я приведу краткий список операций, которые можно проводить с функцией, чтобы поменять её график. В этом списке буквой A я буду обозначать некое новое число, которое вводится в уравнение y = f(x).

  • y = f(x) + A. Добавив число в качестве слагаемого, вы переместите весь график функции вверх (если A положительное) или вниз (если оно отрицательное).
  • y = f(x) * A. Добавив число в качестве множителя, вы растянете (если A больше единицы) или сожмёте (если A меньше единицы) график по оси y, а если вдруг A будет отрицательным, то отразите его зеркально относительно оси x.
  • y = f(x+A). Добавив число в качестве слагаемого к аргументу (в каждом месте, где он встречается в уравнении) вы переместите график влево (если A положительно) или вправо (если A отрицательно) вдоль оси x.
  • y = f(-x) даст график, зеркально отражённый относительно оси y.

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

На графике слева синяя кривая снова представляет наш табличный набор точек, а чёрная тонкая кривая соответствует уравнению y = 2*√x. Мы видим, что наш множитель (так называемый масштабирующий коэффициент) вывел нас на финишную прямую в вопросе аппроксимации табличных значений. Ура!

6. Отклонение и критерий точности

Наше уравнение y = 2*√x достаточно точно аппроксимирует числовую последовательность, полученную из таблицы. Глядя на график сверху, вы, однако, сможете заметить расхождения (особенно они видны на участке (x = 30, x = 250). Мы уже исключили из рассмотрения точки, которые явно подгонялись дизайнером проекта вручную, поэтому сейчас такие расхождения можно объяснить округлениями. Действительно, в точке x = 80, например, наша формула даёт результат 17.889 (даже сейчас пришлось округлить его до третьего знака после запятой), тогда как в таблице мы видим, что времени 80 минут соответствует цена 18 монет. Такое отклонение не смутит нас в данной ситуации, однако часто ситуация бывает другой.

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

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

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

В крайнем правом столбце мы (простым вычитанием) вычислили разницу между фактическим значением цены в таблицы и тем, что даёт нам формула. Заметьте, что мы вычислили лишь модули этих разниц (т е. только их значащую часть, без знака). Это потому, что нас не интересует, «в какую сторону» ошибается формула, а лишь то, насколько она ошибается.

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

В нашем случае просто суммируя модули разниц, мы получим число, примерно равное всего лишь 3.12. Неплохо, с учётом того, что среднее значение цены в таблице составляет 15.4.

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

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

7. Анализ функции

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

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

Исследовать рост и убывание функции нам поможет её производная. Прозводная от функции f(x) — это другая функция, обозначаемая f’, которая говорит о том, насколько быстро изменяется значение f(x) при изменении x. Очевидно, что f‘ — тоже функция от x, поэтому мы используем запись f’(x).

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

f(x) = a*xb + c

Для неё производная будет выглядеть так:

f’(x) = a*b*xb-1

По сути, чтобы вычислить производную, мы берём степень x и ставим её перед x в качестве множителя, а степень x при этом сокращаем на единицу. Производная от константы c будет равна нулю, потому что константа не изменяется вообще.

Например: производная от f(x) = x3 будет равна f’(x) = 3*x2.

Хитрее дело обстоит, например, с корнем. Алгоритм тот же, но степень у x в результате становится отрицательной.

Например: производная от f(x) = √x будет равна f’(x) = 0.5 * x-0.5 = 0.5 / x0.5 = 1/(2*√x).

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

Предположим, что у нас есть две функции:

  • f(x) = 10*x2, производная f’(x) = 20*x. Давайте считать, что эта функция отвечает за некое суммарное развитие игрока (т. е. составляет его доход в том или ином виде).
  • g(x) = x3, производная g’(x) = 3*x2. Представим, что эта функция отвечает за увеличение игровой сложности (т. е. составляет расход игрока в том или ином виде).

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

  • Для точки x = 2: f’(2) = 40, g’(2) = 12.
  • Для точки x = 10: f’(10) = 200, g’(10) = 300.

Во-первых, обе производные положительны, а это значит, что обе функции растут. Кроме того, видно, что сначала функция f растёт быстрее, но затем уступает в скорости функции g. Поскольку чем больше x, тем больше преимущество в скорости у g, можно не сомневаться, что рано или поздно g обгонит f. Если мы хотим узнать, в какой точке это произойдёт, придётся решить уравнение f(x) = g(x). Решением такого уравнения являются две точки: x = 0 и x = 10. Первая нам не подходит (уровень начинается с 1), а вот вторая — и будет той точкой, в которой расход игрока превысит его доход. Вырисовывается картинка игровой экономики — вплоть до десятого уровня игрок имеет профицит, а после этот профицит постепенно сходит на нет, пока не превратится в дефицит.

Базовые правила для исследования роста или убывания функции с помощью производной могут быть сформулированы так:

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

Заключение

Реверсный инжинеринг баланса — дело не только сложное, но и муторное. Ваша задача — просмотреть множество игровых переменных в их взаимосвязи, построить множество графиков и аппроксимировать множество табличных значений, чтобы получить множество функций. Но результат выполнения этой задачи того стоит! Проведя правильный реверс баланса проекта, вы сможете проникнуть в его математическую суть — увидеть те ниточки, которые стягивают проект воедино. Этими ниточками вы потом сможете пользоваться в своём проекте — совершенствуя их или оставляя такими, какими они были задуманы в самых успешных проектах индустрии.

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

    Комментарии

    Войдите на сайт, чтобы оставить комментарий

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

    Google Chrome Firefox Opera