Pull to refresh

Comments 47

А экстраполяция присутствует? А откатывание времени на сервере назад присутствует? Ведь в клиент-серверной реалтайм игре основная фишка в том что игровое время на сервере опережает время клиентов на время пинга, зачастую это 50-100 мс. И если клиент что-то делает то нужно откатывать время на сервере назад и смотреть мог ли он это сделать действительно. Еще у клиентов есть данные для интерполяции наперёд только на 100-200 мс. В реальности случаются пинги и в 1000+ мс, игра запросто получит ситуацию когда просто не будет информации для рендера.
Вся статья о том, что экстраполяция — это зло. Дело в том, что это не сервер опережает, а клиент запаздывает. Собственно, об этом и статья. Достаточно тонкий момент, который я почему-то долго не понимал. Возможно, вы имели ввиду «предсказание на клиенте». Но это работает только для локально изменяемых объектов (которые контролирует конкретный клиент) и, в случае промаха, создает баг. Это как раз случай про длинные пинги в 1000мс. Предсказание, на сколько я понял, в общем виде вообще не имеет решения.

Откатывать можно, но не всегда нужно (от игры зависит). У всего есть свой предел. Если пинг — полчаса, и мы откатываем, то мы смоделируем эффект бабочки. И все будут страдать от самого медленного.

Сейчас я считаю (возможно неверно), что события (сэмплы клавиатуры) происходят именно тогда, когда они пришли на сервер, либо они выражены во времени относительно событий, уже зарегистрированных на сервере. Таким образом, последовательность и интервалы между событиями остаются такими же как на клиенте для конкретного клиента. Получается, что сервер получает события «почти всегда» из будущего (относительно текущей ситуации) и моделирует до этого будущего. То есть перемотка назад «почти всегда» не нужна, а страдают больше всего игроки с длинным пингом (что кажется логичным).

В целом, сейчас экспериментирую с друзьями на эту тему, так что не судите строго — рассказывайте как надо, если я не прав.
Для шахмат можно считать что событие произошло когда пришло на сервер, для реалтайм (об этом статья же) например стрелялки (fps и не только) — это не так, игрок нажал на кнопку и догадайтесь когда игра должна среагировать? Верно — сразу же, точнее — через 1-2 кадра, это 16-32 мс. Ответ от сервера прийдет как минимум через 100 мс, если рендер будет рисовать ответы от сервера то будет жесткое ощущение лагов и в такую реалтайм игру никто играть не будет. Потому время на клиенте как раз «сейчас», а серверу приходится существовать в «будущем», да еще таком что время любого клиента было меньше времени сервера, но время сервера не было сильно больше времени любого клиента, иначе слишком много нужно данных хранить о действитях клиентов. Поскольку все клиенты имеют время «сейчас», а канал связи между ними — 2 пинга, то экстраполяция наше всё, без неё вообще никак. Так устроены все сетевые стрелялки, а это самые требовательные к сетевой составляющей игры.
Абсолютно верно, но это называется prediction. И на клиенте у нас получается два времени — одно в будущем, а одно в прошлом относительно сервера. Об этом можно отдельно статью написать или перевести.

Здесь речь идет о том, как сделать плавным движение противника.

Если же события от клиента на сервере запаздывают — в этом нет никакой проблемы, потому что действия этого клиента происходят на сервере в правильном порядке и через те же интервалы, что и на клиенте. А как они накладываются на действия противников — это уже второй вопрос и, в целом, не такой важный, так как правду все равно никто не узнает =)
В реалтайм сетевой игре у каждого клиента «свой мир» и серверу нужно чётко проверять не только по дельтам времени, а то получится что клиент у себя убил противника, а на сервере противник уже чуть сдвинулся и клиент не попал.
Конечно, так тоже можно попробовать сделать, но в данной статье описывается модель, в которой сервер всегда прав. То есть это не сервер подстраивается под каждого клиента (что невозможно), а клиент подстраивается под сервер. По этому вопросу надо подробнее читать «weapon prediction». Там для меня пока темный лес.
Видимо, в сети не так много документов аналогичных этому — постоянно вижу именно эту ссылку. Может у кого-нибудь в закладках имеется что-то интересное по теме? Вот, например, из моих закладок: gafferongames.com/networking-for-game-programmers/
ооо душевное спасибо за вашу ссылку!
Какое-то время назад мне казалось что у многопользовательских игр на Node.JS + HTML5 большое будущее. Мне все еще не очень понятно почему нету чего-то такого сильно популярного.
Есть, вы просто не знаете что они на node.js + HTML5 :). Например — «Полный Пи».
Он до сих пор на ajax. Но, насколько я знаю, там вполне себе node и вполне себе HTML5, местами. Вебсокеты != HTML5.
«Powered by Jetty» — вроде там Ява использовалась в качестве сервера? Если я правильно понял это та игра прототип которой тестировался на хабре, но я не знаю что довели проект до такого законченного состояния.
Вопрос отличный. Я ни одной популярной игры не знаю.

Но для прототипирования, связка очень удобная — один код на клиенте и на сервере (как раз к вопросу предсказания на клиенте). При этом, разработка быстрее, чем на C++. Для экспериментов — самое то.
На главной картинке супер-герой Flash. Это намек на чем нужно было делать клиент?
И правда смешно, но нет. Но Flash на клиенте у меня работал на порядок хуже (просто моделирование игры, без сервера).

А супер-герой — это то ощущение, которое возникает, когда ты находишь баг и prediction начинает работать.
Важное замечание.

А можете рассказать подробнее, что именно имеете в виду под «на порядок хуже»? Очень заинтересовало, т.к. собираю информацию об этом сейчас
Делал достаточно сложное моделирование (много расчетов на каждом кадре). Там где флеш ложился и не собирался вставать, js+canvas продолжал работать отлично еще очень долго. Возможно это мой частный случай, но он выглядел для меня очень показательно.

При предсказании положения клиента, на нем приходится делать моделирование мира, как на сервере. Если мир будет достаточно сложным, на этом этапе могут включиться тормоза.
Очень спорное замечание, видимо что-то на флеше рисовалось в лоб, без использования Bitmapdata.draw и прочих техник, я уж и не говорю про включение аппаратного ускорения рисования. Никогда не будет интерпретируемый в браузере javascript работать быстрее чем заранее откомпилированный actionscript во флеше.
Будет, еще как будет. Вы немного отстали от технологий: ни один современный браузер не интерпретирует javascript, его сейчас только компилируют с помощью JIT. А скорость работы откомпилированного кода на том же V8 уступает разве что плюсам и другим «низкоуровневым» языкам.
О как, интересно… А что тормозило во флеше, отрисовка или логика в коде, и в каких пропорциях вносило вклад в «торможение»?
Не измерял, но логика в коде была чуть более чем насыщенная. Алгоритма сложности n^2. Флеш зависал где-то на n=30, а js нормально работал при n=100. Это навскидку.
А нет демок где-то размещенных с публичным доступом? Хотелось бы посмотреть глазами без клонирования репозитория.
В этой модели имеется единый авторитетный сервер, который и моделирует игру. А также клиенты, посылающие лишь свои данные ввода. Например, я посылаю только информацию о том, что моя клавиша «пробел» была нажата, а сервер определяет, что это обозначает в терминах игры. Благодаря данной модели, мы освободились от множества проблем предыдущей реализации.


1) 75 миллисекунд от цели до сервера, +75 мс от сервера до стрелка = 150 мс. Стрелок стреляет по своему разумению (в то, что видит) и отсылает пакет с заявкой на попадание с вектором снаряда в момент попадания, что даст теперь 225мс.

При скорости движения 16 км/ч (=4.444м/с) (это PzKpfw III на пересечённой местности) за это время цель успеет переместиться вплоть до 1 метра. Строго говоря, в неопределённом направлении, то есть ±1 метр. Такая неопределённость составляет 2 метра в диаметре.

а) Стрельба по слабым местам бронирования теряет смысл.

На практике 75 мс могут получить только игроки Дефолт-сити, и, вероятно, окрестностей. У меня до дефолт-сити вплоть до 300 мс, а это ±4 метра с противником, который тоже имеет 300 мс. Длина корпуса PzKpfw III составляет 6 метров, что делает стрельбу почти бессмысленной.

И это БЕЗ учёта подлётного времени снаряда, которое на, например, танковой дистанции в 500 метров составит, в лучшем случае, 615 мс (это при 650 м/с начальной скорости снаряда Ф-34 и БЕЗ учёта торможения в воздухе — лень искать баллистический калькулятор, да и с ним будет только хуже).

В случае Дефолт-сити: 75 мс + 75 мс + 615 мс + 75 мс = 840 мс => ±3.73 метра
В случае 300 мс: 300 мс + 300 мс + 615 мс + 300 мс = 1515 мс => ±6.73 метра

б) Стрельба вообще теряет смысл

Даже если исключить время возврата попадания (цель экстраполируется), результаты всё равно весьма печальны.

2) Для авиасимов с их, ну скажем, хотя бы 400 км/ч = 111.11 м/с архитектура заведомо и гарантированно обеспечивает промах. (Длина B-17 Flying Fortress 22.6 м)

3) Всё это сказано без учёта пинга «терминального доступа к моему юниту», то есть лага по моему же джойстику, к которому автор призывает привыкнуть.

Вероятно я ошибаюсь, но у меня получается так.
P.S. Я не упомянул рассеивание снарядов из ствола стрелка?

P.P.S. В статье не разглядел тему визуализации попадания. В какой момент рисовать вспышку на мишени: когда я шлю факт попадания, когда сервер подтверждает попадание, когда мишень получает повреждение?

В первом случае игроки должны «привыкать», что мало какая вспышка является попаданием и ждать текста от сервера (не очень атмосферно),
во втором случае игрокам придётся ждать 75-300 мс (в кучу к 615 мс подлёта), но попадание, вроде, гарантировано,
в третьем случае игрокам придётся ждать 300-1200 мс (в кучу к 615 мс подлёта), мишень согласилась оказаться подбитой и начинает разваливаться на глазах.

Пока что получается, что защита от единичных читеров заставляет поголовно всех игроков «привыкать» и к лагу джойстика и к лагу попадания.

P.P.P.S. Что же касается нулевой скорости подпрыгнувшего мяча, то грамотные игроделы имеют в загашнике вплоть до второй производной скорости по словам игрока. И новая скорость (в дальнейшем и новые координаты) всегда вычисляется с учётом ускорения игрока, или даже с учётом изменения ускорения.
Все это можно попробовать сделать за счет магии на клиенте (см. prediction и т.д.). Я пробовал — работает очень круто при «реальном» пинге. Но, конечно, если у вас пинг — две секунды, то играть вы сможете только в шашки.
Тогда вам придётся отказаться от вашего утверждения «Пользователь всегда будет сообщать, что он находится там, где ему надо, попадает во всех противников со стопроцентной точностью и имеет полный запас здоровья.»

К тому же я не утверждал, что «у меня пинг 2000 мс».
«У меня лично пинг 100-300 мс».
Если пользователь отсылает только сэмплы клавиатуры, а не местоположение с координатами, то он будет двигаться инкрементально (см статью).

Я никоим образом не хотел обидеть ваш пинг =) 100-300 — очень хороший пинг.
пинг гугла в спб 8мс, яндекс 15мс, до сервера уфы к примеру 40мс
если пинг будет скажем в 30мс то это 15мс на отправку пакета, не так уж и много
если делать игру на webrtc можно подключатся к игрокам напрямую, а на сервере будет просто проверка всех действий игроков
если игроки будут с одного города то можно играть абсолютно без никаких лагов
Да, так тоже можно, но это кажется гораздо сложнее и при этом не факт, что быстрее, так как надо некоторое время на синхронизацию событий. Не совсем понятно как добиться того, чтобы все клиенты моделировали один и тот же мир (состоящий их одних и тех же событий в нужной последовательности и через одинаковые интервалы).
если игроков не много я думаю можно делать подключение многое ко многим, т.е. каждый игрок посылает свои действия для всех + для сервера, а те уже в свою очередь формируют мир в зависимости от поступаемых данных
сделал выстрел, если реально убил то значит посылаешь команду о попадании для всех игроков, а сервер уже проверит так оно было или нет
Именно. Но, почему-то после прочтения именно статьи из перевода, у меня все встало на свои места. Она написана более просто. Поэтому решил поделиться.
Тем кто понимает что описано в статье, советую продолжить читать: Trailing State Synchronization

«Наша нервная система может подстраиваться под задержку.» — Ха Ха Ха! Если это какая-нибудь кнопка, триггер — то всё ок. А если надо отображать перемещение персонажа, или то как он блок из стены вынул, или там бомбу поставил?

WebSockets => если при использовании TCP пакет потеряется то пинг будет побольше 75мс.

P.S. у меня простой Time Warp с кучей хаков.

Ваш bombermine.com
Данная статья, действительно, для начинающих. Мне лично она помогла побороть порог на вход, во многом из-за простоты изложения.

Про нервную систему — верно, остальное, я думаю, во многом можно побороть используюя предсказание.

Спасибо за ссылку. Буду изучать.

На ваш проект посматривал. Если опишите, как оно работает с точки зрения отзывчивости, наложения эффектов и звуков, с какими проблемами боролись и как, какие были ошибки при реализации, буду весьма благодарен.
Такое ощущение, что на ноде написали уже все html5 игры.
Было бы интересно увидеть что-то более экзотическое. Erlang + lua или go например.
Правду сказать, тут больше не про node.js, а про клиент-серверную модель в многопользовательских realtime приложениях. Нод хорошо подходит для экспериментов в этой области и для создания маркетингового эффекта (шутка с долей правды). Как он себя поведет при нагрузке, все-таки хотелось бы сначала посмотреть вживую. А для этого надо привлечь несколько тысяч пользователей (достаточно большие риски).
на локалхосте хорошо выглядит, без лагов. интересно было бы взглянуть если бы пинги были по 100 мс
Может как-нибудь добавить sleep() на сервере, чтобы сэмулировать пинг?
для этого есть специальные прокси, эмулирующие любые линии и скорости клиентов
Блин, я ничего не понял примерно после середины статьи))
Так какая методика более-менее нормальная для реализации «плавного» и хорошего реалтайма?
Берешь горстку грабель, раскидываешь их по сторонам, завязываешь глаза и начинаешь бегать. В общем, экспериментальная. Часто достаточно не самого «хорошего» реалтайма :)
Зависит от механики игры. В eve online, например, они замедляют время, когда много пользователей накапливается в одной локации. Во многих action играх (например counter strike), упрощают механику стрельбы так, что пуля долетает за бесконечно малое время.

Известно, что эта задача, в целом не решаемая. Поэтому надо работать над теми моментами, которые «плохо выглядят» со стороны пользователя. Даже если решение не логично, оно может улучшить геймплей. Понять это можно только по юзер тестам, к сожалению.
Sign up to leave a comment.

Articles