Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Алгоритм Real-time Multiplayer

Алгоритм Real-time Multiplayer

Страницы: 1 2 Следующая »
nikotinign3DПостоялецwww28 мая 201811:29#0
Здравствуйте. А как вообще принято в профессиональных студиях решать проблему с разным пингом игроков? Возьмем простой пример дуэли; из двух игроков выигрывает тот, кто первый нажал кнопку (выстрелил). У первого игрока пинг 50 мс, у второго -5000 мс. Даже если второй игрок выстрелил раньше на 1000 мс - сервер сможет об этом узнать только через 2500 мс. И тут возникает 2 интересных момента - первый игрок выстрелил -ждет 1550 мс и погибает, а второй пошел покурить и ему тут приходит уведомление что он выиграл. Эту проблему как то решают? По логике есть только один вариант решения - поставить кучу серверов чтобы пинг уменьшить, но если один игрок на одном конце планеты а другой на другом, то даже это не поможет. Да и потом как время определить в которое был выстрел -на всех устройствах System.currentTimeMillis() отличается (System.currentTimeMillis() -метод java, на С# и других языках как то по другому называется) . Получается нужно вычислять средний пинг и на сервере его вычитать из System.currentTimeMillis(). А если учесть что пинг постоянно прыгает, то вообще все может получится не верно -выиграет не тот кто выстрелил первый. Не подскажите, есть какие то исследования по этому вопросу?
Как принято его решать?

Правка: 28 мая 2018 11:32

ТатаринПостоялецwww28 мая 201811:54#1
не решают, если пинг большой то таких игроков банально отключают, пусть ищут сервера поближе. Если он выстрелил и попал то он попал - вот и вся механика, поэтому во всех шутерах пуля может прилететь когда ты уже забежал за стенку. Люди тут многое любят придумывать но в итоге - в реальности - никто не заморачивается над всей этой фигней, потому что начнешь решать создашь другие проблемы или просто никогда не сделаешь.

Правка: 28 мая 2018 11:55

TiendilУчастникwww28 мая 201812:06#2
Смотря какие игры. Если не шутаны, а какие-нибудь RTS, то там шаг игровой логики может измеряться сотнями мс, соответственно, пинг не так критичен становится, так как команды всё равно будут одновременно применяться. В любом случае, при нормальной архитектуре, логика игр пошаговая :-)

>Да и потом как время определить в которое был выстрел
Опять таки, при хорошей архитектуре, команды на действия применяются на сервере, а не на клиенте. То есть игрок шлёт команду "стреляю", а сервер уже управляет логикой игры и определяет точное логическое время выстрела и рассылает его клиентам. Графика в этом случае пытается подогнать себя под логику.

>поставить кучу серверов чтобы пинг уменьшить
Это уже когда баблос какой-то появляется. Более того, некоторые (Riot Games) даже свои сети прокладывают. Региональные кластера уже норма для многих больших игр.

TiendilУчастникwww28 мая 201812:07#3
Ну и до кучи, правильные команды можно подбирать, со сходным пингом.
nikotinign3DПостоялецwww28 мая 201816:51#5
Tiendil
> Опять таки, при хорошей архитектуре, команды на действия применяются на
> сервере, а не на клиенте.
В случае с выстрелом для хоста не проблема его понять (процессор команду bool shoot=true;  даже не почувствует), а если нужно передать позицию персонажа , которая вдобавок по физике вычисляется, то вычисляя за всех клиентов физику сервер жестко может зависнуть (в доке по юните такой сервер называется авторитарным). А если позволить клиентам физику вычислять, то результат вычисления физики на разных гаджетах может сильно отличаться -один игрок будет видеть одно положение, а другой другое. Раньше использовал box2D встроенный в libgdx и оказалось что результат его физики зависит от fps (не говоря уже о железе). Если его использовать - то неизбежно придется посылать контрольные пакеты (в доке по юнити предлагается 15 пакетов в секунду посылать https://docs.unity3d.com/ru/current/Manual/net-HighLevelOverview.html ). Очевидно чем сильнее мы терроризируем сеть (отсылаем большие пакеты по 1024 byte со скоростью fps (60)), тем сильнее прыгает пинг,чаще возникают задержки сигнала на 1-2 секунд и vps дохнет от переизбытка трафика да и процессор уже не справляется. Все это в купе приводит меня к мысли что физика в таком случае должна зависеть только от времени (с момента нажатия на кнопку) и не от чего более (то есть если fps=1 на каком нить клиенте, и за секунду перс успевает прыгнуть, то не смотря не на что перс вообще не должен прыгнуть на стороне тех клиентов, fps которых меньше 3), тогда можно добиться того, чтобы положения физических объектов на всех клиентах (в момент прорисовки) были одинаковы. Не уверен, но похоже физика unity (как и box2D) зависит не только от времени и не подходит для Multiplayer, лучше самому писать физику.Tiendil
> То есть игрок шлёт команду "стреляю", а сервер уже управляет логикой игры и
> определяет точное логическое время выстрела и рассылает его клиентам. Графика в
> этом случае пытается подогнать себя под логику.
Возможно по этому в CSGO когда лагает, боец перемещается не плавно, а скачками. А как точно время выстрела он вычисляет? На что сервер оперяется в своих вычислениях - на средний пинг до клиента (то есть например клиент послал на сервер с подтверждением 3 пакета - пинг первого 50мс, второго 100мс, третьего 75мс, средний пинг -75мс). Если да, то когда этот средний пинг вычисляется, во время загрузки игры, или постоянно?
nikotinign3DПостоялецwww28 мая 201816:55#6
И существуют ли какие то требования к физике для  Multiplayer, или все используют не предсказуемую физику?
TiendilУчастникwww28 мая 201817:04#7
>А как точно время выстрела он вычисляет?
Тут лучше опираться на логическое (серверное) время. В простешем случае  сервер может смотреть время получения команды и его использовать. В чуть более сложном клиент может сказать "сделай действие на 100500 ходу/тике".

Про физику надо помнить одну штуку: их две на самом деле:

- физика логики (например, как игрок движется, прыгает, etc)
- физика визуалирзации (например, как легли пулевые отверстия на стену, как движутся волны на воде)

Первую лучше делать на сервере и она довольно лёгкая (по сравнению со второй).
Вторую лучше делать на клиенте.

По реализации, как-то так:

- физику логики считает и клиент и сервер
- клиенты передают на сервер команды (но сами их выполнять не начинают, пока забиваем на апроксимацию)
- сервер получает команды, применяет их у себя и рассылает их клиентам с синхроннизированными временными метками (серверное время)
- клиенты применяют их к своей модели мира и, если руки прямые у разработчиков, получают одинаковые результаты (так как последовательность команд одинаковая
- если руки у разработчиков не очень кривые, то используются разного рода эвристики: периодически скачивается снимок мира с сервера, ограничиваются параметры физических взаимодействий (например, моментально останавливаются предметы, движущиеся с очень малыми скоростями).

nikotinign3DПостоялецwww29 мая 20188:32#8
Tiendil
> Тут лучше опираться на логическое (серверное) время. В простешем случае  сервер
> может смотреть время получения команды и его использовать. В чуть более сложном
> клиент может сказать "сделай действие на 100500 ходу/тике".
Спасибо, если правильно понял - сервер не должен знать пинг клиента, серверное время (от запуска игры) должны знать клиенты, которые вычисляют его с помощью своего среднего пинга. Запустить серверное время (игру - карту, гонку, etc) сервер должен тогда, когда сигнал о запуске дошел до самого дальнего клиента, остальные клиенты (пинг которых меньше) его ждут, получается сервер должен еще всем отправить самый большой пинг, который перед запуском серверного времени должны все дождаться (чтобы у всех серверное время началось (почти) одновременно). Но запаздывание все равно неизбежно, о том что клиент выстрелил - сервер может узнать только после того, как к нему сигнал пришел (на пол пинга позже).Tiendil
> Первую лучше делать на сервере и она довольно лёгкая (по сравнению со второй).
Использовал одно время Box2D на андроид 2.3 с процессором 600 Мв, и когда 4 перса сталкивались -fps падал с 60 до 10. Это 4 перса, а на одном сервере может находиться >10000 клиентов, и для всех нужно вычислять физику. Это какой для этого нужен vps сервер - стоядерный процессор по 5 гигагерц? НЕ лучше ли клиентам вычислять физику логики? Или коллизии не относятся к физике логики?
ZabПостоялецwww29 мая 201810:36#9
nikotinign3D
> чтобы у всех серверное время началось (почти) одновременно
Это способ испортить жизнь всем игрокам из-за одного нехорошего соединения. По идее должен страдать только тот, у кого соединение плохое, пусть его это беспокоит и он ищет способ улучшить свои условия, а не наказывать из-за него всех невиновных.

> когда 4 перса сталкивались -fps падал с 60 до 10
Колижн модели делай упрощенными, не надо столкновения вычислять по рисуемым объектам. Тем более на сервере.

Очень многое можно считать на клиенте. А чтобы не читерили, подменив клиент, тоже самое считать и на сервере, для контроля. Но на сервере можно упрощать.
Это один подход. Если же клиенту не доверять совсем, все считать на сервере, придется тщательно выбрать приемлемый уровень упрощения, не делающий поведение ущербным.

> на одном сервере может находиться >10000 клиентов
Трафик не забудь посчитать. Хрен с ней с физикой, сеть то выдержит?
Если ничего не предпринять, объем пересылаемых данных растет в квадрате от числа игроков.

TiendilУчастникwww29 мая 201810:45#10
Zab
+1

10000 игроков на сервере нет ни у кого. Точнее на сервере-то да, а на одной карте нет. Большое количество игроков - это вообще хардкорно. Даже евка эту ситуацию очень специфично обрабатывает (замедляет игровое время на порядки).

По поводу хитрых общётов и рассылок можно погуглить как WG делает серверную часть танков. Или сразу архитектуру Big World почитать, если документация есть в открытом доступе.

Общий подход к таким штукам: сделать сначало чтобы просто работало, потом оптимизировать под конкретные требования (и требования тоже оптимизировать под реалии нашей вселенной). Потому что одинаоково хорошо сделать для всех случаев не получится.

Иными словами: физики, сеть и игровые правила имеют очень сильные связи между собой, работать над ними можно только в сумме. Нельзя сделать сеть, которая будет работать для всех сочетаний физики и логики, нельзя придумать логику, которая будет работать для всех вариантов физики и сети, ну физикой то же самое.

nikotinign3DПостоялецwww29 мая 201811:48#11
Tiendil
> 10000 игроков на сервере нет ни у кого.
Интересно как такую проблему решает csgo https://store.steampowered.com/app/730/CounterStrike_Global_Offen… ve/?l=russian ? У них в игре было больше 300000 игроков. Если на одном сервере <10000 игроков то это уже минимум 30 серверов.

Правка: 29 мая 2018 11:49

TiendilУчастникwww29 мая 201811:54#12
nikotinign3D
> Если на одном сервере <10000 игроков то это уже минимум 30 серверов.
Так и решают. Горизонтальное масштабирование называется.
Sh.Tac.Постоялецwww29 мая 201813:48#13
вроде бы есть демка с 1000 чуваками на одной сцене, 10000 нет : )
https://www.youtube.com/watch?v=JNN_J0g5fmQ
ZabПостоялецwww29 мая 201813:52#14
Sh.Tac.
> вроде бы есть демка с 1000 чуваками на одной сцене
Даже 200 - уже цифра запредельная, если не применять всяких хитростей, чтобы не слать каждый раз информацию всем обо всех.
Страницы: 1 2 Следующая »

/ Форум / Программирование игр / Сеть

2001—2018 © GameDev.ru — Разработка игр