Статья опубликована в рамках: XXX Международной научно-практической конференции «Научное сообщество студентов XXI столетия. ТЕХНИЧЕСКИЕ НАУКИ» (Россия, г. Новосибирск, 31 марта 2015 г.)
Наука: Информационные технологии
Скачать книгу(-и): Сборник статей конференции
- Условия публикаций
- Все статьи конференции
дипломов
МУЛЬТИПЛЕЕР В ИГРАХ C АРХИТЕКТУРОЙ КЛИЕНТ-СЕРВЕР
Караваев Вадим Юрьевич
студент 4 курса кафедры «Автоматизированных систем управления» Московского государственного университета приборостроения и информатики, филиал, РФ, г. Ставрополь
E -mail: 5665tm@gmail.com
Авакян Тамара Ашотовна
научный руководитель, доцент кафедры «Автоматизированных систем управления» Московского государственного университета приборостроения и информатики, филиал, РФ, г. Ставрополь
Существует два основных вида организации мультиплеера в играх — peer-to-peer, и клиент-сервер.
При подходе peer-to-peer каждый игрок является одновременно клиентом и сервером. Среди преимуществ — разработчику игры не нужно выделять средства на содержание сервера. Недостаток заключается в том, что недобросовестные игроки вместе с модулем сервера в своей игре получают огромные возможности по обману других игроков. Простейшей подменой сетевых пакетов можно добиться эффекта бессмертия у своего игрового персонажа, возможности наносить бесконечный урон и прочих вещей, которые идут в разрез с изначальной концепцией игры. В основном подход peer-to-peer применяется в играх, предназначенных для взаимодействия по локальной сети.
Более совершенным и сложным является подход клиент-сервер. При таком способе организации мультиплеера клиенты не общаются друг с другом напрямую, а передают пакеты серверу, который проверяет сообщения клиентов на подлинность. Степень проверки клиентов может быть разной и варьироваться от простейших одиночных проверок, до полной симуляции игрового мира. Чем глубже степень проверок, тем больше ресурсов требуется для сервера, и тем меньше у клиента возможностей для обмана. Например, если в игре автомобиль не может развивать скорость свыше 300 км/ч, и вдруг от одного из клиента приходит сообщение, в котором автомобиль развил скорость 450 км/ч, то сервер может посчитать такого клиента нарушителем и предпринять соответствующие действия. Действия могут быть разными, от игнорирования пакета до полного запрета игроку возможности участвовать в сетевых сражениях. Основное правило при разработке — игрок является врагом разработчиков, который обладает обширными знаниями, владеет всеми исходниками клиентской части, и всеми силами пытается нарушить игровой процесс.
В нашем проекте используется архитектура клиент-сервер, с проверками только самых критичных параметров игрового процесса, таких как координаты игрока, его скорость, количество здоровья, наносимый урон и т. д. В качестве рабочей машины для сервера используется инстанс, расположенный на Amazon Web Services. При выборе местоположения нужно руководствоваться простейшим правилом — машина сервера должна находиться как можно ближе к игрокам, для обеспечения наименьшего пинга (время отклика). Amazon Web Services дает возможность разместить машину в Азии, Америке или Европе. Так как основную нашу аудиторию будет составлять русскоязычный сегмент, нами был выбран город Франкфурт, как наиболее близко расположенный к территории РФ из предложенных вариантов.
Для написания серверной части в проекте использовалась связка C# + Net. Framework 4.5. Этот вариант немного проигрывает C++ в плане производительности, однако имеет большие преимущества в плане скорости написания кода, и простоты поддержки. К тому же средства асинхронного программирования введенные в новой версии Net. Framework предоставляют огромные возможности для написания многопоточного кода [3, c. 56]. Для сетевого общения используется два протокола. UDP протокол используется для сообщений критичных к скорости передачи, например координаты игрока в реальном времени. TCP протокол используется для сообщений в которых важен факт их доставки: регистрация игрока, покупки внутри игры и т. д. В качестве базы данных используется PostgreSQL. Преимущества этого решения — свободное распространение, достаточно высокая производительность и неплохая функциональность.
Одна из самых сложных проблем, с которыми сталкивается программист, занимающийся клиент-серверным взаимодействием — пинг. Дело в том, что пакеты от клиента к серверу и обратно доходят не мгновенно, а с некоторой задержкой. Например, в среднем сообщение между клиентом и сервером доходит за 100 мс. Игрок А решил произвести выстрел в игрока Б. От игрока А сообщение сначала идет на сервер. Время 100 мс. Затем на сервере проводится проверка сообщения, и клиенту Б посылается сообщение о выстреле, что займет еще 100 мс. В итоге получается 200 мс времени. Если игровой персонаж является человеком, бегущим со скоростью 10,8 км/ч, то за это время он успеет сместиться на 60 см. Не очень критично, однако если игрок А целился в голову, то возникнет противоречивая ситуация. На стороне игрока А, игрок Б получил попадание в голову и должен погибнуть. Однако на стороне игрока Б, он уже сместился на расстояние достаточное для того что бы остаться в живых. Еще хуже ситуация становится если вместо людей используются быстродвижущиеся объекты, такие как танки или, что еще хуже, самолеты. Самолет, движущийся со скоростью 720 км/ч, за, казалось бы, небольшие 200 мс изменит свои координаты на 40 метров. Для решения проблем с задержкой пакетов существует множество уловок и трюков, применяемых разработчиками. Однако первое и самое главное правило — прав не клиент А, и не клиент Б, прав сервер. То состояние игрового мира, которое осуществлено на сервере, справедливо для всех клиентов, независимо от того что игроки видят на экране. Второе правило — игрок А не знает что находится на экране у игрока Б, и наоборот, и этим можно пользоваться. В нашем случае можно пренебречь координатами игроков для устранения противоречия «попал-не попал» (Рисунок 1).
Рисунок 1. Игровой процесс на стороне А и Б
Игрок А видит свой вариант игрового мира, игрок Б свой. Однако и в том, и в том мире игрок А стреляет и попадает в игрока Б, следовательно противоречия не возникает.
Во многих онлайн играх связанных со стрельбой, не используются трассеры (следы от пуль). Таким образом, снижаются требования к точности игрового мира на клиенте, т.к. если выстрел происходит с расстояния в 100 метров, то 60 см погрешности клиент может и не заметить.
В любой онлайн игре присутствует интерполяция и экстраполяция игрового процесса. В основном используются линейные алгоритмы [1].
Интерполяция используется для того, чтобы сгладить движения различных объектов. В большинстве игр сообщения от клиента к серверу поступают примерно 20 раз в секунду [2]. Однако сообщения могут прийти не вовремя, может перепутаться их порядок, некоторые сообщения могут и вовсе потеряться. Да и 20 сообщений в секунду недостаточно для того что бы обеспечить естественную для человеческого глаза плавность. Поэтому на клиенте искусственно вводится небольшая задержка (40—60 мс) игрового процесса, и каждый фрейм рассчитывается состояние игрового мира на основе его состояния в предыдущем фрейме, и возможном состоянии в следующем фрейме.
Экстраполяция используется для того что бы предугадать движения объектов. Это может использоваться для различных целей, таких как компенсация задержки или адекватный игровой процесс на стороне А, в случае перебоев связи на клиенте Б. Например если игрок Б двигался вперед, и внезапно у него возник кратковременный перебой связи, то клиент А может продолжать симулировать движение игрока Б вперед, до тех пор пока на клиенте Б не восстановится связь (Рисунок 2).
Рисунок 2. Экстраполяция в действии
Другая проблема, с которой сталкивается разработчик — сетевой трафик и методы общения клиента с сервером. Привычные методы вроде XML и JSON совершенно неприменимы, из-за излишнего объема трафика и возможности клиента расшифровать такой трафик. Обычно в программном коде закладывается строго заданное количество типов сообщений между клиентом и сервером. Для каждого типа сообщения определяется его формат, содержание и т. д. Но начинается каждое сообщение с номера, к которому относится этот тип. В итоге все сообщения имеют вид — номер сообщения + информационная часть. Допустим, в игре имеется 256 типов сообщений между клиентом и сервером. Сообщение «клиент изменил координаты» имеет номер 42 и имеет следующий вид информационной части — номер клиента + координата X + координата Y + координата Z. Тогда все сообщение будет иметь вид «42 + номер клиента + координата X + координата Y + координата Z». Когда сообщение поступает от клиента к серверу, сервер первым делом считывает номер сообщения. После считывания номера, сервер на его основе выбирает подходящий для этого вида сообщения алгоритм чтения информационной части. Аналогичные действия происходят и на клиенте при получении сообщений от сервера.
Список литературы:
1.Руководство Unity // Официальный сайт Unity Engine [Электронный ресурс] — Режим доступа. — URL: http://docs.unity3d.com/ru/current/Manual/UnityManualRestructured.html (дата обращения 03.03.2015).
2.Сетевое программирование в Source // Valve Developer Community [Электронный ресурс] — Режим доступа. — URL: http:// developer.valvesoftware.com/wiki/Source_Multiplayer_Networking:ru (дата обращения 03.03.2015).
3.Хейлсберг Д. Язык программирования C#. Классика Computers Science. 4-е изд. СПб.: Питер, 2011. — 784 с.: ил.
дипломов
Оставить комментарий