Давайте напишем ... MMO! Часть 9: Больший мир

Опубликовано NowhereMan - пн, 05/11/2020 - 23:21

20 января 2011

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

Мы хотим (полу-) бесконечный мир, а для этого нужна работа. Сначала давайте рассмотрим требования:

  • Графическая карта не бесконечно быстрая, поэтому мы можем рендерить только кусочки нашего мира по мере того, как мы перемещаемся. У нас будет противоречие между расстоянием и деталями. Мы хотим дать пользователю представление о мире, чтобы он знал, где он находится, и мог видеть интересные места. Но мы не можем тратить много времени на их визуализацию, иначе мы не сможем хорошо рендерить близлежащие объекты.
  • Полный мир будет содержать огромное количество данных. Дисковое пространство и пропускная способность также не бесконечны. Нам нужно разрезать мир на куски, чтобы сервер мог отдавать вам куски по требованию.
  • Мир процедурно генерируется, то есть создается алгоритмом, а не художником. Это позволяет нам генерировать местность по требованию по мере того, как вы перемещаетесь в новые области. Для того чтобы это реализовать, алгоритм ландшафта должен быть достаточно быстрым.
  • Как только местность сгенерирована, она может быть изменена пользователями. Они смогут изменять рельеф местности и создавать растения, здания, тварей и т.д... Мы должны обобщать их на расстоянии, чтобы не рисовать каждый дверной проем в далеком городе на горизонте.

Из чего сделаны миры

Далее, давайте определим все элементы мира.

Небо

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

Территория

Я буду использовать слово "территория", чтобы обозначить процедурно сгенерированный контент, который в данном случае будет астероидами. Нам нужно много уровней детализации - низкий для камня в небе, более высокий для того, чтобы подойти к нему из космоса, и полный, когда вы стоите на нем (или в нем).

Ландшафт

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

Растения

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

Строения

Структуры в стиле Minecraft, созданные пользователями. Обобщать их на расстоянии будет нелегко. Вы можете видеть кубы с большого расстояния, и замена группы 2x2x2 на один "сводный" куб разрушит множество структур.

Корабли

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

Скриптованные объекты

Упомянутые до сих пор элементы (небо, рельеф, ландшафт, здания и корабли) все статичны. Кроме того, будут объекты, которые могут быть скриптовыми. Все они основаны на объекте "аватар". Это скелет с блоками и другими формами, прикрепленными к конечностям. Под контролем скрипта конечность можно перемещать, перетаскивая блоки вместе с ним. Это может быть использовано несколькими способами:

Аватары По одному на пользователя, они представляют игрока.
Мебель Движимый объект и "конечности" скелета могут реализовать двери или другие движущиеся части.
Оружие Сценарий мог перемещать части (конечности), чтобы показать эффект стрельбы. Я не уверен, как реализуются "лучи" или снаряды.
Крепления Крепление перемещается вместе с пользователем и регулирует его скорость. Иначе, как аватар.
Твари Существо имеет независимую позицию и перемещается под контролем скрипта. Существа также могут быть одноразовыми, их позиции и номера забываются, когда вы выходите за пределы досягаемости.

Реализация

Чтобы реализовать все это, нам нужно решить некоторые проблемы:

  • Как мы представляем мир? Это вопрос структуры данных и затрагивает все требования. Мы должны уметь доставлять мир в кусках, с разной степенью детализации, и быстро рисовать его. Не будет единой структуры данных для всех типов объектов.
  • Как мы сгенерируем местность? Недостаточно просто сказать "шум, основанный на вашем положении x, y, z". Как нам расположить астероиды по размеру, чтобы получить хорошее сочетание? Как создать общую форму полигонов, которые вы видите на расстоянии? Насколько детальна поверхность астероидов, которую мы генерируем автоматически?
  • Как пользователи изменяют мир? Мы используем стиль Minecraft для добавления и удаления блоков на зданиях и других объектах. Мне все еще нужен стиль редактирования ландшафта и растений. Мне нужно выяснить, можно ли использовать аватары и другие объекты, сделанные из маленьких кубиков.

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

Поле астероидов

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

Я попробовал разные размеры в демо, чтобы посмотреть, как они выглядят. Радиус астероидов - 630 единиц, или 1260 по горизонтали. Расстояние между астероидами около 20 000 единиц кажется визуально правильным.

10 тысяч единиц - слишком близко.
20 тысяч единиц - почти правильно.
50 тысяч единиц - слишком далеко.

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

Не то, чего я хочу.

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

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