Ru/Prediction: Difference between revisions

From Valve Developer Community
< Ru
Jump to navigation Jump to search
No edit summary
No edit summary
Line 17: Line 17:
===Передача по сети через таблицы данных===
===Передача по сети через таблицы данных===


Хорошее место для начала рассмотреть код оружия. Если у вас есть установленный исходный код, вы можете посмотреть файл <code>src\game_shared\basecombatweapon_shared.cpp</code>. Там, вы можете увидеть блоки '''#ifdef CLIENT_DLL''' и '''#ifdef GAME_DLL'''. Это для разделения какой код компилируется в клиентской DLL и какой в компилируется в серверной DLL. Приведенный ниже (сокращенный) код соответствует шагу 2 описанной выше последовательности (помещает переменные измененные общим кодом в [[Networking Entities|таблицу данных]]).
Хорошим примером будет рассмотреть код оружия. Если у вас есть установленный исходный код, вы можете посмотреть файл <code>src\game_shared\basecombatweapon_shared.cpp</code>. Там, вы можете увидеть блоки '''#ifdef CLIENT_DLL''' и '''#ifdef GAME_DLL'''. Они определяют, какой код компилируется в клиентскую DLL, а какой в серверную. Приведенный ниже (сокращенный) код соответствует шагу 2 описанной выше последовательности (помещает переменные измененные общим кодом в [[Networking Entities|таблицу данных]]).


<pre>
<pre>
Line 33: Line 33:
===Создание таблицы предсказаний===
===Создание таблицы предсказаний===


Таблица предсказаний описывает данные в вашей энтити которые должны быть одинаковые на клиенте и сервере когда клиент спекулятивно имитирует комманду. Это список переменных котрые передаются по сети и их типы. Если значение допустимое к отклонению от серверного (как в случае с значением с плавающе запятой которое передается с урезанным количеством бит), то вы можите указать на сколько допустимо отклонение. В коде приведенном ниже, это выполняется макросом <code>DEFINE_PRED_FIELD_TOL</code>.
Таблица предсказаний описывает данные в вашей энтити, которые должны быть одинаковыми на клиенте и сервере когда клиент спекулятивно имитирует команду. Это список переменных, которые передаются по сети и их типы. Если для значения допускается отклонению от серверного (как в случае с значением с плавающей запятой, которое передается с урезанным количеством бит), то вы можете указать, на сколько допустимо это отклонение. В коде приведенном ниже, это выполняется макросом <code>DEFINE_PRED_FIELD_TOL</code>.


{{note:ru|Таблица предсказаний только непременно нужна в клиентской DLL, так вы можете ограничте код при помощи '''#ifdef CLIENT_DLL'''.}}
{{note:ru|Таблица предсказаний непременно нужна только в клиентской DLL, так вы можете ограничить код при помощи '''#ifdef CLIENT_DLL'''.}}


<pre>
<pre>
Line 49: Line 49:
==Консольные комманды==
==Консольные комманды==


Если вы добавляете функциональность к оружию и забываете выполнить шаги описанные выше, энтитя может сопровождаться рывками и страностями с анимацией. Вы можете использовать [[cl_predictionlist]] и [[cl_pdump]] для отладки этого.
Если вы добавляете функциональность к оружию и забываете выполнить шаги описанные выше, работа энтити может сопровождаться рывками и странностями с анимацией. Вы можете использовать [[cl_predictionlist]] и [[cl_pdump]] , чтобы устранить эти проблемы.


== Подавление сетевых данных ==
== Подавление сетевых данных ==


Большинство оружий имеют общий код, одинаковый код для клиента и сервера. Это позволяет клиенту  предсказывать вещи. Не требовательные вещи такие как эффекты оружия могут быть полностью выполняться клиентом, без отправки серверу данных эффекта всем клиентам. В этом случае подавление данных хорошая идея, которая даст меньшую загрузку сети.
Большая часть оружия имеет общий код, одинаковый для клиента и для сервера. Это позволяет клиенту  предсказывать события. Не требовательные к точности предсказания события, такие, как эффекты оружия, могут быть полностью выполняться клиентом, без отправки серверу данных эффекта для передачи всем клиентам. В этом случае подавление данных хорошая идея, которая даст меньшую загрузку сети.


Интерфейс <code>IPredictionSystem</code> предназначен для этого.
Интерфейс <code>IPredictionSystem</code> предназначен для этого.
Line 70: Line 70:
=Решение проблем=
=Решение проблем=


Предположим мы видим переменную становлящаяся время от времени красным цветом в панели <code>cl_pdump</code>. Теперь, мы знаем что иногда клиент производит отличающеся значение от того что на сервере. Обычно это можно отнести к следующим проблемам:
Предположим мы видим переменную, становящуюся время от времени красной в консоли <code>cl_pdump</code>. Теперь, мы знаем что иногда клиент производит значения отличающиеся от тех, что на сервере. Обычно это можно отнести к следующим проблемам:


# Клиент не выполняет тот же код что выполняет сервер. Это может быть случай, если участок кода помещен в секцию ограниченную <code>#ifdef GAME_DLL</code> или <code>#ifndef CLIENT_DLL</code> вокруг кода который влияет на переменную отмеченную красным цветом.
# Клиент не выполняет тот же код что выполняет сервер. Это может быть случай, если участок кода помещен в секцию ограниченную <code>#ifdef GAME_DLL</code> или <code>#ifndef CLIENT_DLL</code> вокруг кода который влияет на переменную отмеченную красным цветом.
# Другая переменная которая влияет на данное значение становящееся красным не передается через таблицу данных. В таком случае на клиенте, значение этой переменной всегда неверное (так как сервер никогда не передает его).
# Другая переменная которая влияет на данное значение становящееся красным не передается через таблицу данных. В таком случае на клиенте, значение этой переменной всегда неверное (так как сервер никогда не передает его).
# Также возможно не было добавлено соответствующее отклонение при помощи макроса <code>DEFINE_PRED_FIELD_TOL</code>. Например, если передается значение с плавающей запятой в диапазоне от 0.0 до 255.0, и было задано только 4 бита точности, тогда требуется отклонение около 17.0, иначе система предсказания считает значение переменной неверным изза того что значение сжимается до 4 бит перед отправкой клиенту.
# Также возможно не было добавлено соответствующее отклонение при помощи макроса <code>DEFINE_PRED_FIELD_TOL</code>. Например, если передается значение с плавающей запятой в диапазоне от 0.0 до 255.0, и было задано только 4 бита точности, тогда требуется отклонение около 17.0, иначе система предсказания считает значение переменной неверным из-за того что значение сжимается до 4 бит перед отправкой клиенту.


Отслеживание проблем предсказаний обычно предмет рассмотрения различного кода который влияет на переменные которые отображаются красным, и проверки других переменных которые влияют на их значение. Вначале это может показаться утомительным, но проверив это на собственном опыте проблемы с системой предсказания быстро исчезают.
Отслеживание проблем предсказаний обычно предмет рассмотрения различного кода который влияет на переменные которые отображаются красным, и проверки других переменных которые влияют на их значение. Вначале это может показаться утомительным, но проверив это на собственном опыте проблемы с системой предсказания быстро исчезают.

Revision as of 04:20, 16 January 2011

Вступление

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

  • 99% времени, предположения клиента корректны. Поэтому, клиент может играть, не замечая задержек в передаче по сети.
  • Если предположение клиента некорректно, клиент возвращается назад и повторяет имитацию всех команд, которые выполнялись с использованием ошибочных данных. В связи с этим, клиент ощущает небольшой рывок в его поле зрения, анимации оружия, и т.д. К счастью, если код написан корректно, этот случай не очень часто встречается.

Для более подробной информации можно прочитать Lag Compensation.

Подробности

Основные требования, которые требуется выполнить, чтобы энтити использовала систему предсказания:

  1. Одинаковые части кода энтити должны выполняться и на клиенте, и на сервере. Такой код относится к общему коду.
  2. Все переменные энтити которые меняются на сервере и клиенте должны передаваться при помощи таблиц данных.
  3. Эти переменные должны также быть добавлены в список называемый таблица предсказаний (prediction table).

Передача по сети через таблицы данных

Хорошим примером будет рассмотреть код оружия. Если у вас есть установленный исходный код, вы можете посмотреть файл src\game_shared\basecombatweapon_shared.cpp. Там, вы можете увидеть блоки #ifdef CLIENT_DLL и #ifdef GAME_DLL. Они определяют, какой код компилируется в клиентскую DLL, а какой в серверную. Приведенный ниже (сокращенный) код соответствует шагу 2 описанной выше последовательности (помещает переменные измененные общим кодом в таблицу данных).

BEGIN_NETWORK_TABLE(CBaseCombatWeapon, DT_BaseCombatWeapon)
#ifndef CLIENT_DLL
	SendPropInt( SENDINFO(m_iState ), 8, SPROP_UNSIGNED ),
	SendPropEHandle( SENDINFO(m_hOwner) ),
#else
	RecvPropInt( RECVINFO(m_iState )),
	RecvPropEHandle( RECVINFO(m_hOwner ) ),
#endif
END_NETWORK_TABLE()

Создание таблицы предсказаний

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

Template:Note:ru

#ifdef CLIENT_DLL
BEGIN_PREDICTION_DATA( CBaseCombatWeapon )
	DEFINE_PRED_FIELD( m_nNextThinkTick, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
	DEFINE_PRED_FIELD( m_hOwner, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
	DEFINE_PRED_FIELD_TOL( m_flNextPrimaryAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ),	
END_PREDICTION_DATA()
#endif

Консольные комманды

Если вы добавляете функциональность к оружию и забываете выполнить шаги описанные выше, работа энтити может сопровождаться рывками и странностями с анимацией. Вы можете использовать cl_predictionlist и cl_pdump , чтобы устранить эти проблемы.

Подавление сетевых данных

Большая часть оружия имеет общий код, одинаковый для клиента и для сервера. Это позволяет клиенту предсказывать события. Не требовательные к точности предсказания события, такие, как эффекты оружия, могут быть полностью выполняться клиентом, без отправки серверу данных эффекта для передачи всем клиентам. В этом случае подавление данных хорошая идея, которая даст меньшую загрузку сети.

Интерфейс IPredictionSystem предназначен для этого. Когда IPredictionSystem::SuppressHostEvents( pPlayer ); вызван, все сетевые данные к этому пользователю останавливаются. Отправка NULL повторно остановит подавление. Для примера:

if ( pPlayer->IsPredictingWeapons() )
IPredictionSystem::SuppressHostEvents( pPlayer );

pWeapon->CreateEffects();

IPredictionSystem::SuppressHostEvents( NULL );


Решение проблем

Предположим мы видим переменную, становящуюся время от времени красной в консоли cl_pdump. Теперь, мы знаем что иногда клиент производит значения отличающиеся от тех, что на сервере. Обычно это можно отнести к следующим проблемам:

  1. Клиент не выполняет тот же код что выполняет сервер. Это может быть случай, если участок кода помещен в секцию ограниченную #ifdef GAME_DLL или #ifndef CLIENT_DLL вокруг кода который влияет на переменную отмеченную красным цветом.
  2. Другая переменная которая влияет на данное значение становящееся красным не передается через таблицу данных. В таком случае на клиенте, значение этой переменной всегда неверное (так как сервер никогда не передает его).
  3. Также возможно не было добавлено соответствующее отклонение при помощи макроса DEFINE_PRED_FIELD_TOL. Например, если передается значение с плавающей запятой в диапазоне от 0.0 до 255.0, и было задано только 4 бита точности, тогда требуется отклонение около 17.0, иначе система предсказания считает значение переменной неверным из-за того что значение сжимается до 4 бит перед отправкой клиенту.

Отслеживание проблем предсказаний обычно предмет рассмотрения различного кода который влияет на переменные которые отображаются красным, и проверки других переменных которые влияют на их значение. Вначале это может показаться утомительным, но проверив это на собственном опыте проблемы с системой предсказания быстро исчезают.

Template:Otherlang:ru Template:Otherlang:ru:en