Comments 16
Спасибо за статью! Интересно почитать как люди решают те же самые проблемы, что и ты сам.
А как у вас сделан игровой сервер? Это специальный юнити headless билд или вообще отдельное приложение?
И второй вопрос про игровую симуляцию. Я так понимаю у вас трёхмерный мир и персонажи перемещаются свободно. Перемещение, collision detection и collision response у вас сделан средствами юнити и его PhysX? Или какая-то своя логика или свой физический движок?
Игровой сервер — NET приложение на фреймворке Photon, Unity в сервере не участвует.
В симуляции используем отдельную 2D физику (VolatilePhysics) и периодически туда контрибьютим, т.к. в ней есть конкретные баги. Нам повезло, что мы смогли упростить взаимодействия до столкновений неупругих примитивов + рейкастов (сферические и обычные) для расчета видимости и попаданий.
>> Determinism (Volatile uses floating-point values, and is not deterministic across hardware configurations)

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

Или я неправильно понял и в вашем случае клиент работает исключительно в роли «телевизора», получая постоянные обновления всего мира с сервера? Хотя вы пишите, что есть возможность локальной симуляции без использования сервера.
Да, клиент — «телевизор», верит только серверу. Лишь изредка экстраполирует по примитивным правилам для поддержания плавности при высокой потере пакетов. Симуляция на клиенте нужна только для отладки и работы оффлайн. Например: стартовое обучение бою. Поддерживать подключение к серверу расточительно и излишне влияет на воронку прохождения — мы запускаем симуляцию с ботами локально на девайсе.
Спасибо за статью. Но делать субмодули из-за прото файлов, как то очень сомнительно.
Было бы лучше использовать UPD+TCP. UDP для стрельбы, передвижения и т. д. TCP для этих ракет и вообще для того что точно должно дойти. Вроде бы для этого и TCP и создан.

Не могу согласиться)
В риалтайм играх самое важное — максимально быстрая доставка пакетов. UDP + перепосылка пакетов обеспечивает максимально быструю доставку пакетов(даже теоретически не получится быстрее).
За более развернутым ответом прошу на https://gafferongames.com/post/udp_vs_tcp/
:)

С мобильным пингом вы бы не заметили разницы TCP+UDP vs UDP. По мне с кейс с ракетой этого не стоит. Но в других случаях это приемлимое решение.
Это смотря как делать. И если делать правильно, то реально разница есть. Вообще миксовать TCP и UDP то еще занятие.
Странно я думал работа с лобби, отправка ивентов об inAppPurchases и т д. Вы отправляете по TCP.
Не так быстро, друг. Не надо валить все в одну кучу. Я имел ввиду, что для модуля непосредственно битв миксовать TCP и UDP не есть хорошо. Но на уровне всей архитектуры бэкенда бессмысленно привязываться к единому протоколу.
Технически, мы поддерживаем любой пинг в ущерб быстрой реакции на ввод. Но с пингом выше 300 играть не рекомендуется, необратимо портится игровой опыт. В итоге все сводится к вопросу расположения и стоимости серверов.
Могу посоветовать разобрать сетевой код quake/doom. Там шикарное, на мой взгляд, решение проблемы гарантии доставки.
Если кратко, то сообщения бывают двух видов: важные и неважные. Все важные сообщения складируются в буфер и отправляются с каждым новым пакетом. Как только приходит подтверждение доставки, этот буфер чистится. Получается этакий брутфорс, который в довесок гарантирует что любое «важное» сообщение будет получено перед следующим «неважным».
Насколько я понял, вы используете фотон протокол для общения между игровым сервером и клиентом, и при этом вы пробуете сделать reliable UDP пакеты собственного изобретения, но они же уже есть в фотоне. Почему не стали их использовать?
Отличный вопрос! При первоначальном исследовании фотона и eNet — внутри него я не обнаружил стратегии доставки Reliable-unOrdered. Это означает что пакеты, пришедшие не в том порядке могут быть молчаливо пропущены. В случае с нашим инпутом это вредно — у нас есть кейс, когда мы не можем выстрелить ракетой сейчас по какой либо причине, но должны сделать это в симуляции при выходе из блокирующего состояния. Может у меня устаревшая информация и апи фотона стало гибче в этом плане?
В фотоне есть такие функции:
(код из серверного сдк)
SendResult SendEvent(IEventData eventData, SendParameters sendParameters);
SendResult SendOperationResponse(OperationResponse operationResponse, SendParameters sendParameters);

Параметр sendParameters является структурой:
public struct SendParameters
{
        public byte ChannelId { get; set; }
        public bool Encrypted { get; set; }
        public bool Flush { get; set; }
        public bool Unreliable { get; set; }
 }


в ней можно при отправке указать Unreliable = false и тогда сообщение гарантировано будет доставлено. По поводу очередности — надо читать документацию, этого не знаю.

Использую фотон года 2-3 с версии 2.хх и всегда эта возможность была. Там же есть шифрование, если вдруг понадобится.
Only those users with full accounts are able to leave comments. Log in, please.

Information

Founded
Location
Россия
Website
pixonic.com
Employees
201–500 employees
Registered