Ложь во спасение: чем плох честный "рандом"

Пользователи хотят получать удовольствие и выступают за честные шансы «выбивания» предметов — но порой это взаимоисключающие явления, считает продюсер и продакт-лид 2RealLife, участник сообщества «Манжеты ГД», Григорий Чопоров. Свой взгляд на лучший способ реализации выдачи онизложилв статье для портала.

Хорошо ли быть с игроком честными до конца или нет?

Как часто пользователи рассказывают о том, что хотят максимально честного «рандома» в вашей игре? Часто? Очень часто? Так вот — люди врут. Напомню прописную истину геймдизайна: игроки хотят получать от игры удовольствие. Честность (если пользователи получают его в полной мере) заботит их в самую последнюю очередь.

Сегодня я предлагаю перестать верить игрокам и не делать честного «рандома», как минимум в тех случаях, когда необходимо совершить бинарный выбор (то есть определить, одержал игрок победу, или его постигла неудача). Например, если нужно определить, выпал пользователю предмет с убитого им монстра, или нет. О более сложных случаях (когда выбор производится из «n» вариантов) я расскажу в другой статье, хотя изложенный ниже метод можно применить и к ним.

Представим себе неискушённого в игровых механиках программиста, который по вашей просьбе реализует проверку вероятности. Как он поступит скорее всего? Возьмёт стандартную функцию (какую-нибудь «rand()», «random()» или «math.random()», в зависимости от того, на каком языке программирования пишет), получит случайное число от 0 до 1, умножит его на 100 и сравнит полученный результат с указанным вами шансом выпадения (например, с 10%). После чего со спокойной душой пойдёт дальше заниматься важными архитектурными задачами.

Устроит ли вас такой вариант? Если вы будете смотреть только на сводную статистику выпадения предмета — скорее всего да. Вы увидите, что примерно на каждые 10 попыток игроки (вот здесь будьте внимательны, не игрок, а игроки) получают один предмет (хотя скорее всего, конечно, на каждый миллион попыток пользователи получают 100 тысяч предметов). Что, казалось бы, хорошо, ведь этого вы и добивались. Однако вот отличная картинка, иллюстрирующая чувства, которые вы испытаете, если отвлечётесь от общей статистики и опуститесь до рассмотрения судеб отдельных игроков (а это в целом надо делать как можно чаще, — вторая прописная истина).

Рассматривая каждого игрока по отдельности, вы увидите, как много среди них тех, кто не получает предмет за 15 и даже 20 попыток, и тех, кому они выпадают каждые пять-шесть раз. Но, можете сказать вы, пройдёт время, и кривая «рандома» всех уравняет.

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

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

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

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

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

  • current_chance = (max — goods) / (length — tries)

Здесь «max» и «length» — задаваемые вами константы, равные желаемому количеству получаемых игроком предметов («max») из желаемого количества попыток («length»). Например, «max = 10 предметов из length = 100 попыток» (что будет эквивалентно 10% шансу выпадения по схеме, реализованной вашим неискушённым программистом).

Две другие переменные («goods» и «tries») принимают значения, равные количеству уже выпавших на данный момент предметов (goods) из количества уже совершённых на данный момент попыток (tries). Как только «tries» становится равным «length», всё начинается заново, и так по кругу.

Несложно подсчитать (если вам сложно, смотрите в таблице ниже), что в таком варианте реализации шанс успешной попытки растёт при каждой неудачной, пока не достигнет единицы (или 100% — для самых редких неудачников), и возвращается к базовому, равному «max/length», при каждой следующей удачной попытке. В конечном итоге, настроенная таким образом выдача будет гарантировать получение игроком 10 предметов из 100 попыток (не больше и не меньше).

Всё стало на свои места, и ожидания игроков совпали с реальностью, отлично. Но этого должно быть мало для пытливого геймдизайнерского ума! Дополнительный вопрос — а сможем ли мы проконтролировать выдачу 10 предметов из 100 попыток так, чтобы игрок, например, чаще получал предметы во время начальных попыток (и радовался, что ему благоволит «рандом») и реже — во время конечных (чтобы не портить вам расчёты экономики)? Конечно, достаточно ввести в формулу магический коэффициент «k» следующим образом:

  • current_chance = ((max — goods) / (length — tries))*(k^(max — goods))

В итоге при «k = 1» ничего в выдаче не изменится (и она будет равнораспределённой), при «k > 1» игрок будет чаще получать предметы на начальных попытках, а при «0 < k < 1» — на конечных. Если результат деления равен или больше 1, то на «k^(max - good)» умножать не надо (чтобы самым неудачливым пользователям предмет выпал хотя бы на последней попытке).

Обманываем ли мы игрока? Конечно, обманываем. Становится ли ему от этого лучше? Конечно, становится. Получается ситуация, выигрышная для обеих сторон (побольше бы таких, вот последняя на сегодня прописная истина).

Ну а теперь примеры. Ниже вы найдёте таблицу, в которой для выпадения 10 предметов из 100 попыток и трёх разных значений коэффициента «k» посчитано, на какой попытке выпадет каждый предмет.

Надеемся, что с этой таблицей всё стало ещё понятнее!

Нравится6
Комментарии (2)
  • 2


    Довольно очевидное решение, которое практикантам не выгодно.

    Немного профессионального юмора из Warframe. Свыше 20 раз ходил за 1 из 4 частей одной вещи. При этом каждый раз со мной участвовало три других человека, имеющих тот же предмет, что и я, из которого может выпасть эта часть при выполнении определённых условий. Кроме того, этот предмет можно прокачать, чтобы повысить шанс дропа этой части до 10% (по официальному заявлению). Т.е. в итоге, ничего не выбив, в сумме мы впустую потратили 80 предметов, случайно получаемых на одних миссиях, прокачиваемых на других и открываемых на третьих.

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

    Рассматривая каждого игрока по отдельности, вы увидите, как много среди них тех, кто не получает предмет за 15 и даже 20 попыток, и тех, кому они выпадают каждые пять-шесть раз. Но, можете сказать вы, пройдёт время, и кривая «рандома» всех уравняет.

    Бесспорно, однако здесь и сейчас одна часть ваших игроков слишком несчастна, а другая — чересчур счастлива.


    Только происходит это отнюдь не из справедливости рандома, а вероятно из хитросплетений машинального и маркетингового анализа внутриигрового рынка, а может и самих игроков. Учитывая происходящее в трейде приведённой мною игры, рандом скорее пытается уравнять количество предложений к количеству спроса. Ведь если из 10000 игроков окажется 5000 счастливчиков, из других пяти тысяч невезучих окажется недостаточно много игроков, заинтересованных в получении именно этой вещи. Это приводит к соотношению сообщений типа "want to sell" и "want to buy" 20к1 соответственно, что в конечном счёте недвусмысленно намекает на последующий заработок правовладельца.

    Потому в мультиплеерных играх и в ММО в частности справедливый, неконтролируемый или контролируемый, описанный афтором, рандом ведёт к риску владельца не получить денежный профит с внутриигровых прикруток. Так что ИМХО: в них объективного рандома вообще нет. Он есть субъективно: мне плюшка выпала, значит я натурал и прославлен.
  • 0
    Нужно прописать алгоритм, который учитывал бы предыдущие варианты неудачного события (когда предмет не выпал). Таким образом, после каждой неудачной попытки выпадения предмета, шанс на выпадение будет значительно повышаться. То есть чтоб невозможно было 50 неудачных выпадений... Как-то так )
B
i
u
Спойлер