Логика игры на сервере! Хорошо или плохо?

25

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

Доминик Бартл
источник

Ответы:

37

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

Точно так же вам не обязательно отправлять обратно все, что нужно клиенту. Например, вы можете отправить какое-то сообщение с надписью «NPC X умер», и клиент определяет, какую анимацию / звуки воспроизводить. Вроде того.

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

Есть много более конкретных вопросов по этой теме по всему сайту. Например:

Должно ли обнаружение столкновений выполняться на стороне сервера или совместно между клиентом и сервером?

Кто делает вычисления AI в MMO?

Должен ли хозяин игры быть авторитетом или другим тупым клиентом?

тетрада
источник
4
+1 Ударь меня к этому. Кроме того, в зависимости от стиля игры, вы можете / должны сделать некоторые предсказания на стороне клиента.
Джон Макдональд
14

Ну, у вас есть ответы, но ваш реальный ответ - "попробуй сам". Вещи отличаются от игры к игре.

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

Моя рекомендация:

Шаг 1
Просто начните с полностью авторизованного серверного дизайна. Как вы сказали, просто отправьте пользовательские входные данные на сервер, и пусть сервер сделает все, и клиенты получат результаты. Ваша игра будет работать полностью согласованно. Но когда вы смотрите на своих клиентов, вы заметите некоторые лаги, некоторые проблемы с телепортом, а не плавное движение ... и т.д.

Шаг 2
Начните исправлять проблемы на стороне клиента. Проблемы телепортации например. Ваш персонаж был в (0,0), и сервер сказал, что теперь вы в (100,100). Ваш персонаж просто телепортируется в (100,100), что нехорошо. Наступает интерполяция. У вас должен быть код на стороне клиента, который плавно передвигает символ от (0,0) до (100, 100). Да, вы переместите своего персонажа с (0,0) на (100,100), но как быстро? Пока вы можете просто использовать разницу во времени между обновлениями каждого сервера. Если ваш сервер отправляет 10 пакетов в секунду, то есть задержка 100 мс между каждым пакетом.

Шаг 3
Теперь ваша игра уже хороша для быстрых сетей, в которых задержка составляет (1-50) мс. Но это обречено, если есть потеря пакета, большая задержка или расчет занимает много времени на сервере ... и т. Д. В этих ситуациях вы заметите, когда вы нажмете стрелку влево, вы увидите, что ваш персонаж движется влево с задержкой 200 мс. Задержка между вашим пакетом поступает на сервер, время расчета и возвращается к вам с вашей последней позицией. Это плохо, худший недостаток авторизованного дизайна сервера. Игрок хочет, чтобы его персонаж двигался влево, как только он нажимает налево, вы не можете заставить его ждать. К счастью, клиент также имеет тот же код, что и сервер, так почему бы не выполнить его на клиенте немедленно и не исправить окончательный результат с ответом от сервера? Вот что такое в основном входной прогноз. Клиент нажимает влево, код в его стороне переместит его влево, через некоторое время, скажем, 200 мс, реальная позиция поступает с сервера, и клиент корректирует свою позицию с ее помощью. Если все прошло хорошо, клиент ничего не заметит, «шаг 2» также поможет нам в этом.

Ну, в сети есть много уроков и вещей на эту тему. Но есть 2, которые мне действительно нравятся:

Действительно хорошо, покрывает темные пятна: многопользовательская сеть
от Valve-Source Engine История, интересная для чтения и стоящая того: 1500 лучников на 28.8 ,

тесла
источник
3

Плюсы:

  • этот подход является более (наиболее) доказательством пиратства
  • вы можете применять обновления проще
  • централизованное сообщество

Минусы:

  • огромные требования к пропускной способности
  • некоторые пользователи могут ненавидеть такой подход (конфиденциальность и прочее)
  • проблемы с локальным геймплеем (LAN вечеринки), одиночная игра
neciu
источник
Проблем с игровым процессом в локальной сети можно избежать, предоставив выделенный двоичный файл сервера или разрешая одному из клиентов выступать в качестве сервера. Решение, которое устраняет проблемы как для одного игрока, так и для локальной сети, состояло бы в том, чтобы прозрачно разместить сервер на клиентском компьютере (если это всего лишь игра для одного игрока, между этим подходом и традиционным двоичным кодом не должно быть существенной разницы в вычислительной мощности). Это может не работать для всех типов игр
3Doubloons
2

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

ddyer
источник
Забавно, когда я задавал подобные вопросы здесь в 2016 году, все просто говорили мне: «Никогда не доверяй клиенту».
newguy
Это зависит от игры, но клиенты обманывают самих себя, это не серьезная проблема, а клиенты обманывают других, честных клиентов; все, что сервер мог сделать, чтобы не доверять клиенту, честные клиенты могут сделать вместо этого.
ddyer
2

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

Если вы хотите сделать шутер, вы можете использовать как входные, так и абстрактные функции. Если вы возьмете Unreal Tournament 3 в качестве кейса, они создали многопользовательский режим, в основном, через реплицированные вызовы функций.
Для движения они принимают входные данные игрока (сжатые в один бит для каждого действия), вращение дельты, ускорение и метку времени и отправляют их на сервер.
Для других целей, таких как оружие, они синхронизируются, когда вы стреляете (AFAIK, еще не изучал эту часть подробно).
Для более статичных / менее часто изменяемых значений, таких как здоровье, они отправляют переменную клиенту или серверу в зависимости от того, что указал программист.

И для игр не-RTS, помните предсказание клиента.

Питер Олстед
источник