SK | bds, он же Andreas Thorstensson, в декабре 2001 года черкнул занимательную статью, целью которой было пояснить банальные, но в то же время важные команды сетевого кода. Само собой, без мельчайших подробностей. И вот, спустя год, вышло продолжение этого знаменитого и сто раз перечитанного креатива, который в свое время породил массу кривотолков и термины “config-hacks”, “interp-cheater”. Итак, приступим.
К рассмотрению предлагается феномен “удушья” сервера (он же лаг сервера), от которого и зависят параметры большинства сетевых переменных.
“Удушье” – задержка до времени возможной посылки следующего пакета информации, которое определяется так: (Время посылки)=(Данное время)+ 1 / (значение cl_updaterate). (проще говоря, временное снижение FPS)
То есть, если играть с высоким значением cl_updaterate, то можно заиметь частые лаги, коль пропускная способность канала связи с сервером невелика. При наличии большого количества игроков на фоне низкой пропускной способности канала тоже будет лагать (так как посылается больше информации, а значит, и пакетов). И, наконец, лагать может при низком значении cl_updaterate. Если срабатывает эффект “удушья”, то сервер пытается послать пакет клиенту (читайте – игроку) через каждый кадр, нежели ожидать очереди на посылку в момент, наступающий каждые (1/cl_updaterate) секунд, пока не пройдет эффект.
Интерполяция.
Это уже метод движка Half-Life для сохранения позиций игроков, связывая их со временем, в оперативной памяти (да-да, это численные методы :)). Затем, после сохранения, движок использует переменную ex_correct для анализа архива на предмет нахождения двух наиболее подходящих позиций, куда “поставить” игрока, то есть игрок перемещается с такой же скоростью, как и на сервере, независимо от используемого значения ex_interp (которое приравнивается к 1/cl_updaterate или большему значению). Единственный случай, когда игрок может пройти быстре дефолтной скорости – это после значительной потери пакетов, идущих клиенту, после длительного лага, когда игрок принудительно ставится в нужную позицию, соответствующую данным на сервере, как можно быстрее.
А теперь уже идут команды и переменные…
Собственно, дефолтные значения этих переменных малы лишь из-за прихоти “игра должна идти нормально под любым видом соединения, в том числе и по Интернету”. Вторая причина состоит в особенности HLDS, для которого предусмотрены возможность работать на маломощных машинах и несоздание чрезмерной загрузки процессора. Напомним, что cl_updaterate и cl_cmdrate контролируют траффик от клиента к серверу и обратно, причем чем больше значения этих переменных, тем больше траффик.
Хотя использование больших значений имеет такую неприятную особенность, как эффект “удушья”, который происходит при невозможности пропихнуть весь траффик через канал клиента, а так же увеличивается нагрузка на сервер, которому приходится чаще обмениваться информацией и делать больше расчетов, что, несомненно, загружает процессор сервера и может вызвать лаг на сервере. Естественно, при игре по LAN можно не особо мучаться совестью и ставить немаленькие значения, благо, канал позволяет. 🙂
Однозначно самая мистическая и обсуждаемая переменная. Наиболее подходящее для нее значение – это 0.1 , которое стоит по умолчанию. Именно такое значение дает наименьший эффект от небольшого бага, который влиял на ход интерполяции на клиенте и, конечно, на результат, отсылаемый на сервер. Однако, следует учесть, что значение ex_interp можно менять, в отличие от большинства ex_переменных. Рекомендуется поставить значение равным (1/cl_updaterate), так как в этом случае (при отсутствии мини-ЧП в виде лагов или потери пакетов) клиент будет получать обновленную информацию как раз после окончания интерполяции и игроки, объекты будут двигаться плавно, без перерывов. Но учтите, что для полного эффекта нужен достаточно быстрый сервер, который способен посылать (cl_updaterate) пакетов в секунду!
После того, как CPL (и прочие ей подобные конторы) изменили свои правила сетевых настроек, предписывая ставить бОльшие значения, нежели дефолтные, для cl_updaterate и cl_cmdrate, то было замечено возрастание количества лагов на играх по LAN. А все из-за того, что HLDS в “sv_lan 1”-режиме насильно ставит rate=10000 на каждом клиенте, тем самым облегчая участь ламеров, не занимающихся настройкой. 🙂 Однако следует учесть, что значения выше 20000 просто не будут приняты.
Экстраполяция – это то, для чего и делается интерполяция. 🙂 Если клиент не получает информацию о конечной позиции интерполяции (например, при потере пакетов), то движок экстраполирует из интерполяционной функции свою позицию (куда и попадает игрок), как бы “предсказывая” ее. Значение сией переменной суть максимальное время, которое отводится на экстраполяцию позиции игрока (читай – насколько далеко можно уйти без поддержки сервера), причем при превышении лимита времени игрок просто никуда не уйдет, оставшись на последней вычисленной позиции. Эта переменная не изменяется.
Еще один из путей описания интерполяции клиента и “предсказаний”. И эта переменная неизменна. 🙂
Если бы ex_correct равнялась 1, то этой переменной можно было бы изменить радиус, в котором бы игрок двигался равномерно от позиции Х в позицию У (как бы минимальный шаг) за время интерполяции, причем при выходе за радиус происходит телепортация в конечное положение (на границу окружности с этим самым радиусом). Увы, ex_correct не изменяет своему серверу, а с ней и ex_maxerrordistance.
А эта переменная описывает framerate сервера. Чем больше она, тем больше пакетов можно отсыласть клиентам (если проц позволит :)).
Этот параметр указывает максимальную частоту обновления сервера; чем больше частота, тем больше пакетов можно закидывать клиентам.
И пара слов на закуску… Все параметры, по большому счету, зависят от мощности компьютера и пропускной способности канала связи с сервером, причем учтите, что даже при невысоких значениях переменных движок вполне способен нормально обрабатывать информацию! А в хороших условиях (читайте – при игре по LAN) можно даже и побольше поставить, лишь бы сеть позволяла 🙂
Удачи!
(c)Andreas “SK|bds” Thorstensson, translated by BeReZa.