Я пытаюсь создать онлайн-сервер игры для своей танковой игры 2D (Unity). В моей игре 2-4 игрока будут контролировать свои танки и сражаться друг с другом.
Я пытался использовать Unity networking, это было не очень подходящим для моей игры, потому что мы должны выбрать одного из игроков в комнате, чтобы стать «сервером», который не очень гибкий для моего будущего (например, когда «сервер» завершает работу, мне приходится много работать, чтобы оставаться связью между другими игроками).
Затем я попытался создать собственный сервер с Nodejs là socket.io для связи между сервером и клиентом. Это очень просто: получает данные от одного и транслирует их другим. Кажется, что он работает нормально, пока не появится физическая часть: сервер должен доверять клиентам, когда они говорят, что что-то попало или взорвалось, а затем передало его другим клиентам. Не говоря уже об обманутых клиентах, с латентностью сети, физическое моделирование клиентов будет отличаться. Например, танк может быть поражен этим клиентом, но он должен быть закрыт за стеной на другом и остаться в живых, но бак позади него ловит пулю и взрывается из-за латентности. В этих случаях сервер не знает, какой из них прослушать.
- Как @Catwood, упомянутая ниже, Photon PUN — еще один вариант для меня. я ранее следовал одному из своих учебников. Photon не нуждается в том, чтобы игрок был «сервером», например, Unity networking. Но как мне реализовать свою логику игры на сервере? (для авторитетного сервера)
- По-видимому, Smartfoxserver — еще один хороший (и дорогой) вариант. Я не стал глубже смотреть на их документ API. Я не знаю, могу ли я реализовать свою логику игр и правила на этом (их учебник пропустит эту часть для простоты).
В заключение мне нужно предложение для моего игрового сервера:
- Является авторитетным сервером
- Может обрабатывать правила игры и решать, что произойдет (возможно, должен иметь свой собственный физический движок).
- Хорошо работает с Unity2D
- Предпочтительны Javascript, С#, Java!
Я иду в правильном направлении, потому что кажется, что некоторые сервисы игрового сервера (такие как Photon, Unity networking) просто не заботятся о том, как реализовать логику игры на сервере. И делает ли он их не авторитетным сервером?
Я очень новичок в этой области, все будет оценено!
Я бы посоветовал создать собственный сервер для вашей игры, как в NodeJS. Большинство решений, которые я знаю, довольно сложно использовать и не могут делать все, что вы хотите.
Например, игра Blizzard Hearthstone основана на Unity для клиента и имеет пользовательскую серверную сторону.
Вот несколько советов о том, как создать игровой сервер.
Кажется, что все нормально, пока не появится физическая часть: сервер должен доверять клиентам, когда они говорят, что что-то попало или взорвалось, а затем передало его другим клиентам.
При создании сервера вы должны принимать все важные решения на стороне сервера, а не на стороне клиента. Это сервер, который начинает вечеринку, поэтому сервер должен иметь следующую информацию
- Размер карты
- Количество игроков
- Данные о каждом игроке (точка здоровья, положение, размер, скорость атаки. )
- Любая другая информация, необходимая для принятия решений.
Теперь клиент должен всегда отправлять очень маленький сигнал на сервер, как показано ниже.
- Переместить влево
- Присоединиться к группе
- Shoot
- Повернуть вправо
- и т.д.
На основе пользовательских действий и пользовательских данных сервер может запускать «симуляцию» игры.
- Проверьте, разрешено ли действие.
- Если это разрешено, имитируйте действие. Если это не так, поместите его в очередь
- Отправьте пользователям информацию о том, что происходит (игрок один попал, игрок два умирает, игрок четыре хода слева и т.д.)
При этом сервер знает, когда что-то происходит, и решите, что произойдет. Вы не полагаетесь на информацию о стороне клиента, вы получаете только желаемые действия игрока.
Однако, как вы сказали, из-за латентности и других сетевых факторов ваш клиент не может быть слишком зависим от сервера. В современных играх клиент имеет те же данные о игроке, что и сервер, и не всегда полагается на сервер для отображения на экране того, что происходит.
Если вы играли в некоторые онлайн-игры, возможно, вы заметили, что когда соединение с сервером потеряно, есть небольшое количество времени, в течение которого вы можете продолжать играть (перемещаться, снимать и т.д.), но ничего не движется, кроме вы. Это связано с тем, что клиент продолжает «запускать» игру на основе вашего действия, даже без информации о сервере.
Однако, чтобы избежать огромной разницы между тем, что отображается клиентом игроку, и тем, что происходит в симуляции сервера, клиент и сервер «синхронизируются» с регулярным интервалом.
Например, если вы решите двигаться влево, клиент знает скорость вашего движения, чтобы он мог отображать движение, не полагаясь на сервер.
Когда происходит синхронизация, сервер отправляет клиенту критическую информацию, а клиент меняет любую отображаемую в данный момент информацию с тем, что отправляет сервер.
В примере с левым движением, если скорость вашего движения отличается на сервере и на клиенте, когда клиент получает заказ на синхронизацию, вы заметите, что ваш плеер будет «телепортирован» из отображаемой позиции в другую. Это также может произойти, если какой-либо пакет потерян или из-за высокой задержки.
Обработка lantency — огромная проблема при создании онлайн-игры как на стороне сервера, так и на стороне клиента, и это не тема этого вопроса.
Подводя итог, ваш сервер должен
- быть самодельным
- Только получать действия от клиентов
- Имитировать игру
- Отправить клиентам информацию о том, что происходит.
- Синхронизация с регулярным интервалом с клиентами
Вот несколько объяснений того, как добавить логику внутри вашего сервера. Небольшой отказ от ответственности до этого, я никогда не использовал NodeJS, поэтому я не знаю, возможно ли это с помощью NodeJS, я обычно использую С++.
Теперь для вашей игры я предполагаю, что игрок может использовать только действие MOVE.
Когда пользователь подключается к вашему серверу, вы можете запустить игру. Поскольку ваш пользователь может перемещаться, это означает, что есть 2D-карта, которая у вашего пользователя имеет размер и начальную позицию и скорость. Таким образом, ваш сервер должен запустить новый «GameParty» и инициализировать вышеуказанные данные. Например, допустим, что установлено значение по умолчанию.
Когда клиент хочет MOVE, он отправляет пакет на сервер, говоря, что хочет двигаться. Вы можете использовать любой протокол, который вы хотите для связи с клиентом и сервером, я использую двоичный протонал, но позвольте сказать, что вы используете Json
При этом ваш сервер будет знать, что пользователь хочет перейти влево. Таким образом, вам нужно уменьшить user_posx на значение user_speed , чтобы иметь серверную сторону, вашу новую позицию. Если эта позиция находится на краю карты, у вас есть два варианта: пользователь может появиться на другом краю карты, чтобы запретить действие.
С регулярным интервалом времени ваш сервер отправит клиенту текущую позицию игрока.