- Главная страница /
- Форум /
- Статьи и инструкции /
- Сетевое программирование в Source (полный guide от VALVE)
4 февраля 2020 г, 14:04
|
|
![]() Создатель Рейтинг: 67 Сообщений: 22 Спасибок: 9 |
1.Обзор Многопользовательские игры на движке Source используют архитектуру Клиент/Сервер. Обычно Сервер - это выделенная машина, на которой запущена игра и которая диктует симуляцию игрового мира, правила игры и результаты обработки действий игрока. Клиент - это компьютер игрока, подключенный к игровому серверу. Клиент и сервер общаются между собой путем частой посылки небольших пакетов с данными (обычно 20-30 пакетов в секунду). Клиент получает текущее состояние игрового мира от сервера и на основе этих данных генерирует картинку и звук. Клиент также получает данные с устройств ввода (клавиатура, мышь, микрофон и т.д.) и отправляет эти данные на сервер для последующей обработки. Клиенты общаются только с сервером, но не между собой (в отличие от приложений с архитектурой peer-to-peer). В отличие от однопользовательских игр, многопользовательским требуется решать широкий спектр проблем, связанных с общением на базе передачи пакетов данных. В силу того, что пропускная способность сети ограничена, сервер не может посылать пакет с обновлением всем клиентам каждый раз, когда в игровом мире происходит изменение. Вместо этого, сервер делает моментальные снимки состояния игрового мира через равные промежутки времени и передает эти снимки клиентам. На доставку пакета с данными от сервера к клиенту и обратно требуется определенное время (ping). Это означает, что время на клиенте всегда немного отстает от времени сервера. Более того, команды ввода с клиента тоже должны дойти до сервера, так что сервер тоже обрабатывает пользовательские действия с задержкой. В добавок, время прохождения пакета у каждого клиента отличается в зависимости от типа соединения, фонового трафика и частоты обновлений. Эти разницы во времени между сервером и клиентом порождают различные логические проблемы, которые становятся еще серьезнее при возрастании пинга. В боевиках с быстрым геймплеем даже миллисекундные задержки могут вызвать ощущение лага и значительно затруднить взаимодействие и попадание по движущимся объектам. Помимо ограничений, накладываемых пропускной способностью и пингом, проблемы может вызывать еще и потеря пакетов. Сервер симулирует игровой мир в дискретные промежутки времени, названные "тик" (tick). По умолчанию используется 66 тиков в секунду, однако моды могут использовать свою собственную частоту тиков. Например в Counter-Strike: Source используется частота 66 тиков в секунду. Во время каждого тика сервер обрабатывает пользовательские команды, симулирует физику, проверяет правила игры и обновляет состояние объектов игрового мира. После завершения симуляции тика, сервер определяет каким клиентам требуется обновление и делает снимок состояния мира, если это необходимо. Более высокая частота тиков увеличивает точность симуляции, но требует больших ресурсов процессора и пропускной способности как на сервере, так и на клиенте. Администратор сервера может установить значение частоты тиков с помощью параметра Пропускная способность клиента обычно ограничена. В худших случаях, игрок с модемным соединением может принимать не более 5-7 Кб/сек. Если бы сервер попытался отсылать ему обновления с большей частотой, то потеря пакетов стала бы неизбежной. Поэтому, клиент должен сообщить серверу о доступной входящей пропускной способности с помощью консольной переменной Клиент создает пользовательские команды опрашивая устройства ввода с той же частотой, с которой работает сервер. Пользовательская команда - это попросту говоря, снимок текущего состояния клавиатуры и мыши. Но вместо отправки на сервер нового пакета на каждую пользовательскую команду, клиент шлет обновления с определенной частотой в секунду (обычно 30). Это значит, что две или более команд передаются в каждом пакете. Игрок может увеличить частоту отправляемых пакетов с помощью команды Для уменьшения нагрузки на сеть используется так называемая дельта-компрессия. Это значит, что сервер посылает не полный снимок, а разницу между текущим и последним подтвержденным клиентом снимками (дельта-снимок). С каждым пакетом, передаваемым между сервером и клиентом, передаются данные о подтверждении приема, чтобы отслеживать непрерывность потока. Обычно полные снимки состояния мира передаются только в начале игры или в случае, когда клиент страдает от сильной потери пакетов в течении нескольких секунд. Клиент может запросить полное обновление вручную с помощью команды Время реакции, то есть время, проходящее между совершением пользователем определенного действия и отражением этого действия в игровом мире, зависит от многих факторов, включая загрузку процессора на клиенте и сервере, частоте тиков, скорости передачи данных, настройках обновлений, но больше всего от времени прохождения пакета по сети. Время, проходящее между отправкой клиентом пользовательской команды и реакцией на нее окружающего мира, называется задержкой или пингом (latency или ping). Низкий пинг является серьезным преимуществом в онлайновой многопользовательской игре. Такие вещи, как предсказание и лаго-компенсация направлены на то, чтобы минимизировать это преимущество и дать возможность игрокам с медленным соединением играть на равных с остальными. Настройка сетевых переменных также помогает улучшить производительность при условии достаточной производительности процессора и пропускной способности. Мы рекомендуем придерживаться стандартных значений, так как некорректные настройки могут привести с негативным эффектам вместо пользы. Последний снимок был получен клиентом на тике 344 или на позиции 10.30 секунд. Клиент продолжает отсчитывать время основываясь на этом снимке. Новый видео кадр же рендерится во времени, равном текущему времени клиента минус задержка интерполяции (10.32 - 0.1). В нашем примере это время составит 10.22 секунды и все объекты и анимация интерполируются между корректными снимками 340 и 342. Учитывая, что задержка интерполяции у нас составляет 100 миллисекунд, мы получили бы реальное отражение мира даже в случае, если бы снимок 342 был недоступен из-за потери пакетов. В этом случае интерполяция использовала бы снимки 340 и 344. При потере более чем одного снимка подряд интерполяция будет работать некорректно по причине отсутствия достаточного количества снимков в буфере. В этом случае используется экстраполяция ( Интерполяция вызывает непрерывную задержку отображения в 100 миллисекунд даже, если вы играете на невыделенном сервере (сервер и клиент расположены на одном и том же компьютере и сервер запущен прямо из игры). Так что если вы включите команду
4.Предсказание ввода Давайте предположим, что пинг игрока составляет 100 миллисекунд и игрок начинает движение вперед. Информация о нажатии кнопки Задержка между нажатием кнопки и его визуальным отображением создает странное, неестественное чувство, в результате которого очень сложно двигаться и стрелять точно. Для устранения этой задержки и обеспечения игроку возможности ощущать изменения мгновенно используется предсказание ввода ( Через 100 миллисекунд клиент получит от сервера снимок игрового мира, содержащий изменения, основанные на пользовательской команде, предсказанной ранее. Клиент сравнивает данные сервера с результатами предсказания. Если они различаются, происходит ошибка предсказания. Это означает, что у клиента не было корректной информации об окружающих объектах, чтобы произвести корректное предсказание, или же что пользовательская команда не была доставлена в результате потери пакетов. В этом случает клиент корректирует позицию игрока, так как информация сервера является решающей по отношению к клиенту. Если включена команда Предсказание поведения объектов может работать только если клиент знает те же правила и состояния объектов, что и сервер. Обычно это не так, т.к. серверу известна полная информация о всех клиентах и объектах, в то время как отдельный клиент видит только ту часть игрового мира, которая необходима для корректного рендеринга. В результате, предсказание ввода действует только для самого игрока и оружия, которое он использует. Точное предсказание других игроков и интерактивных объектов на клиенте невозможно. Система лаго-компенсации хранит историю всех недавних позиций игроков на промежутке времени примерно в одну секунду (это можно изменить переменной Время исполнения команды = Текущее время сервера - Пинг клиента - Задержка интерполяции клиента
Этот скриншот был снят на невыделенном сервере с задержкой 200 миллисекунд (используя команду Возникает закономерный вопрос: почему регистрация попаданий на сервере так сложна? Зачем разбираться с откатами в прошлое для выяснения позиций игроков и проблемами с точностью если все это можно обработать на клиенте без проблем и с точностью до пикселя. Клиент же мог бы просто посылать серверу сообщение о попадании. Этого мы позволить не можем просто потому, что сервер не может доверять клиенту в столь ответственных решениях. Даже если сам клиент чист и защищен VAC (Valve Anti-Cheat), пакет с данными можно модифицировать с помощью 3-й машины по пути до сервера. Подобные "cheat прокси" могли бы вставлять сообщения о попадании в пакет минуя защиту VAC. Задержки сети и лаго-компенсация порождают парадоксы, выглядящие алогично в реальном мире. Например, в вас может попасть противник, которого вы уже даже не можете видеть, потому что вы уже скрылись в укрытии. Это случается потому, что сервер передвинул вас в прошлое на позицию, где вы были еще видимы. Подобные несоответствия не могут быть решены из-за относительно невысокой скорости передачи пакетов. В реальном мире вы не замечаете подобных проблем потому, что свет ("пакет с информацией") путешествует столь быстро, что все вокруг видят мир таким же, как и вы в данный момент. В Source существует несколько инструментов, позволяющих проверить скорость и качество соединения клиента. Самый популярный из них - это net graph, который можно включить командой Под графической частью первая строка сообщает количество отрисовываемых кадров в секунду, среднюю задержку и текущее значение Источник: VALVE Отредактировал: Sleep, 5 февраля 2020 г, 10:45 |
Тема: Бесплатное AWP
Дата: 15 февраля 2020 г, 01:57
Дата: 15 февраля 2020 г, 01:38
Дата: 15 февраля 2020 г, 00:27