В дополнение к статье, на которую есть ссылки в других ответах, я могу немного рассказать об опыте проекта 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 в базу данных, прямая связь между серверами для передачи обслуживания может быть реализована позже).
Некоторые дополнительные глобальные сервисы необходимы через: При входе в систему клиентам необходимо указать подключение к правильному серверу зоны. И вы могли бы хотеть всемирную систему чата.
Я подробно остановился на этой теме, как достигается балансировка нагрузки в ММО?