Как стать автором
Обновить

Комментарии 54

Не смогу теперь просто так играть в CS:GO
не меньше 20 раз в секунду(как в Overwatch)

Здесь вообще очень много споров, чуть ли не самая популярная тема на форумах батлонета. Насколько мне известно, там не синхронный тикрейт, в духе 22 up, 60 down.
и поднимать его вплоть до 120 (как в CS:GO).

В csgo matchmaking тикрейт 64, в более адекватных местах 128.
там не синхронный тикрейт, в духе 22 up, 60 down.

Так оно и есть. Отсылаются команды в OverWatch 60 раз в секунду.
В том и дело что даже 20 FPS на сервере вместо 60 вызывает недовольство. Так что 10 скорее всего вызовут дичайшие взрывы протеста.

и поднимать его вплоть до 120 (как в CS:GO).
В csgo matchmaking тикрейт 64, в более адекватных местах 128.

Я решил «округлить» до 120 в целях сокращения информации. Хотя, признаться честно, я не умею с клиента отличать 128 FPS от 64.
Это можно сделать командой net_graph 1. Иногда 64 тика подводят, да, но даже на 64 нужен очень хороший пинг, не говоря уже о 128 тиков.
Я имел в виду что я не умею отличать как простой игрок)
Я не чувствую разницы между 64 и 128 апдейтов в секунду.
Это может быть из-за плохого монитора/слабого компьютера. Если сыграть на 250+ стабильных фпс на мониторе с 144Hz разница между 128 и 64 tick засмущается очень сильно.
Я бы посмотрел на тест двойным слепым методом, подтверждающим это утверждение.
это не работает таким образом. нужно иметь нормальную скорость реакции и чувствовать отклик.
на 64 абсолютно нормальной ситуацией является словить в голову, уже уйдя за угол, просто потому что другой клиент в данный момент еще видел последний пиксель хитбокса вашей головы и прожал в него.
на 128 сделать такое будет, очевидно, ровно в два раза труднее.
Боюсь, вы забыли про пинг. Враг видит вашу позицию в прошлом скорее потому что у одного из вас пинг большой, а не потому что обновления редкие. 60 кадров в секунду в худшем случае оставляют задержку в 16 мс.
А средний пинг, я боюсь, сильно выше этого значения. Представим что с вами играет человек с пингом 50, а у вас пинг 20.
Он видит вашу позицию за 50/2+16+20/2 мс назад, т.е за 51 мс. После того как он нажмет на выстрел, до вас сигнал будет идти еще 60/2+16+20/2. Я тут взял 16 за задержку сигнала на сервере, хотя среднее время ожидария будет 8 мс а не 16.
Так вот, при таком раскладе от смены частоты сервера вы выигрываете 16 мс из 102.
Когда я играл в Rust Exp, если противник бежал и я стрелял точно в него, то я не попадал, а потом я понял, что есть некая задержка, тогда я начал стрелять чуть-чуть наперед и стал точно попадать.
Спасибо вам, теперь я понимаю как это работает и почему так происходит.
Да, скорее всего банально нет механизма компенсации лагов.
250 фпс на 144 гц, говорите?
По поводу овервотча
Да, это замечательное видео и я его всем советую:)
Может кто-то готов будет сделать серию туториалов на NodeJS + Socket.io по этой теме?
Я бы с удовольствием почитал и поучился.
Описываемое в данной серии статей абсолютно не зависит от инструмента. Более того, это не так уж и сложно в реализации.
Ну, ничего страшного значит. Рано или поздно дорастете. :)
Начните делать прямо сейчас. Не успеете оглянуться как создадите тысячи строк кода, реализуете десятки разных алгоритмов… Сложнее всего начать, то-есть создать первую строчку кода. Потом уже не остановиться. Будете пилить все новые и новые фичи. Главное выберите то что Вам по силам. Из моего опыта — работая в небольшой студии, принял участие в разработке более пяти игр разных направлений. Все это время я не представлял как можно в одиночку и без финансирования создать игру. А потом получилось как то само собой.
Socket.io (да и вообще WebSockets) не очень подходят для «быстрых» игр сетевых. Гарантия доставки и последовательности TCP протокола дает ощутимые задержки если какой-то из пакетов по пути потеряется.
Еще и чертов http-handshake от которого волосы дыбом становятся.
Не знаете, может уже появилась возможность из браузера по средствам js достучаться до udp сокетов?
Теоретически, можно попробовать через WebRTC. Он работает ближе к UDP и в нем есть дата-канал, но, вроде бы, еще не во всех браузерах. У меня была мысль попробовать сделать демку, но готового клиента для WebRTC в ноде не нашел, а самому разбираться не было времени.
Все равно грустно это все.
WebRtc он же чуть более чем полностью заточен на передачу видео/аудио.
Скорее всего выйдет доработать напильником, что бы передавать, что хочешь, но вероятно много кровавых слез упадет пока все получится.
И еще больше потом при поддержке(

Вот не дает JS себя полюбить. Слишком много искусственных ограничений об которые сломаешь себе шею.
все это здорово насчет экстраполяции, а вот на практике как-то не получается…
вот к примеру, сервер тикает каждые 100мс
игрок тикает каждые 10мс(100 fps)
вот пришли мне данные что враг А двигается со скоростью 5метров в секунду.
я это экстраполирую до след. прихода пакета.
в идеальной вселенной время прихода между пакетами будет 100мс
в реальности будет задержка связанная как с сетью, так и с тем, что пакет не всегда приходит в начале кадра. он может придти сразу после попытки чтения из сети. вообщем в реальности разброс будет от 0 до 10-20 мс.
т.е. я для врага использую «старую скорость», потом приходит пакет с обновлением. я меняю позицию и происходит jittering.
как с этим справиться экстраполяцией я так и не смог :(
я пробовал и позицию менять постепенно, но там в итоге артефактов был вагон(визуальных в виде аномального изменения скорости)
в итоге сделал интерполяцию с буфером в 100мс. но экстраполяцию так и не поборол (
забыл дописать, что скорость объекта меняется. т.е. враг идет на форсаж
Признаюсь честно, я не писал экстраполяцию. Впрочем, до недавнего времени я и интерполяцию не писал:)
Я так понимаю, тут есть определенные пункты, которые необходимо выполнять:
  • Экстрополяцию последнего снапшота ведем пока не получим обновление от сервера
  • Обновленную модель от сервера получаем не сразу, а интерполируем между текущим результатом и новым результатом экстраполяции
  • Ну и конечно если у вас в игре есть вторая производная(ускорение), надо её учитывать и экстраполировать не только позицию, но и скорость

Вам вроде как остался только последний пункт. В идеале экстраполировать надо учитывая физическую машину модели. Т.е. считая что ввод врага константный, применяете его пока не получите обновление.
угу, я пробовал интерполировать текущий результат и полученный от сервер. артефактов было много всяких разных, в основном объект то замедлялся то резко ускорялся. такое меня не устроило
передавать скорость — да, в итоге я и пришел к этому но отказался по причине дополнительной передачи скорости в пакете(а игроков в кадре планировалось много).
в итоге сделал интерполяцию и остался доволен.
экстраполяция штука хитрая. много кто о ней знает, но мало кто ее делал. у кого бы я ни спрашивал)
Хотелось бы видеть реализацию данных методов на каком-либо языке, чтобы новичкам было проще понимать, как оно с точки зрения кода работает. За иллюстрации отдельное спасибо!

ЗЫ Так как работаю с Unity3D, то использую плагин(сервис) PhotonCloud для сети, в котором уже есть реализация данных алгоритмов. Вот такая реализация на C#: Смотреть на Pastebin
Мы писали на c#, собственно, тоже под юнити. Но код такого рода доводить до состояния, чтобы новичкам можно было сказать: «делайте так» — довольно долго. У нас была более простая задача — собрать рабочий прототип механик и осознать узкие места и проблемы мультиплеера.

Да, действительно описанное в данной статье есть у ФотонКлауда. И даже можно построить авторитарный сервер, правда запускаемый из-под юнити, хотя, как я понимаю, такое решение не поддерживается из коробки. И, на сколько я знаю, тема следующей статьи(компенсация лага) не поддерживается в Юнити.
Дело не в юнити и не в фотон клауде. Поэтому и упомянул вскользь, чтобы не заострять на этом внимание. Реализация алгоритма не сложная, нужно лишь складывать состояние объекта в очередь и обрабатывать при смене кадра игры + доп условия, это если про интерполяцию. Но тем, кому интересно, могут и по ссылке выше разобраться, не сложный код ведь.

По поводу авторитарного сервера — выбор каждого. Фотон клауд можно запустить и на своих серверах, и даже дописать свою логику, если разобраться с SDK. Для прототипа механики как раз и круто использовать что-то готовое, имхо много времени уходит на написание сетевого велосипеда. Хотя товарищ gnoblin и еще пару используют PhotonCloud на проде как сервис и живут как-то:)
Спасибо за интересные ссылки)
Пожалуйста.

Да простят меня хаброжители за ссылку на ВК, но полезным постом грех не поделиться — собрал все линки про сеть что имею в одно место.
Таким образом вы показываете настоящее передвижение врагов, но на 100 мс позже.
Так вот почему в Battlefield можно умереть, даже забежав за укрытие. В системе отсчёта противника я до него ещё не добежал.
Верно. Помните, что эти условные 100 мс складываются из:
  1. Задержки для интерполяции
  2. Пинга
  3. Времени ожидания апдейта сервера
А как это все будет работать при пингах клиента 150+ до сервера?
Смотрите в следующей статье)
Мне бы хотелось бы узнать не про классику «авторитарный сервер»-«множество клиентов», а про вариант, когда клиенты обмениваются игровыми данными напрямую и сами друг друга тестируют на читерство, а сервер просто собирает общую статистику.

Допустим, есть игровое поле, где одновременно несколько тысяч игроков. Главный сервер просто захлебнется при таком раскладе.

Будет ли?
всегда есть вариант подменить логику на двух машинах(а может и на одной но в разных инстансах клиента). да и потом если на игровом поле будут играть много клиентов, на ком лежит ответственность за проверку? может один читерит, а второй ему помогает? тогда каждому надо тестить всех остальных в кадре. это огромные тормоза на клиенте и лишняя логика в клиенте, которую можно подсмотреть. + если обнаружен факт читерства что делать? клиент отправляет серверу что мол «вот читер, ловите его». а если клиент врет? надо тестировать несколькими клиентами? а сколько нужно? а если вас на карте двое? а если данные противоречивы? очень много проблем возникает сходу. а в реале еще больше. в любом случае логика на клиенте это считай дал доступ к серверу. если интересует случаи когда игроков множество — надо смотреть scaling, разбитие карты по секторам и вынесение сектора на отдельный сервер.
Распределенная p2p-сеть между игроками — на первый взгляд эта система гораздо сложнее. Когда у нас есть наши сервера — мы знаем их производительность, сколько игроков может держать один сервер. В случае с распределенными клиентами — мы понятия не имеем, а достаточная ли производительность у клиента? могут ли все клиенты поддерживать заданный тикрейт? А что будет, если не могут? Замедлять всех клиентов до скорости самого медленного? Для тысячи игроков это не вариант

Можно разбивать большое поле с тысячей игроков на достаточное количество маленьких участков, за каждый из которых отвечает свой авторитарный сервер. Но в этом случае нужно учитывать переход игроков и игровых объектов между зонами влияния серверов.
>> Когда у нас есть наши сервера — мы знаем их производительность, сколько игроков может держать один сервер.

Именно. И у нас есть строгие и ясные ограничения на уровне нашего железа… И чем больше клиентов, тем выше нагрузки на мастер-узел сети. А когда серверные обязанности отданы клиентам, тогда чем больше клиентов, тем быстрее сеть.

>> А что будет, если не могут?

Либо клиент сам виноват, что играет по GPRSу, где лаг в три секунды нормален и тогда на эти три секунды его траектория просчитывается автоматом, при этом просчет должен осуществляться не этим клиентом, а как минимум тремя наиболее близкими по пингу, со взаимным контролем. Либо просто не пускать на общее поле…

>> достаточное количество маленьких участков, за каждый из которых отвечает свой авторитарный сервер.

где авторитарный сервер суть клиент с особыми полномочиями.

давно думаю над этой идеей, но пока лишь на уровне общих рассуждений, как вы привели,
Я бы посмотрел на эту идею в формате статьи, или, еще лучше, в формате демо версии:)
Интересная статья, спасибо. Было бы интересно почитать про потерю связи с сервером. К примеру отключился интернет или пинг стал в 10 раз больше. В этом случае данные на сервер и от него будут приходить с задержкой уже не в 100мс, а, например, в 1с. Другие игроки в этом случае будут видеть вас (например) бегущим куда-то далеко, хотя вы на клиенте указываете другое направление и тд
Как эту проблему можно более грамотно решить и после возобновления соединения правильно все обновить
Видел несколько реализаций
1) на тестовом сервере вова
приоритет сервера, вы отправляете на сервер чего хотите сделать сервер обрабатывает и отправляет обратно, никаких расхождений с тем что в клиенте 1 клиенте 2 и сервере.
но! полное ощущение погружения в желе, вы такает кнопку, а персонаж начинает двигаться через пинг туда + пинг обратно.
в случае обрыва хоть занажимайтесь, но никуда не сдвинетесь, весьма специфичное поведение при потере пакетов, вы можете залипнуть. А все будут бегать, почти никакой возможности почитарить вы отправляете только свои пожелания на сервер.

2)приоритет клиента, на релиз сервере вова — вы бежите у себя в клиенте, а на сервер отсылаются координаты, потом сервер отсылает другим игрокам, {экстра|интер}полированные данные, при больших пингах на отдачу лагающий игрок у нормальных начинает двигаться рывками, есть возможность почитарить,- в случае замеса — выдёргиваем кабель убегаем, потом втыкаем, а толпа в недоумении наблюдает как ваша тушка телепортировалась, есть конечно моменты которые требуют синхронизации с сервером но их мало. чем собственно и пользовались на 2 сезоне wod арены, сервер почти никак не проверяет полученную от клиента информацию.

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

Проблема конкретно этого сервера была в том, что удар моба стопорит ну пусть на 0,2 сек, а интервал между атаками 1 сек мой пинг грубо говоря 0,8 сек, удар моба остановил меня на 0,2 но так как клиент отправляет уже превышающие лимит доверия данные, то они не учитываются и я стою, и 0,8 +0,2=1 секунду ровно интервал тоесть не могу убежать от моба совсем, решается тем что сервер должен был отдёрнуть меня, но разрешить бежать дальше в данном направлении вместо этого я стою и огребаю.

Прошу заметить что это игры с таргетом(можно сказать автоприцелом), в которых только радиус и «столбы» сказываются на попадании, с нонтаргет играми приоритет сервера заканчивается тем что при лагах фиг попадёшь, а с приоритетом клиента фиг спрячешься ваш подвисший призрак у лагера будет ловить все пули, и вы сдохнете сидя за стенкой.
Конечно на каждое действие можно выставить свой приоритет, на вращение вокруг своей оси пускай будет приоритет клиента, на движение комбинированный, а на выстрел в голову приоритет сервера.
Спасибо за статью.
Вспоминается quake 3 и его чудный движок, в котором от фпс игрока зависела физика игрока. Это казалось какой-то магией, когда в Wolfenstein: Enemy Territory (сделана на id Tech 3) ты подходишь к ящику и не можешь на него запрыгнуть. Но стоит залочить фпс на 120 и чудо — запрыгиваешь без проблем. Это баг, и его починили, но интересно, почему это происходило. Сервер не проверял передвижение игрока и физика на клиенте зависела от фпс? Или тикрейт клиента был не ограничен, как в современных играх, и физика глючила уже на сервере?

А вообще, как мне кажется, высокий тикрейт важен для локальной сети. При игре через интернет пинг и лаги сведут всю точность расчёта сервера на нет.
Эти перестрелки во времени в своё время знатно раздражали, когда ты уже забежал за угол, а противник убивает тебя в прошлом, убивая и в будущем.
А если таким убийством не влиять на будущее, но засчитывать в очки? А реальное убийство только когда пуля убивает и в прошлом и в будущем — это когда противник бежал прямо на пулю или от него?
Ответьте себе на один вопрос: «Если бы вы выстрелили прямиком в голову врагу, а вам бы не засчитали убийство, вы бы решили, что это ок, или что игра забагована?»

Я боюсь, что если вы и столь разумны, что способны это принять, большинство игроков — нет. Да и на баланс это плохо повлияет.

Задача разработчиков — дать максимальную иллюзию реальности. И максимально честные условия соревнования. Если ты прицелился в голову врагу и выстрелил, он должен умереть, т.к. иначе для игрока это будет выглядеть как баг.
Успел за угол, но всё равно умер — это максимальная иллюзия реальности?
Я ж написал «засчитывать очки». Например, показывать очки «за ранение головы». Выше уже написали, что игрок просто привык стрелять перед бегущим противником и ничего.
Кстати, вроде бы в первых двух Батлфронтах подобное было из-за того, что во вселенной ЗВ энергозалпы летят относительно медленно.
Для стрелка это максимально реалистично. Лагокомпенсация применяется НЕ ТОЛЬКО когда враг забегает за угол. Большую часть времени игроки видят друг друга когда стреляют. И именно для этого и существует компенсация лага. Но этот неприятный случай — побочный эффект.
Без этого механизма чтобы убить человека, который бежит перпендикулярно направлению выстрела, надо стрелять на опережение.

А это удар по всему геймплею, а не частности в виде забегания за угол.
на практике игрок обычно приспосабливается к пингу и может стрелять на упреждение(проверял это на себе), если конечно пинг не совсем жесткий. но компенсация для пользователя конечно удобнее, главное соблюдать компромисс, чтоб давая возможность одним, не ущемлять при этом других игроков…
Если бы пинг был константым, я бы мог с вами согласиться. Но это уже давно обсужденная проблема благодаря Quake 3.
http://www.ra.is/unlagged/
«I don't have the most evil of Internet connections, but it really is sporadic sometimes. It's not unusual for my ping to fluctuate between 100 and 150, which does terrible things to my rail aim»
«У меня далеко не худший интернет, но иногда связь может дергаться. Мой пинг регулярно скачет между 100 и 150, что приводи к ужасным результатам для точности моего рейлгана»

Возможно для вас это и работает, потому что у вас стабильный и возможно небольшой пинг. А еще скорее всего потому что вы стреляете из оружия с большой частотой выстрелов. А вот со снайперской винтовкой было бы сложнее, т.к. с ней важнее не промазать в данный конкретный момент.
Имел опыт создания мультиплеерной игры. Как раз и использовал то что описано в статье, но по большей части дошёл до этого методом проб и ошибок. К примеру, пули имели направление, которое они не меняют и скорость, которая не меняется, так что тут экстраполяция пошла на ура. С движениями игроков не прошло, хоть они двигались и не так бысто как в некоторых играх, экстраполирование глючило при резких сменах направления движения и пришлось использовать интерполяцию по прошлым положениям, как и описано тут.
Оставалась большая проблема, при попадании пули в игрока игрок видел «взрыв» этой пули за своей спиной, что сильно портило общее впечатление. Всё решилось довольно простым хаком, взрыв был привязан к позиции игрока и иллюзия сложилась в довольно целостную картину.
А игроков с малым пингом старались отсеевать ещё до подключения к игре, в т.н. «комнате» и они играли с ботами, не подозревая об этом.
Хотя это и стоило нам многих негативных отзывов, когда люди замечали подмену.
А игроков с малым пингом старались отсеивать ещё до подключения к игре, в т.н. «комнате» и они играли с ботами, не подозревая об этом.

Я так понимаю, игроков с высоким пингом?
Сижу и смеюсь:D Жесткое решение:)

Да, эти правила писаны кровью)
Да, имел в виду с высоким, спешка :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории