Сегодня статья сугубо практическая. Я поделюсь с вами инструкцией по созданию инструмента для расчета loot box’ов, в создании которого я принимал участие под руководством Константина Сахнова, будучи Ведущим гейм-дизайнером в компании Rocket Jump. Материал публикуется с разрешения компании Rocket Jump.

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

Алгоритм действий

Начнем с алгоритма предстоящих действий. Состоит он из нескольких пунктов:

  1. Подготовка таблицы: ввод имеющихся данных (предметы, стоимости, категории, стоимость сундука и т.д.);
  2. Определение доли каждой категории в сундуке (в процентах);
  3. Расчет шансов выпадения каждого предмета в категориях;
  4. Корректировка шансов;
  5. Перенос расчетов в проект.

Подготовка таблицы

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

Лист Items

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

2017-12-17 21.03.33
Рис 1. Пример таблицы с перечислением сущностей

Стоит отметить, что, помимо имен предметов (internal_name), в удобном для нас формате, для расчетов нам необходимо добавить следующую информацию:

  • стоимость (price, gold) — в качестве примера наши сундуки продаются за золото. Стоимость поможет настроить вероятность выпадения в соответствии с ценностью предмета;
  • категория (category) — если предметы неравноценны, то категория позволит определить их долю относительно предметов из других категорий, содержащихся в сундуке. Чем категорий больше, тем проще управлять вероятностями в большом списке предметов;
  • подкатегория (subcategory) — вводится по желанию, позволяет сделать настройку шансов более тонкой, в данном примере не используется.

Лист Chests

Далее необходимо создать лист с вводными данными, из которых и будут производиться расчеты; назовем его Chests. Все дальнейшие действия рассмотрим на примере одного единственного сундука. Таблица с вводными данными может выглядеть следующим образом (см. Рис. 2):

2017-12-17 21.06.33
Рис 2. Пример таблицы с вводными данными

Данная таблица должна содержать следующие обязательные параметры, которые и являются вводными (настраиваемыми) данными:

  • Chest Target Price — стоимость сундука, которая определяется методом волевого решения или любым другим способом. Именно с ее помощью мы будем рассчитывать вероятность выпадения того или иного предмета;
  • Chest Slots — количество слотов в сундуке, т.е. уникальных наград, выпадающих из сундука (может быть = 1);
  • Slot Categories — категории, на которые разбиты все предметы, содержащиеся в сундуке;
  • Probability — данный параметр определяет вероятность выпадения предмета из соответствующей категории. Сумма вероятностей по категориям должна = 1 (или 100%).

В остальном таблица содержит:

  • Expectation — средняя награда (мат. ожидание) в категории, выраженная в золоте. Их сумма определяет среднюю награду, которую получит игрок;
  • Chest Price Gold — стоимость сундука, выраженная в золоте (расчеты необходимо производить в единой валюте);
  • Slot Target Price — средняя награда за один слот. Считается как отношение стоимости сундука к количеству слотов. К этому параметру должен стремиться параметр Expectation;
  • Slot Real Price — средняя награда, которую игрок получит в одном слоте. Показывает, насколько выдаваемая средняя награда (сумма Expectations) выше или ниже реальной стоимости слота (Slot Target Price);
  • Overprice — показывает разницу между тем, сколько награды получит игрок (сумма Expectations) и стоимостью слота (Slot Target Price). В примере на Рис.2 стоимость выдаваемой награды выше стоимости сундука на 54%.

В таблицах для наглядности удобно применять цветовое форматирование. Например:

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

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

Лист Example Chest

После создание листа с вводными данными можно перейти к листу сундука; назовем его Example Chest. Данный лист может выглядеть следующим образом (см. Рис. 3):

2017-12-17 21.15.09
Рис 3. Пример расчетного листа

Лист содержит следующую информацию:

  • items — список всех предметов, которые вы планируете выдавать в награду в конкретном сундуке;
  • count — количество предметов, выпадающих за раз;
  • chance_manual — в этом столбце можно вводить шансы вручную, чтобы играть со средней наградой (Expectation), тут все зависит от желаемого результата;
  • price_calc — цена сущности, берется из листа Items;
  • category — категория сущностей, берется из листа Items;
  • chance — шанс выпадения сущностей, соответствующий доле категории в сундуке;
  • expectation — фактически мат. ожидание для каждой сущности сундука, сумма которых и будет являться средней наградой, выраженной в золоте. Рассчитывается по формуле:

2018-01-08 20.24.53

Формула 2.1

Расчеты

В расчетах задействованы два листа: Chests и Example Chest.

Расчет шансов по категориям

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

CategoryProbability / CategoryItemsCount = chance

Формула 3.1

т.е. отношение шанса категории из листа Chests к количеству предметов в этой категории. На примере категории Basic это:

0,60 / 56 =0,01071428571

Формула 3.2

Таким же образом производятся расчеты шансов для предметов из каждой категории.

Ручная настройка шансов

Теперь, посчитав шансы выпадения предметов (по формуле 3.1) в каждой категории и посчитав их мат.ожидание (по формуле 2.1), мы можем играть с Expectation и подгонять (или нет) его под Slot Target Price, чтобы в среднем не выдавать в награду больше стоимости сундука. Рассмотрим подгонку на примере предметов из категории Basic (см. Рис. 4):

2017-12-17 23.05.50
Рис 4. Пример честного (но неправильного) рандома

Из данного примера следует, что предмет, стоимость которого гораздо выше, выпадает с той же вероятностью, что и предмет более низкой стоимости. Сразу видно, что за счет дорогого предмета вырастает средний выигрыш (Expectation) и одинаковая вероятность с более дешевым предметом выглядит некорректно. Именно для этого нам и нужен столбец chance_manual, с помощью которого мы можем исправить эту проблему (см. Рис. 5):

2017-12-17 23.08.47
Рис 5. Пример правильного рандома

Теперь в среднем игрок получит предметов на одинаковую стоимость и проблема нивелируется. Также ее можно решить, добавив категорий или считая шансы от подкатегорий. Т.е. чем больше категорий предметов разной стоимости, тем тоньше можно производить настройку. В итоге оптимальным будет получить суммарное значение Expectation в листе Chests близкое или равное планируемому Slot Target Price.

Пересчет вероятностей

Так как шансы рассчитываются от стоимости сундука автоматически (равномерно), то, вводя значения вручную в chance_manual, нам необходим такой же, автоматический, пересчет остальных значений. Для этого я использовал стандартные функции VLOOKUP и COUNTIFS. В нашем примере дополнительная таблица расположена на расчетном листе сундука Example Chest (см. Рис. 6):

2017-12-17 23.16.26
Рис 6. Таблица для пересчета шансов

В данной таблице те же 5 категорий: Basic, Low, Medium, High и Premium. Значения в них передаются из листа Chests, но если мы введем в chance_manual хотя бы одно значение руками, шансы в категории пересчитаются.

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

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

Заключение

Подводя итог, еще раз отмечу, какие шаги необходимо предпринять, чтобы рассчитать шансы выпадения предметов:

  1. Составить список предметов со всеми необходимыми значениями (название, стоимость, категория);
  2. Создать таблицу с вводными параметрами: стоимость сундука, количество слотов, категории, шансы выпадения предмета из категорий и пр.;
  3. Создать расчетную таблицу, используя данные из таблиц, созданных в п.1 и п.2
  4. Посчитать шанс выпадения каждого предмета в категориях;
  5. Скорректировать шансы таким образом, чтобы Expectation равнялся Slot Target Price (если не задумано иное);
  6. Перенести расчеты в проект.

Как я уже говорил в начале статьи, данный метод подходит для расчета шансов выпадения предметов, но на этом работа не заканчивается. Процесс выпадения необходимо контролировать — управлять ожиданиями игроков. Более подробно почитать об этом можно в статье Григоря Чопорова «Честный рандом — нечестный». Надеюсь, этот пример будет вам полезен.

Спасибо за внимание и до новых встреч!