Тема: Сеть
Показать сообщение отдельно
Старый 18.01.2013, 01:54   #3
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Ответ: Сеть

Учитывая что у тебя мультплеер с летящими пулями, то если пули летят не слишком быстро, можно и интерполяцией обойтись. НО, тут нужно тогда на сервере учитывать стрельбу в прошлом и это порой геморойней сказывается.

Поэтому лучше всего это экстраполировать. Тем более что у тебя чистой воды взаимодействие с другими игроками, так что экстраполяция - musthave.

Экстраполировать нужно на промежуток времени вперёд, равный твоему пингу пингу самого клиента. Таким клиент будет стараться симулировать состояние в мире идентичное как в реальный момент на сервере.
Самого же себя нужно управлять напрямую, НО. Используя начальную задержку. Короче нужно сперва экстраполировать личные данные, и если они сильно не расходятся с теми что пользователь пытается применить вводом - разрешать применять. Иначе смешивать плавно с экстраполируемой. Это исправит сильные ошибки из-за лагов. Также вначале движения, т.к. игрок стоит ещё на клиенте, и сервер не начал идти, а клиент уже выдал инпут - следственно его инпут будет применяться лишь частично, будет эффект разгона игрока.
Это нужно тупо потому что сервер получит данные позже, и начнёт двигать игрока позже, следственно мы не можем сразу бежать быстро.

Про стрельбу, тут очень важно правильно экстраполировать на клиентах. Если это сделано честно, то и игрок будет стрелять честно.

Скорость пули нужна достаточно быстрая.
Но есть тут правда одна зацепка, при больших лагах, команда о выстреле дойдёт до сервера намного позже, и тем самым не попадёт.

Поэтому нужно реализовывать машину времени на сервере.
Которая в случае с выстрелами будет делать такой ход: Клиент прислал запрос на выстрел. Сервер идёт назад на промежуток времени равный пингу клиента, и проверяет если клиент мог тогда выстрелить, если да, то стреляет тогда, затем проверяет не попал ли ни в кого между тем где был, и сейчас. Если нет, то пуля создаётся уже с учётом прошедшего времени от начала выстрела в прошлом, то есть она будет впереди.

Также есть такая тема с парадоксами. Например КлиентА с пингом 50, выстрелил фатальный в КлиентВ на момент игры 1000 мс. А КлиентБ с пингом 150 выстрелил фатальный в КлиентВ на момент игры 950мс.
КлиентБ по сути должен быть тот кто убил, т.к. реально выстрелил раньше.
Но сервер получит выстрел от КлиентА на момент 1050, и убьёт КлиентВ. И лишь потом на момент 1100 получит пакет от КлиентБ, пойдёт в прошлое стрелять, и окажется он убил КлиентВ раньше чем КлиентА.
И тут дилемма как поступить.
Простейший вариант - это сообщать что КлиентВ мёртв. Но награждать убийцу и сообщать кто убил нужно по протяжению максимальной задержки машины времени. Например 500мс. Таким образом будет в разы честнее. Это относится не только к выстрелам.

Только так можно сделать Честную игру, где не будет приоритета игрокам с лагами и без.

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

То что описал выше, называется Optimistic Consistency. Есть ещё пессимистичная консистенция, это интерполяция, и много прошлого на сервере.
Для Action-like нужна экстраполяция, т.к. с пессимистичной моделью у тебя задержка будет ужасной..

Кстати какой у тебя UPS (Update Per Second) на сервере?
(Offline)
 
Ответить с цитированием
Эти 5 пользователя(ей) сказали Спасибо moka за это полезное сообщение:
HolyDel (19.01.2013), nil0q (18.01.2013), pax (18.01.2013), Phantom (16.08.2013), St_AnGer (18.01.2013)