Как с ними справляются такие игры, как Minecraft или вообще любая MMO-игра, в которой есть звукосниматели?
Скажем, местность порождает 3 капли "грязи" каждый раз, когда вы копаете указанную местность. Скажем, у каждого элемента есть анимация вращения, вычисленная для каждого кадра. Если количество пикапов в мире очень велико, это будет бесполезным огромным расходом при вычислении фрейма для клиента на данном сервере, так как, вероятно, многие из этих предметов пикапов находятся на расстоянии световых лет от вас.
Так что я подумал, что вы должны «делать вещи» только с звукоснимателями, расположенными рядом с местным игроком, но все же это будет означать, что каждый кадр, который я должен проверять, достаточно ли близок к любому другому элементу звукоснимателя, чтобы он начал анимацию.
Мой актуальный вопрос: как другие ММО решили эту проблему?
источник
minecraft:dirt
) и счет (30), так что, когда игрок находится достаточно близко, чтобы поднять его, он просто добавляет как можно больше счета в инвентарь игрока. Если у игрока есть место только для 6 предметов, а стопка из 30 находится на земле, игрок соберет 6, аОтветы:
Просто загружая в память те части мира, которые находятся рядом с игроком. Все остальное подвешено к жесткому диску. Когда на расстоянии около двух километров лежит крошечный объект, игрок не может его видеть и не может с ним взаимодействовать. Поэтому нет причин обновлять его или отправлять в графический процессор для рендеринга. Чем меньше объект и диапазон его взаимодействия, тем ниже диапазон вокруг проигрывателя, куда вам нужно его загрузить.
Что касается выяснения того, что близко к игроку: это в основном сводится к хранению мира в структуре данных, оптимизированной для пространственного поиска. Хорошими кандидатами для этого являются пространственное хеширование и многомерные деревья .
источник
У вас есть две очень разные вещи для управления:
Сервер должен управлять всем миром авторским способом. Для этого необходимо общение с N клиентами (где N "массивный").
В принципе, клиент может знать обо всем мире, но это не нужно . Для клиента достаточно знать, что находится рядом с игроком. Предполагая, например, довольно грубое разбиение в виде сетки, необходимо знать только ячейку игрока и 26 ячеек вокруг игрока (или 8 ячеек, если у вас есть двумерная сетка). Несколько более мелкая сетка лучше, но вы поняли идею.
Теперь много пикапов, что такое «много»? Вы копаете, может быть, 5 вещей в секунду, это, может быть, два десятка номеров, которые необходимо обновить на сервере, и серверу, возможно, придется передавать их другому игроку, чья область интересов перекрывает вашу ячейку. Для компьютера это довольно смешной объем данных и пренебрежимо малый объем вычислений. Это может стать проблемой, когда в одной и той же ячейке сотни / тысячи игроков (тогда ваше разделение будет слишком грубым).
Серверу не нужно ни знать, ни заботиться о ротации пикапов или подобных деталях. С чего бы это?
Клиенту на самом деле тоже все равно, так как это всего лишь глазной леденец, который клиент может сделать на лету.
С точки зрения сервера необходимо знать, что вы копали в (30, 40, 50) в узле, в котором вы находитесь, и решает, что это порождает, например, три объекта типа 5 или один объект типа 7 с счет 3. Это все, что его волнует, и это все, что он говорит вам. Он также будет включать эту информацию в данные, отправляемые кому-либо, перемещающему свою область интереса через ячейку сетки позже (при условии, что она все еще там к тому времени).
Клиенту говорят, что там появилось три объекта, бла-бла. Теперь, показывает ли клиент карту ASCII-искусства, где теперь есть буква «D», или показывает вращающуюся кучу грязи, все равно. Независимо от того, имеют ли сваи разные повороты или вращаются только те, которые находятся рядом с вашим игроком, это тоже одно и то же. Это просто материал, который отображается на вашем мониторе, это ни на кого не влияет.
Таким образом, в конкретном случае, когда вы хотите вращать только близлежащие кучи грязи, вы можете просто выполнить проверку дальности всех объектов, о которых вы знаете. Поскольку набор данных не большая, даже грубая сила на все будет работать.
Вы можете (и должны), в зависимости от размера вашего раздела, тривиально удалять ненужные ячейки сетки.
Вы можете, конечно, дополнительно подразделить свою клетку и использовать что-то очень умное. Если хотите, используйте kd-Tree, но не ожидайте огромных успехов. Вы можете обрезать вещи с помощью манхэттенской злости, или вы можете сортировать свои вещи в маленькой собственной сетке ... но почему?
Проверка расстояния (действительно квадратное расстояние, но оно то же самое для вас) - это просто два умножения и сложение (оптимизированное для MUL, MADD, так что на самом деле это просто две операции), за которым следует ветвление или условное перемещение. Это почти так же быстро, как и любая другая операция, которая не удаляет целые ячейки сетки одновременно. На самом деле, это то, что вы могли бы даже сделать на GPU ...
Видя, как у вас будет несколько сотен или самое большее несколько тысяч проверок расстояния на одну и ту же позицию (квадратное расстояние отлично работает), у вас действительно не возникнет особых проблем с выполнением этого вычисления, тем более, что это скорее кэш-память. дружественная итерация по непрерывной памяти, и с условными ходами, это очень дешево. Нечто подобное (псевдокод)
rot = r[i] + 1; r[i] = ((dx*dx+dy*dy) < DIST_SQ) ? rot : r[i];
. Это одна итерация массива из нескольких сотен значений на кадр. Компьютер не должен заботиться об этом, это непрерывные загрузки и хранилища, простой ALU, нет веток и всего несколько тысяч итераций.Это (многие-к-одному) не тот же класс проблем (многие-ко-многим), что и на сервере. На самом деле, клиент не проблема.
источник
@ T.Sar пишет в комментарии, что вы должны изучить концепцию Minecrafts «загруженный кусок» для получения дополнительной информации. Если вы это сделаете, имейте в виду, что это довольно сложно в Minecraft из-за людей, которые строят машины в игре.
Ниже приведена очень упрощенная версия:
Мир делится на квадратные области (куски). В Minecraft также есть разделение по высоте, но большинству ммос это не нужно.
Игровой клиент заботится только о регионах, близких к игроку. Это гораздо проще, чем нарисовать круг вокруг игрока, но достаточно хорошо.
В Minecraft регионы имеют размеры 16x16 блоков, и клиент знает о 9x9 областях, по 4 области в каждом направлении. (4 региона восток + игрок региона находится в + 4 регионах запад = всего 9 регионов. Тот же север / юг)
В этих числах нет ничего волшебного, используйте то, что имеет смысл в вашей игре.
Клиент только оживляет вещи внутри этой области. Сервер вычисляет только такие вещи, как блуждающие монстры в регионах, близких к какому-либо игроку.
Когда игрок ходит по региону, ничего особенного не происходит, когда он пересекает границу региона, «край анимации» перемещается на один регион. Затем клиент должен спросить сервер о регионах, которые он сейчас видит.
Нет ничего плохого в наличии нескольких вложенных ограничений анимации. Например, анимированный предмет падает в области 3х3, блуждающие монстры в области 5х5 и просто показывают пейзаж в области 9х9.
Сервер хранит «замороженную версию» регионов, которые ни один игрок не видит. Если это занимает много памяти, вы можете разгрузить их через некоторое время. При следующем прибытии игрока регион перезагружается без выпадения предмета. Ты должен быть быстрее в следующий раз, Игрок 1.
источник