Комментарии 21
Играл с самого начала ЗБТ.
Очень интересно побывать на «кухне» игры, спасибо :)
Очень интересно побывать на «кухне» игры, спасибо :)
+5
Интересная статья!
P.S.
А будут ли еще статьи про графику?
P.S.
А будут ли еще статьи про графику?
+4
Спасибо!
У нас нет каких-то планов по написанию статей. Захотел — написал. Попросили — написал. Поэтому я не обладаю никакой инсайдерской информацией на эту тему. Поэтому только SergeyMakeev знает, будет он еще писать или нет.
У нас нет каких-то планов по написанию статей. Захотел — написал. Попросили — написал. Поэтому я не обладаю никакой инсайдерской информацией на эту тему. Поэтому только SergeyMakeev знает, будет он еще писать или нет.
+1
> На самом деле было сразу несколько причин ошибок 107:
> — слишком хорошее сетевое подключение и быстрый клиент (пинг < 3 мс);
Посмеялся. Как это вообще так? Я в упор не представляю, как от слишком хорошего подключения мог оказаться превышен таймаут.
> — слишком хорошее сетевое подключение и быстрый клиент (пинг < 3 мс);
Посмеялся. Как это вообще так? Я в упор не представляю, как от слишком хорошего подключения мог оказаться превышен таймаут.
+1
Это баг, вызванный гонкой состояний в масштабах клиента и сервера. Представьте, что клиент посылает две команды, при этом клиент ожидает, что после первой команды сетевой поток, его обслуживающий, успел переключиться в нужный для второй команды режим. Но при хорошем подключении две команды идут так быстро, что сервер не поспевает. И получает второе сообщение в невалидном состоянии. Лечится, как правило, путём добавления сообщения-ответа в духе «состояние переключил — давай следующее сообщение».
+1
Ошибка на уровне протокола, нехорошо как-то.
+2
Да, протокол входа в игру был не очень надежен. Именно для того, чтобы находить такие баги, и были заведены таймауты. Если мы в стейт-машине входа в игру не переходим из одного состояния в другое слишком долго, то оповещаем об этом игрока и «выходим».
Старый «движок» входа в игру понравился бы вам еще меньше, поэтому мы его и переписали, добавив диагностики и таймаутов. Раньше можно было застрять в каком-то состоянии навсегда.
Старый «движок» входа в игру понравился бы вам еще меньше, поэтому мы его и переписали, добавив диагностики и таймаутов. Раньше можно было застрять в каком-то состоянии навсегда.
+2
Может вы ещё и производительность клиента намерянно снижаете и пинги удлинняете?) В skyforge вообще интересно обстоят дела с пингом. Все сервера (которые попросила пропинговать тех. поддержка) пингуются в 26мс, в игре наблюдаю от 35 до 100. Может счётчик врёт, потому, что лаги можно наблюдать при любом значении пинга. Ну и странно видеть увеличение пинга при проседании ФПСа.
+1
Пинг, который вы видите в игре — это не то же самое, что результат выполнения команды ping. Это сериализация + отправка + пересылка + прием + десереализация сообщения. Я сейчас посмотрел график латенси с идущего прямо сейчас стресс-теста:
95 перцентиль — ~110 мс.
90 перцентиль — ~86 мс.
80 перцентиль — ~60 мс.
70 перцентиль — ~ 43 мс.
50 перцентиль — ~ 23 мс.
И так далее. Т.е. в принципе, ваши ощущения верны. У значительного числа пользователей разброс от 35 до 100.
Так же верны ваши наблюдения, что при падении ФПС падает пинг — мы работаем медленнее, медленнее отправляет и принимаем сообщения.
Наши механики отлично должны себя чувствовать до 300мс. У нас есть различные механизмы компенсации пинга, чтобы бой смотрел и игрался хорошо.
95 перцентиль — ~110 мс.
90 перцентиль — ~86 мс.
80 перцентиль — ~60 мс.
70 перцентиль — ~ 43 мс.
50 перцентиль — ~ 23 мс.
И так далее. Т.е. в принципе, ваши ощущения верны. У значительного числа пользователей разброс от 35 до 100.
Так же верны ваши наблюдения, что при падении ФПС падает пинг — мы работаем медленнее, медленнее отправляет и принимаем сообщения.
Наши механики отлично должны себя чувствовать до 300мс. У нас есть различные механизмы компенсации пинга, чтобы бой смотрел и игрался хорошо.
+1
Тогда в вашей архитектуре фатальный недостаток. То, что ФПС и пинг держится на приемлемом уровне 99% времени — это ничто по сравнеию с оставшимся процентом, который случается всегда ВНЕЗАПНО и в критических моментах приводит к фатальным последствиям. Телепортируешься(скилом) уже мёртвым, ульта срабатывает после смерти, мобы убивают последним хитом, после того как они были сами убиты. Не вижу никакой предсказуемой связи между отображением и работой механики, либо она не работает как задумывалось.
На примере паладина — это приводит к тому самому эффекту метронома, о котором писалось в одной из ваших предыдущих публикациях. Я не могу ориентироваться на картинку на экране, т.к. вижу рваный ритм СКАЧУЩЕГО «пинга» и мне приходится самому быть механизмом его компенсации.
Если честно, не очень понимаю, как связана графика и механика. Почему «пинг» не сокращается и скачет, когда ФПС высокий, т.е. всё успевает отрабатываться с высокой скоростью и в игре в данный момент ничего не происходит, т.е. я стою один в пустом инстансе и просто кручу камеру?
Пока что я вижу приоритет графики над здравым смыслом и пингом. А пока игра для топовых конфигураций и толстых каналов. Но так как она мне понравилась, я мирюсь с этими косяками и надеюсь вы успешно победите все эти косяки и отполируете шероховатости.
На примере паладина — это приводит к тому самому эффекту метронома, о котором писалось в одной из ваших предыдущих публикациях. Я не могу ориентироваться на картинку на экране, т.к. вижу рваный ритм СКАЧУЩЕГО «пинга» и мне приходится самому быть механизмом его компенсации.
Если честно, не очень понимаю, как связана графика и механика. Почему «пинг» не сокращается и скачет, когда ФПС высокий, т.е. всё успевает отрабатываться с высокой скоростью и в игре в данный момент ничего не происходит, т.е. я стою один в пустом инстансе и просто кручу камеру?
Пока что я вижу приоритет графики над здравым смыслом и пингом. А пока игра для топовых конфигураций и толстых каналов. Но так как она мне понравилась, я мирюсь с этими косяками и надеюсь вы успешно победите все эти косяки и отполируете шероховатости.
+1
Мы могли бы показывать игроку пинг до нашего датацентра, на который мы никак повлиять не можем. Тогда бы он был стабильный и не вызывал вопросов. Но это было бы ложное ощущение, т.к. качество обслуживания могло не соответствовать указанному значения. Мы же показываем «честный пинг»: реальную задержку между применением команды и получением результата. Это тот параметр, над улучшением которого мы можем работать.
Как я писал выше, значение «пинга» — это сумма нескольких слагаемых. FPS, а точнее производительность клиента, может влиять только на сериализацию. Поэтому можно легко загнать один из слагаемых в гору, значительно увеличив сумму, но, уменьшив его до минимума, не получить явной выгоды, т.к. остальные слагаемые никуда не делись.
Кстати, на днях мы заметили, что включенный в фоновом режиме uTorrent может задирать «пинг» до 4к. Правда, пока мы не знаем точных причин.
А вот эти все проблемы могут быть как связаны с пингом, так и быть отдельными. Например, сервер честно прислал сообщение клиенту и уже отработал его, но рендер не успел показать, что аватар умер. Или интерфейс послал команду с запозданием. Я понимаю, что вам, как конечному пользователю не очень интересна причина бага. Просто хочу объяснить, что не «пингом» единым.
Спасибо за добрый отзыв.
Почему «пинг» не сокращается
Как я писал выше, значение «пинга» — это сумма нескольких слагаемых. FPS, а точнее производительность клиента, может влиять только на сериализацию. Поэтому можно легко загнать один из слагаемых в гору, значительно увеличив сумму, но, уменьшив его до минимума, не получить явной выгоды, т.к. остальные слагаемые никуда не делись.
Кстати, на днях мы заметили, что включенный в фоновом режиме uTorrent может задирать «пинг» до 4к. Правда, пока мы не знаем точных причин.
Телепортируешься(скилом) уже мёртвым, ульта срабатывает после смерти, мобы убивают последним хитом, после того как они были сами убиты.
А вот эти все проблемы могут быть как связаны с пингом, так и быть отдельными. Например, сервер честно прислал сообщение клиенту и уже отработал его, но рендер не успел показать, что аватар умер. Или интерфейс послал команду с запозданием. Я понимаю, что вам, как конечному пользователю не очень интересна причина бага. Просто хочу объяснить, что не «пингом» единым.
я мирюсь с этими косяками и надеюсь вы успешно победите все эти косяки и отполируете шероховатости
Спасибо за добрый отзыв.
+1
Кстати, на днях мы заметили, что включенный в фоновом режиме uTorrent может задирать «пинг» до 4к. Правда, пока мы не знаем точных причин.
Кстати, случайно обнаружил пару сотен подключений у игрового центра, хотя раздача после скачивания в настройках отключена. Может он тоже подобным образом свою лепту может вносить?
+2
Симптомы похожи на гонку состояний, да, но ваш ответ как будто бы о чем-то другом. Пусть пакет доходит от клиента к серверу аж за 500 мс — все равно обе команды дойдут до сервера за одно и то же время, разве нет? Единственная ситуация, в которой это будет не так — нестабильный пинг, тогда первая команда дойдет за 50 мс, а вторая уже за 55 мс, скажем. При этом в статье сказано, что нестабильный пинг тоже к таймауту приводит, хотя как раз при нестабильном пинге эта гонка и не должна возникать…
+1
Как это было:
Если (t2 + dt) > t1, то всё было хорошо. Иначе сообщение_2 приходило в момент, когда его никто не мог корректно обработать.
Это был самый первый баг ошибки 107, которому были подвержены пользователи с маленьким пингом и быстрым клиентом.
- Клиент отправляет сообщение_1
- Сообщение_1 доходит за время t0
- Сервер получает сообщение_1 и переключает состояние сетевого подключения за t1
- Спустя dt после отправки сообщения_1 клиент отправляет сообщение_2
- Сообщение_2 доходит за время t2
Если (t2 + dt) > t1, то всё было хорошо. Иначе сообщение_2 приходило в момент, когда его никто не мог корректно обработать.
Это был самый первый баг ошибки 107, которому были подвержены пользователи с маленьким пингом и быстрым клиентом.
+2
А пофиксить пытались на скорую руку добавив задержку? И это привело к проблемам у пользователей с медленным соединением?
+1
Нет, конечно. Мы не чиним race condition добавлением sleep. Мы так только дебажимся :) Хотя в данном случае, sleep отработал бы лучше.
Мы добавили сообщение-уведомление для сервера, что клиент посылает следующее сообщение в новом состоянии. Чтобы сервер явно переключил сетевое соединение в нужное нам состояние. Проблема была в том, что на медленных соединениях TCP любезно склеивал пакеты «переключи состояние» и следующее сообщение, и они приходили в рамках одного тика сервера. Сервер же не мог отработать в рамках одного состояния два сообщения, предназначенные для двух разных состояний. Но я согласен, что фиксили на скорую руку. Потому что не предусмотрели все варианты развития событий. Простым добавлением в клиент ожидания подтверждения от сервера о переходе в нужное состояние удалось пофиксить таймаут в этом месте еще раз.
Мы добавили сообщение-уведомление для сервера, что клиент посылает следующее сообщение в новом состоянии. Чтобы сервер явно переключил сетевое соединение в нужное нам состояние. Проблема была в том, что на медленных соединениях TCP любезно склеивал пакеты «переключи состояние» и следующее сообщение, и они приходили в рамках одного тика сервера. Сервер же не мог отработать в рамках одного состояния два сообщения, предназначенные для двух разных состояний. Но я согласен, что фиксили на скорую руку. Потому что не предусмотрели все варианты развития событий. Простым добавлением в клиент ожидания подтверждения от сервера о переходе в нужное состояние удалось пофиксить таймаут в этом месте еще раз.
+2
Что мешает серверу не обрабатывать команду 2, пока команда 1 не отработала и не переключила стейт-машину в нужное состояние? Команда 2 может спокойно подождать в очереди.
+1
Серверу, чтобы понять, какая команда что значит, нужно сперва превратить поток байтов во что-то вразумительное. Проблема в том, что для команды 1 и для команды 2 нужны разные способы десериализации. Т.е. команду 2 мы пытаемся десериализовать неправильным способом и получает какую-то фигню вместо команды. Поэтому мы не можем понять, что это была команда 2.
+1
Даже если так, можно складывать в очередь команду в виде массива байтов и парсить опять же после переключения стейта в результате выполнения 1-й команды. Но вообще звучит как ужасный дизайн протокола, сложно представить разумную причину для такого решения — можете пояснить для чего так сделано?
0
Зачем делать очередь? Можно просто добавить пару-тройку сообщение для того, чтобы строго определить, кто и когда переключил стейт. Да, это понизит скорость подключения на пару пингов до сервера и обратно, но это копейки по сравнению с загрузкой сцены. То, что такой синхронизации не было изначально — просто баг. А не злое намерение или преждевременная оптимизация. Код отлично работал несколько месяцев, в том числе в нагрузочных теста, пока не оказался на боевых.
К сожалению, я не понял, что именно вы считаете «ужасным дизайном протокола»?
Разделение всех сообщений от клиента на две группы? Условно их можно назвать «до того, как игрок вошел в мир» и «после того, как игрок оказался в мире». И, скажем так, для них действуют разные контракты.
К сожалению, я не понял, что именно вы считаете «ужасным дизайном протокола»?
Разделение всех сообщений от клиента на две группы? Условно их можно назвать «до того, как игрок вошел в мир» и «после того, как игрок оказался в мире». И, скажем так, для них действуют разные контракты.
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
За кулисами закрытого бета-тестирования Skyforge