Вопрос о генерации мира

Это очень не нравилось Эйнштейну, но учёные доказали, что Луна действительно не существует, когда на неё никто не смотрит.

Программирование любой игры сложнее самой этой игры на столько же, насколько то, что под капотом у БМВ, сложнее цепи у велосипеда. Поэтому любые попытки объяснить то, что ты хочешь, на данном форуме приводили в прошлом к минусаторству и обвинениям в “заумности”.

TL;DR и VLR (Very Long Read!)

Я вас предупредил :wink:

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

Устройство ММО-проектов в целом...

Главная идея: по офф.данным, на старте игры было больше 10 млн. активных игроков, которые все играли одновременно. А один сервер тянет, допустим, всего 10 тысяч (в реальности меньше). Поэтому проблему решали добавлением серверов. Как это могло бы быть реализовано?

Во-первых, в игре нет такого понятия, как “просто сервер”. Есть несколько типов серверов. Например, стартовый экран - это так называемый “дорвей-сервер”, локации - “айтем-сервер”, а дропом заведует “дроп-сервер”. Что происходит при входе в игру?

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

Игровой сервер виртуализирован. Это значит, что на одной физической железке крутится несколько таких игровых серверов, каждый из которых называется “пулом” - и если железка способна, допустим, “держать” одновременно 10 тысяч игроков, то конкретный пул лимитирован, к примеру, всего 100 игроками (но на сервере крутится 100 пулов). Это при том, что в игре вы можете одновременно играть всего вчетвером.

При входе в игру игроку показывают трёхмерный старт-скрин, а при заходе в саму игру его рандомно переключают на один из игровых пулов.

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

Поняв вот эту вот идею, можно понять, как устроен дроп в игре.

Если у вас есть шахматная доска (локация) и шахматные фигурки (монстры в игре), то доска всё время может просто лежать на столе - а фигурки вы ставите и снимаете в зависимости от игры на ней. Аналогия в том, что нет необходимости каждый раз прокачивать вот все эти гигабайты игровых текстур, анимаций и всего остального, что нужно для 3D-локации. Это всё постоянно в памяти игрового сервера.

Но т.к. для каждой локации нужен свой набор трёхмерных объектов (первый акт это текстуры монастыря, второй - пустыни и т.д.) то набор данных для каждого сервера сокращается в разы.

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

Это подтверждается тем, что в ранней ванильной версии Диабло 3 существовала ошибка, при которой иногда на одном сервере бегали пятеро игроков одновременно.

Так вот. Эти четвёрки в игре не пересекаются друг с другом, но важно понять, что они всё равно бегают в одном пуле из сотни человек!

Если вы всё это поняли, то дальше - вторая часть, в которой уже собственно, о том, как устроен дроп в ММО-играх.

А теперь о дропе...

Понимаете, что получается?

Вместо того, чтобы каждый раз запускать рандом-генератор на то, чтобы решать, какой предмет выдать игроку, мы уже ЗАРАНЕЕ запускаем рандом-генератор, определяя, на какой игровой сервер и в какой пул попадёт игрок!

Отсюда дальнейшая оптимизация: остаётся разделить дроп на части и прописать каждому пулу по своей таблице выдаваемых предметов. Помните, что у нас есть минимим по 10 серверов, каждый из которых крутит одинаковые локации? Делим триста легендарок на 10, получаем (условно) 30, которые вам может выдать сервер в конкретном пуле. Это называется “таблицами дропа”. Они делятся на части и раздаются игрокам.

Поэтому, если рифт “пустой”, то он и весь “пустой”. Или, если выпал нужный вам предмет, то есть смысл фармить “до столба”, т.к. предмет есть в дропе. Опытные и много играющие игроки уже по составу первых вапавших предметов примерно понимают, что может выпасть дальше, т.к. таблицы одни и те же и меняются сравнительно редко.

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

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

Так вот, в ванильной версии до определённого момента работала схема, при которой “счастливые” сочетания виртуальных адресов пулов (айпи+порт) были “приколочены гвоздями”. Но после того, как это прочухали игроки, схему пришлось сделать более динамической.

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

Отсюда становится понятно, в момент, когда вам что-то должно дропнуться, не генерится ничего вообще!

Как так?!...

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

Поэтому в момент получения предмета работает ещё более хитрая схема)))

Предмет генерится на весь пул в 100 игроков целиком!

Йопс… это как вообще? А очень просто: раз есть пул, то это означает, что игроки уже автоматически выстроены в очередь. Не нужно вычислять никому никакой рандомной вероятности в момент получения предмета - нужно лишь отсортировать игроков по приоритету получения предметов - и вуаля!

Поэтому, в момент каждого-каждого-каждого ивента на получения предмета, игровой (локационный сервер) отправляет запрос на предмет на весь пул (очередь из допустим, 100 игроков) в целом. И дальше спускает его по этой очереди, как по трубе.

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

Но как только он оденется, его приоритет в очереди упадёт и дроп, соответственно, станет хуже.

Таким вот мудрёным способом достигается оптимизация. Разумеется, описан не конкретный подход Д3, а общий и (ппц вообще, да?) упрощённый. Но, как известно, “мир состоит из атомов”, а остальное вы додумаете самостоятельно))

Бонус, чтобы окончательно свернуть мозги ;)

Если вы разработчик ММО-игры, то помимо раздачи дропа, у вас ещё стоит проблема безопасности игры. Не забывайте, что даже в Д3 на старте был RMAH (аукцион за вполне реальные деньги!), поэтому дроп должен быть организован так, чтобы никто из рядовых сотрудников (типа сисадмина, меняющего сервера) не мог подкрутить ничего на конкретном сервере (чтобы прото запомнить его признаки и скипать остальные сервера, имея игровое преимущество).

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

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

Со одной стороны, вмешательство со стороны оказывается невозможно и недоступно для персонала, у которого есть доступ к самим серверам, но нет прав ))). А с другой - таблицы дропа тянутся централизованно, поэтому игрой можно управлять, меняя эти самые таблицы (которые состоят из чего-нибудь вроде описаний пар “предмет+вероятность”). Чем и занимаются разработчики из условного центрального офиса Д3 уже 7 лет.

Однако эта система иногда приводит к парадоксальным казусам: например, предлагаемые предметы на первой странице ванильного аукциона в Д3 зависели от того, что надето на игрока. Нет у вас, допустим, перчаток - и аукцион автоматически предлагает купить.

Аук не выпилили; ему просто заблокировали интерфейс и все зависимости всё равно остались. Поэтому теперь, если у вас уже полно критшанса на предметах, иногда можно например, упариться роллить у кидалки КШ на предметах или предметы с КШ.

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

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

Дело в том, что из-за стохастичности принимавшихся в истории игры решений, как именно работает вся эта система, не знает в точности уже вообще никто, включая самих разрабов, которые успели 10 раз поменяться )))

Отсюда вывод:

Никакого рандом-генератора как конкретного механизма в игре нет - он распределённый и реализован иными принципами.

И наконец, аукцион )))

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

Теперь делаем выводы:

  • в начале сезона ни у кого ничего нет и айтем-сервер всем всё раздаёт равномерно;

  • в конце сезона “папики” уже собрали на себя кучу предметов определённого типа (т.к. все топ-билды в игре всё равно как под пипирку).

Айтем-сервер смотрит: “ха! в игре дохрена сапог” и фиг вы получите свой красный лук Яна.

Как-то вот так…

3 лайка