Как написать сетевую игру? [закрыто]

73

Основываясь на том, почему так сложно разработать MMO? :

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

Я знаю теорию о сокетах, серверах, клиентах, протоколах, соединениях и подобных вещах.

Теперь интересно, как можно научиться писать сетевые игры:

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

Есть ли хорошие книги, учебники, сайты, интересные статьи или другие вопросы по этому поводу?

Я ищу широкие ответы, но конкретные тоже хороши, чтобы узнать разницу.

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

Ответы:

61

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

Как сохранить синхронизацию?

Мы создали фреймворк « Marauroa », основанный на концепции действий и восприятий: действия отправляются от клиента на сервер, на котором есть пользовательский ввод, такой как (идти налево, атаковать монстров # 47, сказать «привет»). И восприятия отправляются с сервера клиентам, рассказывая им о состоянии окружающего мира. Эти представления отправляются каждый ход. В зависимости от игры мы используем время поворота от 30 до 300 мс.

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

Как обойти проблемы с задержкой?

Мы твердо верим в то, что «сервер всегда прав». Клиент делает некоторые прогнозы, такие как плавная ходьба, проверка столкновений и так далее. Но если клиент и сервер о чем-то не соглашаются, сервер побеждает. Подпроект Stendhal (2D RPG) использует время поворота 300 мс по умолчанию (с большой степенью сглаживания, выполненной на стороне клиента). Это делает Stendhal очень устойчивым к задержкам.

Примечание. Некоторые другие игры доверяют клиенту в некоторой степени, чтобы минимизировать влияние задержки в сети. В WoW его часто эксплуатировали на одном из полей битвы под названием «Ущелье Песни Войны». Есть два способа, которыми может выбрать игрок с флагом: в середине через туннель и один в правом глазу, поднимающийся в гору. Таким образом, игрок-обманщик бежит к туннелю, а затем вызывает отставание для себя. Сервер и другие клиенты будут продолжать видеть его бегущим к нему. Но через некоторое время этот клиент может сказать серверу, что он пошел в гору. WoW проверит, что расстояние между последними переданными координатами и текущими соответствует интервалу времени, и примет это.

Использование UDP против TCP

В ранних версиях мы использовали UDP для уменьшения накладных расходов TCP. Мы обрабатывали потерянные пакеты самостоятельно. Это отлично работало в первые дни проекта. Но когда несколько лет назад сервер был перенесен из какого-либо домашнего DSL-соединения в реальный центр обработки данных, у нас возникли огромные проблемы. Протокол UDP (или, по крайней мере, 5 лет назад) чрезвычайно требователен к мощности процессора аппаратного обеспечения брандмауэра: набор правил должен применяться к каждому пакету UDP. Однако для TCP набор правил применяется только для первых 3 пакетов. После этого соединение установлено. Все последующие пакеты будут обходить нормальный набор правил, потому что они находятся в соединительной таблице отслеживания или потому что у них нет флага SYN.

Как защитить коммуникацию и клиента от обратного инжиниринга?

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

Защитить связь от несанкционированного прослушивания третьими лицами с помощью SSL легко.

Однако невозможно защитить его от обратного инжиниринга. Конечно, вы можете запутать его и использовать анти-отладочные приемы. Но, в конце концов, вы не можете предотвратить реверс-инжиниринг программного обеспечения, которое вы отдаете пользователям. Существует очень интересная презентация о том, как Skype был изменен, несмотря на то, что разработчики приложили немало усилий для борьбы с методами отладки: http://recon.cx/en/f/vskype-part1.pdf

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

Какие вещи должны быть вычислены локально, а какие на сервере?

Мы вычисляем все, что связано с игровой логикой на сервере. Клиент будет предсказывать определенные события, чтобы игра проходила гладко. Но в итоге сервер всегда прав.

Прогнозируемые события - это, например, остановка движения при столкновении. Стендаль использует сетку для позиционирования элементов. И с точки зрения сервера, верхний левый угол каждого объекта находится ровно на одном квадрате. Но клиент будет плавно перемещать их между плитками. Это также нарисует псевдо 3D-эффект. Таким образом, сущность, которая имеет базу 1x1, может быть выше в клиенте.

Как сбалансировать проблемы с нагрузкой?

Постарайтесь сделать это как можно более простым, чтобы облегчить обслуживание.

Балансировка нагрузки статического контента хорошо известна в области кластеров http-серверов и сетей распространения контента.

Довольно простая концепция балансировки нагрузки игровых сервисов заключается в разделении серверов по регионам / зонам. Таким образом, зона AC находится на одном сервере, а зоны DF - на другом. Это особенно легко, если вы не можете смотреть из зон в одном наборе на зоны в другом наборе. Вам нужно поставить некоторые проверки, чтобы клиент мог подключиться только к серверу зоны, ответственному за зону, в которой находится игрок.

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

Некоторые дополнительные глобальные сервисы необходимы через: При входе в систему клиентам необходимо указать подключение к правильному серверу зоны. И вы могли бы хотеть всемирную систему чата.

Я подробно остановился на этой теме, как достигается балансировка нагрузки в ММО?

оборота Хендрик Бруммерманн
источник
1
Вы упомянули, что UDP требует немного больше ресурсов ЦП, но вы не упомянули, что TCP требует как минимум трех поездок между клиентом и сервером до обработки пакета, И пакеты буферизуются до тех пор, пока все предыдущие пакеты не будут получены, то есть вы можете столкнуться с нелепостью. количество задержек в ожидании пакетов, которые уже не актуальны. Кажется, важно упомянуть.
BlueRaja - Дэнни Пфлугхофт
2
@Danny, для инициирования нового TCP-соединения требуется три пакета: клиент-сервер: SYN, сервер-клиент: SYN ACK, клиент-сервер: ACK + данные. Это на одну поездку больше, чем UDP, но это происходит только в самом начале, когда клиент впервые обращается к серверу. В установленном соединении каждый пакет обрабатывается немедленно, без каких-либо дополнительных циклов. Будет ответ ACK, но полученные данные уже обработаны, пока пакеты ACK отправляются обратно.
Хендрик Браммерманн
1
@Danny, TCP обрабатывает потерю пакетов автоматически и довольно эффективно. Трудно переопределить, что вы сами используете UDP; если ваш протокол не подходит для случайных недоставленных пакетов. Следующая проблема заключается в том, что TCP гарантирует, что порядок пакетов, в то время как пакеты UDP могут быть получены в неправильном порядке. Опять же, это трудно переопределить самостоятельно, если только вы не можете просто игнорировать более старые пакеты, например, на основе счетчика пакетов. Если для TCP требуется очень короткое время отклика, алгоритм Nagle должен быть отключен.
Хендрик Браммерманн
Похоже, вы яростно защищали свою позицию, не решая очень реальной проблемы с задержкой TCP. Возможно, настоящая проблема заключается в том, что вы
выбрали
27

http://gafferongames.com/networking-for-game-programmers/

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

jsimmons
источник
1
+1, но, пожалуйста, не доверяйте им слепо. Например, по моему опыту, использование UDP и переизобретение функции TCP не очень хорошая идея. UPD полезен, только если потерянные пакеты не оказывают никакого влияния вообще, то есть каждый пакет UDP содержит полное соответствующее состояние мира. WoW использует TCP, SL находится в процессе перехода от UDP к TCP (даже HTTP для статического контента) и значительно улучшил производительность благодаря этим изменениям.
Хендрик Браммерманн
7
Вы не заново изобретаете функции TCP, хотя бы не все из них. Семантика управления потоком TCP и потери пакетов ужасна для игры, в которой требуется соединение с низкой задержкой. TCP полезен только в том случае, если вы не заботитесь о задержке или минимизации необходимой пропускной способности.
jsimmons
2
Second Life значительно улучшил производительность, перейдя от UDP к HTTP по TCP: blogs.secondlife.com/community/technology/blog/2010/08/13/…
Хендрик Бруммерманн,
5
Ну, на самом деле, они улучшили производительность потоковой передачи своих активов, изменив принцип работы. Использование HTTP / TCP в этом случае облегчило их реализацию, а не ускорило. Я мог бы также отметить, что zeromq - интересный проект, и он может очень хорошо масштабироваться для игровых сетей. zeromq.org
jsimmons
8

В зависимости от типа игры, которую вы пишете, вы можете избежать некоторых низкоуровневых сетевых программ. Некоторые типы игр не требуют много обратной связи между клиентами и сервером. В таких случаях можно использовать систему более высокого уровня. Например, я разрабатываю пошаговую стратегическую игру в C # / .NET. Пошаговые стратегии игры несколько уникальны тем, что подавляющее большинство взаимодействия клиент / сервер происходит в начале и в конце хода, с относительно небольшим промежутком между ними. Таким образом, я решил использовать Windows Communication Foundation (WCF), коммуникационную среду высокого уровня, предназначенную в основном для веб-сервисов. Вместо того, чтобы работать непосредственно с сокетами и всем этим низкоуровневым сетевым мусором, я могу делать то, что кажется стандартными вызовами методов, и позвольте WCF разобраться с протоколом и транспортными уровнями для меня. Единственный раз, когда мне приходилось иметь дело с низкоуровневой сетью, было, когда я настраивал свои конечные точки, что в основном является разовой сделкой в ​​файле конфигурации. Возможно, все еще потребуется реализовать некоторую настраиваемую логику сериализации, но вам придется делать подобные вещи независимо.

Майк Штробель
источник
8

Вопрос слишком широкий. Ответы могут заполнить сайт самостоятельно. Но есть книги, которые касаются этого, прежде всего эти два:

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

(Обратите внимание, что я больше говорю о ММО в первоначальном вопросе - «сетевая игра» может означать все виды вещей, от текстовой игры на основе PHP до ММО, а подвопросы выше не все применяется к каждому типу.)

оборота Килотан
источник
7

Как сбалансировать проблемы с нагрузкой?

фиксированный географический размер + несколько экземпляров - самое простое решение. Ребята, работающие над SWG, попробовали динамический размер и пожалели об этом.

Как управлять состоянием игры?

Сервер является авторитетным.

Как сохранить синхронизацию?

Периодическая синхронизация обновлений с сервера. (не совсем уверен, что беспокойство здесь)

Как защитить коммуникацию и клиента от обратного инжиниринга?

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

Как обойти проблемы с задержкой?

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

Какие вещи должны быть вычислены локально, а какие на сервере?

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

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

Aaron Brady
источник
4

Этот вопрос очень широк. Это также очень сложная область для освоения, сетевые программисты довольно востребованы в отрасли с соответствующей оплатой, что в некотором роде указывает на то, что это «нерешенная» область. Есть ли там книги, да, много. Есть ли хорошие книги там, без сомнения. Есть ли там книги, которые ответят на ваши вопросы? ... Я так не думаю. У них могут быть решения, которые работают в некоторых ситуациях, или указатели на то, что нужно искать, но почти все ваши вопросы зависят от игры ... это область, в которой вам действительно придется много работать самостоятельно, это так, казалось бы, тривиально, и это может пойти не так во многих (неконтролируемых) способами.

Кая
источник