Возможно ли, чтобы Сервер отправлял Клиенту не что иное, как область на основе плиток?

8

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

Я создаю мир на основе тайлов, который создается с помощью простого 2D-массива. Давайте скажем что-то вроде World [100] [100], для простоты.

В настоящее время метод рендеринга рендерит только плитки на основе разрешения окна, плюс одну плитку (для плавного рендеринга во время движения.) Независимо от размера мира (10x10, 1 млн. Х 1 млн.) Рендеринг безупречен в производительности.

Игровому процессу не нужно ничего, кроме как знать, что находится в видимой в данный момент (отображается на экране +1), и, возможно, НЕКОТОРЫЕ сведения о тайлах в области вокруг игрока.

Таким образом, все, что посылает Сервер, не будет полной информацией о плитке. Ex. Предметы, лежащие на земле, тип земли, деревья и т. Д., Не будут важны в зоне, недоступной игроку, а будут только тем, о чем клиент / игрок должен знать в этих тайлах. (Например, «входящие имена» Ultima Online, где игроки могли знать, что Персонаж [игрок или монстр] находился за пределами плиток в их визуализированном виде.)

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

Отправляемая информация будет иметь площадь листов размером 10x15, и каждый элемент содержит информацию о том, что находится на элементе. Более эффективно, все было бы Объектом, где плитка содержит все Объекты на плитке. Ex. Плитка [4] [4] содержит Меч # 23452, Рок2, Дерево5, Игрок3, Монстр4.

Пустые тайлы будут отправлять не что иное, как тип местности [Трава, Песок, Вода], если они еще не были загружены во время инициализации / загрузки. Некоторые плитки могут содержать несколько объектов [Tree2, Sword # 924, Gold, Corpse, Rock3].

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

В самом сумасшедшем случае Сервер должен будет отправить 150 плиток с информацией только о нескольких объектах OnLOAD, и с тех пор обновление только заменяет плитки (если они есть) и любые новые плитки (от 10 до 15 каждый раз, когда игрок движется в каком-либо направлении). ) и направление движения персонажей на экране (чтобы клиент мог имитировать плавное перемещение между плитками).

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

Если между клиентом и сервером отправляется очень мало информации, имеет ли смысл просто загружать весь мир при инициализации? Или «Карта», если Мир слишком велик. А потом после ЗАГРУЗКИ отправлять только плитки которые обновляются?

Я все еще размышляю над тем, как конкретно следует обращаться с данными. Книга, которую я использую в качестве ссылки, хочет, чтобы у меня был связанный список, в который я добавляю и удаляю объекты, так что все будет в порядке вещей. "Есть ли персонаж? Есть ли дерево?"

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


источник
Я предлагаю вам взглянуть на freemmorpgmaker.com, этот движок мне очень помог, когда я только начинал. Сценарий относительно прост и с ним очень весело работать. Код научил меня всему, что мне нужно было знать, чтобы создать собственный 2D-движок / игру. То, что вы не должны учиться у них, это как защитить свой сервер / клиент.
Ник

Ответы:

6

Ты на правильном пути.

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

Если между клиентом и сервером отправляется очень мало информации, имеет ли смысл просто загружать весь мир при инициализации? Или «Карта», если Мир слишком велик. А потом после ЗАГРУЗКИ отправлять только плитки которые обновляются?

Это именно то, что вы должны сделать. Отправляйте только те данные, которые вам нужно отправить.

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

Если вы просто отправляете двумерный массив IDS листов, размер данных может быть очень низким, особенно если у вас менее 256 различных типов листов. В этом случае вы можете использовать один байт (или неподписанный символ). Так что, если вы посылаете 100x100 плиток игроку, и каждая плитка состоит только из одного байта ... Вы понимаете. Это не много данных.

Сообщество Minecraft проделало замечательную работу по документированию своего протокола: http://mc.kev009.com/Protocol

http://www.minecraftwiki.net/wiki/Classic_server_protocol

Ник Каплингер
источник
1
вау, большое спасибо! Это большое повышение уверенности в том, что мне сказали, что я на правильном пути, когда я так мало знаю. Это говорит мне о том, что я правильно понимаю вещи и проектирую в меру своих возможностей. Я уверен, что если я продолжу учиться, я буду делать это достаточно адекватно. Так приятно слышать позитивные советы, и нет: «Вы делаете это неправильно!» LOL :)
У меня ушло много времени, прежде чем я набрался смелости, чтобы взять многопользовательские и 3D-игры. :)
Ник Каплингер
Кроме того, положительный совет - то, на чем процветает это сообщество Я призываю всех внести свой вклад любым возможным способом!
Ник Каплингер
3

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

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

Размер предварительно загруженной области зависит от того, насколько быстро ваши игроки могут двигаться, и как долго будет их средняя задержка.

Philipp
источник
-1

Объем данных, которые вы отправляете с Сервера на Клиента, может быть НЕВЕРОЯТНО незначительным. Если это все, что вам нужно отправить, я бы настоятельно рекомендовал загрузить столько, сколько вы можете загрузить, так что это даже меньше данных требуется. Количество, отправляемое при загрузке, будет достаточно маленьким, чтобы оправдать время загрузки, использование памяти будет практически отсутствовать, если ваш мир не будет смехотворно негабаритным, и вам вообще не потребуется обновлять данные.

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

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


источник