Введение в баланс экономики

Введение в баланс экономики

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

В ней вы найдете такие увлекательные вещи, как:

  • числа!
  • больше чисел!
  • скриншоты таблиц с числами!
  • быстрое и невнятное введение в тервер!
  • скрипт на Питоне!
  • непонятные графики!
  • ссылка на гугл-таблицу!

Запрыгивайте и поехали.

Теория

Что вообще такое баланс?

Это просто числа. Числа и взаимосвязи между числами - в общем, система.

Я привык делить баланс на две крупные категории:

1. Боевой баланс

2. Экономический баланс

CCP Games - <a href="https://api.dtf.ru/v2.8/redirect?to=https%3A%2F%2Fwww.eveonline.com%2F&postId=87068" rel="nofollow noreferrer noopener" target="_blank">Eve Online</a>
CCP Games - Eve Online

Если системы в балансе нет, наступает дизбаланс. Это не то, что мы хотим, ведь правда?

Введение в баланс экономики

Сегодня я хочу немного поговорить об экономическом балансе.

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

Введение в баланс экономики

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

Введение в баланс экономики

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

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

Практика

Ну ладно, а теперь к делу! Давайте сами построим простой игровой цикл.

Введение в баланс экономики

Игра:

  • игрок может убивать монстров
  • игра разбита на уровни
  • с монстров падает золото
  • игрок тратит золото на покупку оружия и банок здоровья

Условия:

  • есть 10 уровней
  • есть 5 комплектов оружия помимо стартового
  • нужно, чтобы игрок провел в игре 20 дней

Основная идея циклического баланса в том, что в определенных точках игрок должен тратить то, что накопил - собственно, обеспечивая баланс доходов и расходов.

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

1. Распределяем контент по дням

Начнем с некоторых допущений. Нам нужно, чтобы игрок играл 20 дней, но у нас есть только 10 уровней, и только 5 комплектов оружия. Так что придется заставить игрока погриндить - сначала чтобы пройти уровень, а потом чтобы получить новое оружие.

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

  • в начале стоит выдавать контент щедро
  • чем дальше, тем реже его можно выдавать - в надежде, что у игрока уже сформировалась привычка играть в нашу игру

2. Доходы и расходы

Теперь давайте посчитаем доходы и расходы игрока. Во-первых, давайте перейдем от "игрок получает уровень X на день Y" к "игрок проводит X дней на уровне Y":

Введение в баланс экономики

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

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

Допустим, что доход в день на уровне X равен X, умноженному на некий коэффициент k:

f(X) = X * k

И пусть k равен 100, потому что почему нет?

Введение в баланс экономики

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

​

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

  • игрок играет ровно так, как мы считаем, что он играет
  • он покупает и использует банки здоровья мгновенно, сразу после получения урона
  • он покупает оружие мгновенно, сразу как у него хватает на это золота
  • в конце каждого уровня у него должно оставаться 0 золота

Начнем с дней и уровней, в которые игрок не покупает оружие. Очевидно, это значит, что там он тратит 100% того, что зарабатывает, на банки здоровья:

Введение в баланс экономики

Что насчет остальных уровней? Тут мы опять можем позадаваться какими-то пропорциями, которые кажутся нам логичными. Например, предположим, что на первом уровне игрок тратит 30% своего дохода, чтобы купить оружие, а потом пропорция сдвигается в сторону более дорогого оружия.

Введение в баланс экономики

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

Введение в баланс экономики

3. Монстры

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

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

Введение в баланс экономики

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

Что обычно делает гейм-дизайнер, когда сталкивается с проблемой того, что что-то "слишком предсказуемое"? Он использует рандом, и теперь у него две проблемы.

Допустим, мы хотим, чтобы было как-то так:

  • с монстра может упасть "мало" или "много" золота
  • "мало" золота может упасть с большей вероятностью, чем "много"

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

Теперь давайт выберем какие-то вероятности. На мой вкус 70% выглядит достаточно высоким шансом, а 30% - достаточно низким:

Введение в баланс экономики

Но что теперь?

Быстрое отступление про теорию вероятностей

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

Можно подумать об это так: возьмем обычную игральную кость (ее еще иногда называют D6, потому что у нее шесть граней). Давайте поиграем с ней в простую игру:

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

Сколько очков мы получим за бросок в среднем? Если бросить кость тысячу раз (нам же нечем больше заняться) и взять арифметическое среднее, мы получим какое-то число, довольно близкое к 3.5.

Введение в баланс экономики

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

Но можно ли как-то получить этот результат без того, чтобы много раз бросать кость? После первых 900 раз игра немного надоедает.

К нашему счастью, средний результат броска кости D6 - это и есть ее матожидание. Посчитать его можно так:

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

Поскольку мы считаем, что кость - честная, вероятность выкинуть любую из граней одинаковая и равна 1/6 (потому что у кости 6 граней).

Так что матожидание игральной кости:

M = 1 * 1/6 + 2 * 1/6 + 3 * 1/6 + 4 * 1/6 + 5 * 1/6 + 6 * 1/6 = 3.5

Все сходится. Слава богу, что мне больше не надо бросать кость.

Снова к монстрам

Итак, в нашем случае "золото за одного монстра" - это матожидание награды за убийство этого монстра:

М = золото(min) * p(min) + золото(max) * p(max)

Мы уже знаем M и выбрали p(min) и p(max), но у нас по-прежнему одно уравнение и два неизвестных, так что нужно либо найти где-то больше уравнений, либо избавиться от одного из неизвестных.

Давайте решим, что "мало" золота - это половина нашего "золота за одного монстра":

золото(min) = M / 2

Теперь несложно найти золото(max):

золото(max) = ( M — золото(min) * p(min) ) / p(max)

Введение в баланс экономики

4. Банки здоровья

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

Введение в баланс экономики

5. Резюмируем

Мы построили грубую модель простой игровой экономики. Мы:

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

Модель намеренно не очень хорошая, и сейчас мы с вами в этом убедимся.

6. Проверка

Я написал простенький скрипт на Питоне, чтобы проверить свой баланс:

import random monsters_count = 3 gold_min = 9 p_min = 0.7 gold_max = 36 p_max = 0.3 golds = [] for j in range(100): gold = 0 for i in range(monsters_count): roll = random.random() if roll < p_min: gold += gold_min else: gold += gold_max golds.append(gold) print(“У среднего игрока: “ + str(sum(golds)/len(golds)) + “ золота”)

Если вы не знаете Питон - ничего страшного. Вот все, что происходит в этом скрипте:

  • задаем значения переменных для количества монстров, наград в золоте, вероятностей для уровня 1 (мы их только что посчитали)
  • создаем пустой массив
  • повторяем сто раз, как будто играют сто игроков:
  • “кидаем монетку”
  • на основе заданных шансов решаем, получит игрок "мало" или "много" золота
  • повторяем столько раз, сколько монстров на уровне
  • складываем полученное "игроком" золото
  • добавляем в массив, который до этого создали
  • берем арифметическое среднее по массиву и выводим в человекочитаемом виде

Если хотите, можете попробовать выполнить этот скрипт сами. Для этого вам понадобится пойти на сайт Питона, нажать "Downloads" и следовать инструкциям для вашей ОС. Питонов бывает два: Python 2 и Python 3. Я использую 3.

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

Итак, результаты:

У среднего игрока: 53.19 золота

Выглядит неплохо! По расчетам должно было получиться 50, но результат не так уж далек от требуемого. В конце концов, в наших расчетах мы много чего округляли, а рандом не гарантирует ничего на 100% (на то он и рандом), так что все в пределах нормы.

Это ловушка, в которую часто попадают начинающие гейм-дизайнеры. Жизнь среднего игрока выглядит нормально, но существует ли средний игрок на самом деле?

Давайте немного улучшим наш скрипт и добавим код для визуализации результатов. Если вы хотите повторить это у себя, вам нужно будет пойти в консоль (cmd для Windows, Terminal для Mac) и написать "pip install seaborn", а потом "pip install matplotlib", чтобы установить библиотеки визуализации данных, которые я буду использовать.

import random import seaborn as sns import matplotlib.pyplot as plt monsters_count = 3 gold_min = 9 p_min = 0.7 gold_max = 36 p_max = 0.3 golds = [] for j in range(100): gold = 0 for i in range(monsters_count): roll = random.random() if roll < p_min: gold += gold_min else: gold += gold_max golds.append(gold) print(“У среднего игрока: “ + str(sum(golds)/len(golds)) + “ золота”) sns.set() fig = sns.distplot(golds, kde=False) fig.set(xlabel=’Количество золота после уровня 1', ylabel=’Количество игроков с таким количеством золота’) plt.show()

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

Введение в баланс экономики

Упс. 40 игроков действительно получили около 55 золота, но:

  • 40 других игроков получило примерно 35, что меньше, чем было надо. Скорее всего, они будут не очень счастливы в игре, потому что им будет не хватать золота на новое оружие или банки здоровья.
  • 17 игроков получили примерно 80 золота, и еще 3 получили примерно 100, что означает, что для них игра будет слишком простой

Почему так получилось?

Проблема, разумеется, в том, как с монстров падает золото.

Тут примерно как на этой картинке:

Введение в баланс экономики

В среднем стрелок попал в "яблочко", но в действительности ни один отдельный выстрел в него не попал.

Как нам исправить сиутацию?

Добавить больше монстров

Для начала стоит понять, что рандом лучше работает на больших числах.

Если взять уровень 10, то там игроку нужно убить 15 монстров с "маленькой" наградой в 100 золота и "большой" наградой в 434 золота, чтобы заработать 3000 золота на этом уровне. Если прогнать все это через скрипт, мы получим следующее:

Введение в баланс экономики

Картина все еще не очень, но что, если бы на уровне 10 было сто монстров? В таком случае, с каждого монстра падала бы "маленькая" награда в 15 или "большая" награда в 65 золота, с матожиданием в 30 золота с монстра.

Введение в баланс экономики

Как видите, теперь количество золота распределено гораздо ближе к матожиданию: 2800-3200 золота вместо 2000-3500.

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

Сузить разброс наград

Давайте представим, что золото(min) равно M / 1.5, а не M / 2:

Введение в баланс экономики

Можно заметить, что результаты теперь стремятся ближе к 50. Они будут стремиться ближе и ближе, пока мы не достигнем точки, в которой золото(min) = золото (max) = M.

В следующей главе:

Баланс боевки! Посчитаем ХП игрока, скейлящаеся от его уровня, ХП монстров, урон игрока и монстров, и так далее.

Кстати, вот ссылка на мою гугл-таблицу:

Вопросы, на которые можно попробовать ответить перед следующей главой:

1. Сейчас баланс устроен так, что траты на банки на некоторых уровнях ниже, чем не предыдущих. Это не обязательно плохо, но как нам это поменять, если захотим?

Введение в баланс экономики

2. Что поменяется в расчете монстров, если вместо одинаковых монстров в пределах уровня будут одинаковые монстры и один босс? А если будут монстры, несколько мини-боссов и босс?

3. Что сделать с наградами за монстров, если мы хотим, чтобы впечатления игрока меньше зависели от рандома?

4. Как нам посчитать доходы и расходы экспы, если мы хотим, чтобы у игрока был уровень?

309309
75 комментариев

Комментарий недоступен

32
Ответить

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

8
Ответить

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

2
Ответить

Как пример работы инфа интересная, но это же дизайн мобильных дрочилен; правила 10 уровня не хватает только. Изыди демон!!!

14
Ответить

хм, а можно подробнее про правило 10 уровня?

3
Ответить

Да там вполне Diablo III описана. Золото с монстров падает. Понимаете?

1
Ответить

Мне кажется, что тут очень всколзь упомянуты важные моменты - исходные.
10 уровней и 5 мечей установлены как данность (и часто так и бывает), так же как и то, что в начале игроку чаще сыпятся оружие и проходятся уровни.
А меж тем, это имеет под собой веские основания - и весь дизайн в смысле математики подчинен этим требованиям.
Конкретно в статье указано несколько таких исходных - количество оружия и уровней, время игры и, предположительно, интерес для игрока

- Оружие и уровни - это ограничение по контенту - нам столько сделают художники за пол года и сделать больше будет сильно дороже и денег нет
- 20 дней - это бизнес требование, предполагается, что за это время игрок купит у вас 10 шапок или будет считать, что 30 баксов за полную версию потрачены не зря
- Интерес в игре - ну, очевидная вроде исходная, хотя, судя по мобильным сторам, не совсем. Мы знаем эмпирически, что в начале игрока нужно вовлечь, поэтому нужно делать больше интересных событий (выдачи оружия и награда игроку), а со временем - все реже, делая каждую следующую ценнее и дороже.

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

Как часто выдавать оружие зависит скорее от того, как интересно игроку играть в игру без нового оружия.

Если у тебя в игре только и есть что монстры и оружие, а игровой процесс не супер сложный - тебе нужно выдавать первое оружие через 5 минут, второе - через 10, третье - через 25 и т.д, эти величины нужно подбирать по ощущениям (после выпуска игры - по аналитике)
Соответственно баланс, посчитанный таким способом сможет ответить тебе на вопрос - если Я выдаю по 10 золотых с монстра, и игрок убивает Х монстров в минуту, сколько должно стоить первое оружие в магазине.

5
Ответить