Открыть список
Как стать автором
Обновить

Комментарии 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.хх и всегда эта возможность была. Там же есть шифрование, если вдруг понадобится.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.