Говоря обобщённо, "сетевое решение" (сетевая библиотека) - это дополнительный ассет с библиотекой кода, в которой весь функционал для передачи данных по сети уже написан. Вам остаётся лишь использовать его в своей игровой логике, следуя документации и обучающим материалам. Скачиваем, добавляем в проект. И после этого вы сразу можете делать то, что вам нужно: синхронизировать передвижение персонажей между клиентами, синхронизировать анимации, визуальные эффекты, звуки, переменные, методы и многое другое. Буквально с помощью нескольких строчек кода. А иногда, просто добавив определённый компонент на игровой объект. Нет необходимости вручную формировать и отправлять пакеты с данными. Это уже написано за вас. Конечно, понадобится изучить документацию и понять, что к чему. Но это всё равно гораздо проще, чем писать абсолютно всю сетевую логику для вашей игры с нуля.
1. Что по нагрузке на хост? Насколько требования к железу растут для такие клиентов?
2. Что по поводу пинга и того, что у хоста явное преимущество за счёт нулевого пинга?
3. Что с читерством со стороны хоста?
1. Требования к железу для хоста растут. Потому что ему приходится обсчитывать и серверную и клиентскую логику. А другим игрокам - только клиентскую. На сколько именно - зависит от того, как именно устроена серверная логика. Скажу так - примерно 70-80% процессорного времени в игре занимает рендеринг, обсчёт физики, работа сборщика мусора. А на саму игровую логику остаётся около 20%. Расти будут только последние 20%, потому что только в этой части процессорной нагрузки между хостом и клиентом есть различия. Предположим, у хоста она будет 40%, а у клиента - 20%. Соответственно, 120% суммарной нагрузки для хоста и 100% суммарной нагрузки для клиента. Не такая уже большая разница. Но повторюсь, всё зависит от конкретной сетевой логики.
Более того, нагрузка на сеть тоже будет отличаться. У хоста пропускная способность должна быть выше. Если играют 4 игрока, то хост должен будет вести обмен с 3-мя игроками, а каждый из клиентов - только с хостом. В моей игре на сцене может быть до 60 персонажей. И у всех постоянно синхронизируется позиция, ротация, анимация и ещё куча всего. Иногда трафик у хоста может составлять, например, 3 Мбит/с. А у клиента раза в 2 меньше. Мои замеры были довольно грубыми, поэтому в этих цифрах я не уверен. Чем меньше синхронизаций - тем меньше пропускной способности требуется. Я проводил сетевые тесты вдвоём, втроём, вчетвером. Скорость интернета у меня не очень высокая. Тем не менее всё работает стабильно.
2. Пинг зависит от ряда факторов: удалённость между игроками, качество сетевого кода, качество сетевой инфраструктуры и т.д. Как я писал в статье - у хоста нулевой пинг, а у клиентов - нет. Соответственно, у хоста в любом случае будет преимущество. В моей игре Final Foe пинг обычно не более 100 ms, иногда меньше. Для PVE-кооператива это не критично.
3. Большинство игр типа "Хост-Клиент" рассчитаны на нескольких друзей, решивших вместе во что-то поиграть. Так что даже если игра соревновательная - было бы странно пытаться читерить. Заниматься реверсивной инженерией или чем-то вроде этого, чтобы заменять исходящие сетевые пакеты - чтобы победить своего знакомого в дружеской игре? Это бред. А если говорить про всякие MOBA или MMO-игры, то в них повсеместно используются выделенные сервера. Подключение "Хост-Клиент" не используется в современных соревновательных играх.
Ананасовые вопросы, аж жуть, словно на собеседование на сеньор-юнити-бекенд-разраба попал
А расскажите пожалуйста, как вы реализовали Client-Side Prediction/Server Reconciliation, какие есть проблемы синхронизации игроков (с разным пингом), и как вы их решали. Есть ли это в решении Mirror или писали сами. В общем, интересует техническая часть мультиплеера на Unity :)
Лет пять назад пытались делать мультиплеер в игре на Unity, как мы тогда бомбили от того, что библиотек много, но нигде не было решения просто подключи и играй, без лагов, телепортаций и прочих проблем мультиплеера. А в самом движке есть какие-то механизмы, но тоже не работают без дополнительного кода (может сейчас изменилось). Так и не сделали...
Да, думаю что с тех времён многое кардинально поменялось. Если честно, я не до конца понимаю, что конкретно вы имеете в виду под Client-Side Prediction/Server Reconciliation в кооперативном мультиплеере типа "Хост-Клиент", но как я могу предположить - это ряд мер, которые нужно предпринять, чтобы на стороне удалённых клиентов всё работало и выглядело плавно при условии, что ключевая логика обрабатывается на хосте. Т.е. всё, что касается ввода, передвижения персонажа и т.д.
Начнём с интерполяции. По-моему ещё года полтора назад в Mirror, например, не было нормальной интерполяции передвижения. Сейчас она есть и очень крутая.
Коротко об интерполяции. Если пинг в игре составляет 100 ms, это означает, что клиент получает 10 сетевых пакетов в секунду. Если мы перемещаем персонажа только тогда, когда он получает пакет - то его движение будет дёрганым, как будто у нас в игре 10 FPS. Интерполяция передвижения - это предсказание направления движения персонажа на клиенте. Таким образом, пакетов по-прежнему приходит 10 в секунду, но на стороне клиента всё работает плавно. Например, если вы играете в Albion Online, ваш персонаж куда-то бежит и в этот момент вас резко убивают - ваш персонаж резко отбросится немного назад. К своему настоящему местоположению на сервере.
Так вот, в Mirror - интерполяция на данный момент работает очень плавно и реализуется автоматически при добавлении на сетевой объект компонента NetworkTransform.
Также в Final Foe есть ряд механик, в которых клиент сразу должен получать отклик, не дожидаясь ответа от хоста.
Например, при добивании мобов - моб должен превращаться в рэгдолл и откидываться сразу, не дожидаясь ответа от хоста. У хоста, понятное дело, это происходит сразу по умолчанию. Но то, как это будет происходить у удалённого клиента - зависит от того, как будет устроена сетевая логика.
Т.к. Final Foe - это не соревновательная ММО-игра, а кооператив для друзей - у меня в данном случае больше свободы действия. Например, я могу реализовывать ключевую логику не только на сервере, но и на клиенте. В данном случае - если игрок-клиент наносит монстру смертельный урон, то он не посылает запрос на сервер мол "Я его точно убил? Можно превратить этого монстра в рэгдолл?". Он сразу отправляет его в рэгдолл, потому что нанесение урона сначала обрабатывается на клиенте. А потом на сервер отправляется уведомительная информация о нанесённом уроне. И сервер синхронизирует нанесение урона и смерть этого моба для всех остальных клиентов, включая самого хоста.
Такая схема позволяет всем смертям монстров на удалённом клиенте выглядеть плавно, без задержек.
Вообще в Final Foe довольно много подобных вещей. Если вы посмотрите видеоролик из данной статьи - вы увидите, что там есть маг в белой мантии. Он создаёт различные предметы и убивает ими противников. Так вот, эти предметы синхронизируются не с помощью NetworkTransform + интерполяция. Мне нужно было, чтобы на всех клиентах, этот созданный предмет был абсолютно точно привязан к магу и следовал бы за ним постоянно. Интерполяция не даёт такой абсолютной плавности и точности позиции и ротации. Это было реализовано по-другому. Клиент, играющий за мага, передаёт всем остальным игрокам данные мага и данные предмета. И на каждом клиенте этот предмет привязывается к этому магу. И его следование за этим магом обсчитывается на клиенте, а не синхронизируется по сети. У предметов в Final Foe вообще нет компонента NetworkTransform.
Сообщение получилось длинным. Надеюсь, я ответил на ваш вопрос)
обычно используются специальные промежуточные сервера. Так называемые "лобби"вроде как правильнее их называть Relay сервера. Они только гоняют трафик и избавляют хост от необходимости паблик айпи, тут всё верно! Кроме стима такие есть и у эпиков, тоже бесплатные.
Пример улиц Таркова в частности и всего Таркова в целом говорит, что масштабный мультиплеер на Юнити штука сложная и почти что тупиковая из-за особенностей движка.