Краткая выжимка доклада Shay Pierce с GDC 2017 года о техниках при написания рандомайзера в своих играх.
Shay работал над многими играми, в том числе над Hearthstone. В этом докладе он делится советами о том, как лучше реализовать систему рандома в своих играх.
Стоит сразу отметить разницу между бросанием кубика и вытаскиванием карты из колоды. В первом случае у вас будет весьма неравномерное распределение. Когда как во втором, в следствии того, что вытащенная карта не возвращается в колоду, шанс стриков меньше.
Секрет #1: каждый пограничный случай, который может произойти, обязательно произойдёт
Как разработчик, вы — последняя линия защиты в таких вопросах. Часто бывает, что дизайнеры не умеют в матан (да-да, такое бывает), ваша задача донести до них этот нюанс.
Pity Timer
Система гарантирует, что вы рано или поздно получите редкий лут. Если говорить про Hearthstone, то вам, как минимум, гарантирована одна легендарка на 40 паков.
В Diablo 3 в своё время ввели систему, которая гарантировала дроп легендарки, если вы отыграли определённое количество часов. После получения счётчик сбрасывался.
Оригинального Blue post’а больше не найти, но сообщение упоминается во многих других постах.
The fact that some people claim to go for 10+ hours without finding a legendary is not only not our intent, but should in fact be impossible. We added a system in the expansion that tracks the amount of time you spend fighting creatures without finding a legendary and after a certain period of time will slowly start increasing the legendary drop rate. Once a legendary drops for you, actual item not crafting recipe or material, we reset that timer. This is meant to be a safety net so that the random can never be too extreme to the negative end. If players are legitimately going 18+ hours and not seeing a legendary it’s possible that there are some bugs floating around that need to be identified.
— Blizzard
Секрет #2: человеческий мозг плохо умеет в рэндом
Если шанс дропа шмотки 1%, то убив монстра 200 раз, люди понимают, что есть шанс, что они не получат шмотку, но всё равно они жалуются на это.
Они не ожидают подобного в реальности.
Многие игры эмулируют «справедливость». Pity Timer как один из вариантов.
Секрет #3: люди всё равно в любом случае будут жаловаться на рэндом и несправедливость
Занятная история произошла в сообществе игры The Urban Dead, где игрок отметил закономерность в RNG с таймингом. Если отсчитать примерно 8 секунд и нажать кнопку SEARCH, то рандом сработает в вашу пользу. Дальше в ветке ему указали на то, что «это нонсенс, т.к. в игре используется генератор случайных чисел». Но штука в том, что на вход в функцию как сид передавалось текущее время srand(time())
, что и стало причиной подобной закономерности.
Как вариант реализации Pity Timer он приводит Lookup table, когда вес апается при неудаче, а при успехе вес сбрасывается до дефолтного состояния.
В MMORPG куча разных классов и их важность разнится. Лут для некоторых классов катируется куда сильнее, чем для других. Часто для решения этого вопроса для каждого класса прописывают отдельные веса, чтоб уравновесить экономику игры.
Есть смысл завязывать систему дропа лута на распределении игроков и популярности класса.
Random hashing и deep echoes
В одной игре два случайных города выглядели одинаково, что дезориентировало игроков. Ведь у вас используется какой-то seed для рэндом функции, значит города должны быть случайны, так?
Как пример приводит генератор вселенной, где сид одного уровня генерации используется для генерации нижних уровней. И если на каком-то этапе сид совпадёт, то вы получите одинаковые галактики/солнечные системы/планеты/города, в зависимости от того, на каком уровне произошла коллизия.
Они пришли к решению, когда при вычислении хеша используется информация о слое и родителе. В итоге, даже имея одинаковый сид, дочерние элементы будут генерироваться разные.
Тут всё зависит от восприятия игрока. Естественно на каком-то уровне элементы будут одинаковые — похожие дороги и т.п, но в силу того, что остальное окружение отличается, игрок может даже этого не заметить.
В силу специфики хеш функций, всё ещё остаётся вероятность, что части солнечной системы могут быть похожи — одно и то же расположение планет, те же названия.
Нет идеального решения проблемы в силу математической природы задачи. Если у вас на входе больше, чем на выходе, то вы столкнётесь с «принципом голубей и ящиков», когда при условии, что голубей больше, чем клеток, у вас точно будет клетка с более, чем одним голубем. Так называемый Принцип Дирихле.
Если вам нужно вариантов больше, чем вы можете предгенерировать (как пример, из-за ограничения int32), то вы столкнётесь с такой проблемой.