Комментарии 16
Спасибо за статью! Интересно почитать как люди решают те же самые проблемы, что и ты сам.
А как у вас сделан игровой сервер? Это специальный юнити headless билд или вообще отдельное приложение?
И второй вопрос про игровую симуляцию. Я так понимаю у вас трёхмерный мир и персонажи перемещаются свободно. Перемещение, collision detection и collision response у вас сделан средствами юнити и его PhysX? Или какая-то своя логика или свой физический движок?
А как у вас сделан игровой сервер? Это специальный юнити headless билд или вообще отдельное приложение?
И второй вопрос про игровую симуляцию. Я так понимаю у вас трёхмерный мир и персонажи перемещаются свободно. Перемещение, collision detection и collision response у вас сделан средствами юнити и его PhysX? Или какая-то своя логика или свой физический движок?
0
Игровой сервер — NET приложение на фреймворке Photon, Unity в сервере не участвует.
В симуляции используем отдельную 2D физику (VolatilePhysics) и периодически туда контрибьютим, т.к. в ней есть конкретные баги. Нам повезло, что мы смогли упростить взаимодействия до столкновений неупругих примитивов + рейкастов (сферические и обычные) для расчета видимости и попаданий.
В симуляции используем отдельную 2D физику (VolatilePhysics) и периодически туда контрибьютим, т.к. в ней есть конкретные баги. Нам повезло, что мы смогли упростить взаимодействия до столкновений неупругих примитивов + рейкастов (сферические и обычные) для расчета видимости и попаданий.
+3
>> Determinism (Volatile uses floating-point values, and is not deterministic across hardware configurations)
Я правильно понимаю, что вы используете библиотеку на клиенте и сервере? Каким образом построена синхронизация в таком случае? Как-то корректируете по мере поступления информации с сервера? Или может имеются свои дополнительные надстройки?
Или я неправильно понял и в вашем случае клиент работает исключительно в роли «телевизора», получая постоянные обновления всего мира с сервера? Хотя вы пишите, что есть возможность локальной симуляции без использования сервера.
Я правильно понимаю, что вы используете библиотеку на клиенте и сервере? Каким образом построена синхронизация в таком случае? Как-то корректируете по мере поступления информации с сервера? Или может имеются свои дополнительные надстройки?
Или я неправильно понял и в вашем случае клиент работает исключительно в роли «телевизора», получая постоянные обновления всего мира с сервера? Хотя вы пишите, что есть возможность локальной симуляции без использования сервера.
0
Да, клиент — «телевизор», верит только серверу. Лишь изредка экстраполирует по примитивным правилам для поддержания плавности при высокой потере пакетов. Симуляция на клиенте нужна только для отладки и работы оффлайн. Например: стартовое обучение бою. Поддерживать подключение к серверу расточительно и излишне влияет на воронку прохождения — мы запускаем симуляцию с ботами локально на девайсе.
0
Спасибо за статью. Но делать субмодули из-за прото файлов, как то очень сомнительно.
Было бы лучше использовать UPD+TCP. UDP для стрельбы, передвижения и т. д. TCP для этих ракет и вообще для того что точно должно дойти. Вроде бы для этого и TCP и создан.
Было бы лучше использовать UPD+TCP. UDP для стрельбы, передвижения и т. д. TCP для этих ракет и вообще для того что точно должно дойти. Вроде бы для этого и TCP и создан.
0
Не могу согласиться)
В риалтайм играх самое важное — максимально быстрая доставка пакетов. UDP + перепосылка пакетов обеспечивает максимально быструю доставку пакетов(даже теоретически не получится быстрее).
За более развернутым ответом прошу на https://gafferongames.com/post/udp_vs_tcp/
:)
+1
С мобильным пингом вы бы не заметили разницы TCP+UDP vs UDP. По мне с кейс с ракетой этого не стоит. Но в других случаях это приемлимое решение.
0
Это смотря как делать. И если делать правильно, то реально разница есть. Вообще миксовать TCP и UDP то еще занятие.
+1
Странно я думал работа с лобби, отправка ивентов об inAppPurchases и т д. Вы отправляете по TCP.
0
Скажите, а на какой пинг ваших мобильных игроков вы "целитесь"?
0
Могу посоветовать разобрать сетевой код quake/doom. Там шикарное, на мой взгляд, решение проблемы гарантии доставки.
Если кратко, то сообщения бывают двух видов: важные и неважные. Все важные сообщения складируются в буфер и отправляются с каждым новым пакетом. Как только приходит подтверждение доставки, этот буфер чистится. Получается этакий брутфорс, который в довесок гарантирует что любое «важное» сообщение будет получено перед следующим «неважным».
Если кратко, то сообщения бывают двух видов: важные и неважные. Все важные сообщения складируются в буфер и отправляются с каждым новым пакетом. Как только приходит подтверждение доставки, этот буфер чистится. Получается этакий брутфорс, который в довесок гарантирует что любое «важное» сообщение будет получено перед следующим «неважным».
+1
Насколько я понял, вы используете фотон протокол для общения между игровым сервером и клиентом, и при этом вы пробуете сделать reliable UDP пакеты собственного изобретения, но они же уже есть в фотоне. Почему не стали их использовать?
+1
Отличный вопрос! При первоначальном исследовании фотона и eNet — внутри него я не обнаружил стратегии доставки Reliable-unOrdered. Это означает что пакеты, пришедшие не в том порядке могут быть молчаливо пропущены. В случае с нашим инпутом это вредно — у нас есть кейс, когда мы не можем выстрелить ракетой сейчас по какой либо причине, но должны сделать это в симуляции при выходе из блокирующего состояния. Может у меня устаревшая информация и апи фотона стало гибче в этом плане?
0
В фотоне есть такие функции:
(код из серверного сдк)
Параметр sendParameters является структурой:
в ней можно при отправке указать
Использую фотон года 2-3 с версии 2.хх и всегда эта возможность была. Там же есть шифрование, если вдруг понадобится.
(код из серверного сдк)
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.хх и всегда эта возможность была. Там же есть шифрование, если вдруг понадобится.
0
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.
Дневник техлида: полгода разработки мобильного PvP