Ru/Frame Order: Difference between revisions

From Valve Developer Community
< Ru
Jump to navigation Jump to search
m (Будем здоровы, DEBoshir!)
m (Стилевые правки)
Line 6: Line 6:
Движок имеет два режима работы - потоковый (многопоточный) и безпотоковый (однопоточный). Переменная <code>host_thread_mode</code> определяет, какой режим работы будет использован. Выделенные сервера игнорируют эту переменную и всегда используют безпотоковый (однопоточный) путь. XBox 360 по-умолчанию работает в потоковом режиме, в то время как ПК по-умолчанию работает в безпотоковом. Потоковый режим был введен вместе с Orange Box версией движка, и не существовал в Episode 1 или в предыдущих версиях.
Движок имеет два режима работы - потоковый (многопоточный) и безпотоковый (однопоточный). Переменная <code>host_thread_mode</code> определяет, какой режим работы будет использован. Выделенные сервера игнорируют эту переменную и всегда используют безпотоковый (однопоточный) путь. XBox 360 по-умолчанию работает в потоковом режиме, в то время как ПК по-умолчанию работает в безпотоковом. Потоковый режим был введен вместе с Orange Box версией движка, и не существовал в Episode 1 или в предыдущих версиях.


Сервера-слушатели (например однопользовательские игры или сервера запущенные одним из игроков) выполняют все секции кода, вызывая функции  из client.dll и server.dll из одного и того же цикла работы движка. Клиенты, подключенные к удаленному серверу могут выполнять только помеченные курсивом секции, а выделенные сервера могут выполнять только секции выделенные жирным. Сборки удаленного сервера (Linux или Windows SrcDs) могут выполнять только подчеркнутые секции.
Сервера-слушатели (listenservers) (например однопользовательские игры или сервера запущенные одним из игроков) выполняют все секции кода, вызывая функции  из client.dll и server.dll в одном и том же цикле работы движка. Клиенты, подключенные к удаленному серверу могут выполнять только помеченные курсивом секции, а выделенные (dedicated) сервера могут выполнять только секции выделенные жирным. Сборки выделенного (dedicated) сервера (Linux или Windows SrcDs) могут выполнять только подчеркнутые секции.


Обозначения:
Обозначения:
Line 19: Line 19:
* ''<code><font color=green>CHLClient::FrameStageNotify(FRAME_START)</font></code>''
* ''<code><font color=green>CHLClient::FrameStageNotify(FRAME_START)</font></code>''
* '''''<u>[[#Console_commands|Console commands]]</u>'''''
* '''''<u>[[#Console_commands|Console commands]]</u>'''''
* For each tick:
* На каждом такте:
** '''''<u>[[#Networking|Networking]]</u>'''''
** '''''<u>[[#Networking|Networking]]</u>'''''
** ''[[#Input|Input]]''
** ''[[#Input|Input]]''
Line 34: Line 34:
* ''<code><font color=green>CHLClient::FrameStageNotify(FRAME_START)</font></code>''
* ''<code><font color=green>CHLClient::FrameStageNotify(FRAME_START)</font></code>''
* '''''[[#Console_commands|Console commands]]'''''
* '''''[[#Console_commands|Console commands]]'''''
* Для каждого такта:
* На каждом такте:
** '''''[[#Networking|Networking]]'''''
** '''''[[#Networking|Networking]]'''''
** ''[[#Client_logic|Client logic]]''
** ''[[#Client_logic|Client logic]]''
* ''[[#Client_prediction|Client prediction]]''
* ''[[#Client_prediction|Client prediction]]''
* For each server tick:
* Для каждого такта сервера:
** ''[[#Input|Input]]''
** ''[[#Input|Input]]''
** '''''[[#Networking|Networking]]'''''
** '''''[[#Networking|Networking]]'''''
Line 49: Line 49:


Обозначения:
Обозначения:
* <font color=green>Зеленым - функция вызываемая из движком внутри игрового кода</font>
* <font color=green>Зеленым - функция вызываемая движком внутри игрового кода</font>
* <font color=purple>Пурпурным - код существующий внутри игрового кода и доступный для изменения</font>
* <font color=purple>Пурпурным - код существующий внутри игрового кода и доступный для изменения</font>
* <font color=darkred>Красным - специальная информация</font>
* <font color=darkred>Красным - специальная информация</font>
Line 57: Line 57:
Эта секция читает сообщения от операционной системы и указателей клавиатуры и события окна.
Эта секция читает сообщения от операционной системы и указателей клавиатуры и события окна.


События кнопок отправляются в соответствии с приоритетом сначала утилитам (PET, Actbusy  и т.п.), затем к системе VGUI, после чего к клиентскому коду игры, а в конце  движку. Если один из элементов цепочки не может обработать это событие, то оно отправляется для обработки следующему звену.
События кнопок отправляются по очереди сначала утилитам (PET, Actbusy  и т.п.), затем к системе VGUI, клиентскому коду игры, и наконец движку. Если один из элементов цепи не может обработать полученное событие, то оно отправляется на обработку следующему звену.


* Если нажата кнопка: <code><font color=green>CHLClient::IN_KeyEvent</font></code>
* При нажатии кнопки: <code><font color=green>CHLClient::IN_KeyEvent</font></code>


===Console commands===
===Console commands===


В этой секции подсчитываются и исполняются команды, введенные в игровую консоль. Если консольная команда это ConCommand созданная игровым кодом, она выполнит возврат внутри игрового кода через <code>ConCommand::Dispatch( const CCommand &command )</code> в файле <code>convar.cpp</code>.
В этой секции подсчитываются и исполняются команды, введенные в игровую консоль. Если консольная команда это команда созданная игровым кодом, она выполнит возврат внутри игрового кода через <code>ConCommand::Dispatch( const CCommand &command )</code> в файле <code>convar.cpp</code>.


===Networking===
===Networking===


В этой секции отправляются и принимаются сетевые сообщения. Она работает на локальном хосте сервера через loopback. На экземплярах только для серверов или только для клиентов работает через соединение по протоколу UPD. Игровой код не вызывается в этой секции.
В этой секции отправляются и принимаются сетевые сообщения. На сервере локального хоста она работает через локальную петлю (loopback). На экземплярах только для серверов или только для клиентов работает через соединение по протоколу UPD. Игровой код не вызывается в этой секции.


===Input===
===Input===
Line 77: Line 77:
* Обработка команд перемещения игрока
* Обработка команд перемещения игрока
** <code><font color=green>CHLClient::CreateMove()</font></code>
** <code><font color=green>CHLClient::CreateMove()</font></code>
** Очередь команд перемещения по сети на сервер
** Помещение команд перемещения в очередь для передачи по сети на сервер


===Server game code===
===Server game code===
Line 95: Line 95:
** <code><font color=green>CServerGameDLL::PreClientUpdate()</font></code>
** <code><font color=green>CServerGameDLL::PreClientUpdate()</font></code>
*** <font color=purple>Для каждой игровой системы: <code>PreClientUpdate()</code></font>
*** <font color=purple>Для каждой игровой системы: <code>PreClientUpdate()</code></font>
** Передача сообщений из очереди сети
** Передача очередных сетевых сообщений
** Для каждого клиента:
** Для каждого клиента:
*** Настройка упаковки данных для сети
*** Настройка упаковки данных для сети
Line 114: Line 114:
*** <code><font color=green>CPrediction::PreEntityPacketReceived</font></code>
*** <code><font color=green>CPrediction::PreEntityPacketReceived</font></code>
*** <code><font color=green>CHLClient::FrameStageNotify(FRAME_NET_UPDATE_START)</font></code>
*** <code><font color=green>CHLClient::FrameStageNotify(FRAME_NET_UPDATE_START)</font></code>
**** <font color=darkred>Absolute origin/angle queries invalidated</font>
**** <font color=darkred>Запрос на проверку векторов и углов</font>
*** Обновление базовых данных, обновление таблиц данных сущностей
*** Обновление базовых данных, обновление таблиц данных сущностей
**** При необходимости вызов <code><font color=green>C_BaseEntity::PreDataUpdate</font></code>.
**** При необходимости вызов <code><font color=green>C_BaseEntity::PreDataUpdate</font></code>.
Line 121: Line 121:
*** <code><font color=green>CHLClient::FrameStageNotify(FRAME_NET_UPDATE_POSTDATAUPDATE_END)</font></code>
*** <code><font color=green>CHLClient::FrameStageNotify(FRAME_NET_UPDATE_POSTDATAUPDATE_END)</font></code>
**** <code><font color=purple>CPrediction::PostEntityPacketReceived()</font></code>
**** <code><font color=purple>CPrediction::PostEntityPacketReceived()</font></code>
*** Если сущность вошла или вышла из [[PVS|поля видимости пользователя]]: <code><font color=green>C_BaseEntity::NotifyShouldTransmit()</font></code>
*** Если сущность вошла или вышла из [[PVS|потенциально видимый набор]]: <code><font color=green>C_BaseEntity::NotifyShouldTransmit()</font></code>
*** <code><font color=green>CHLClient::FrameStageNotify(FRAME_NET_UPDATE_END)</font></code>
*** <code><font color=green>CHLClient::FrameStageNotify(FRAME_NET_UPDATE_END)</font></code>
**** <font color=darkred>Absolute origin/angle queries re-validated</font>
**** <font color=darkred>Запрос на повторную проверку векторов и углов</font>
*** <code><font color=green>CPrediction::PostNetworkDataReceived()</font></code>
*** <code><font color=green>CPrediction::PostNetworkDataReceived()</font></code>
** Если сообщение это сообщение сущности:
** Если сообщение это сообщение сущности:
Line 152: Line 152:
** <code>CPrediction::Untouch()</code>
** <code>CPrediction::Untouch()</code>
</font>
</font>
* Обновление углов в соответствии с входящей информации
* Обновление углов в соответствии с исходными данными
** <code><font color=green>CPrediction::SetLocalViewAngles()</font></code>
** <code><font color=green>CPrediction::SetLocalViewAngles()</font></code>
* <code><font color=green>CHLClient::ExtraMouseSample()</font></code>
* <code><font color=green>CHLClient::ExtraMouseSample()</font></code>
Line 158: Line 158:
===Rendering===
===Rendering===


Установка кода отрисовки видимого мира, обновление всех сущностей и отрисовка сцены и пользовательского интерфейса.
Настройка отрисовки видимого мира, обновление всех сущностей и отрисовка сцены и пользовательского интерфейса.


* <code><font color=green>CHLClient::FrameStageNotify(FRAME_RENDER_START)</font></code>
* <code><font color=green>CHLClient::FrameStageNotify(FRAME_RENDER_START)</font></code>
Line 171: Line 171:
*** Обновление сущностей, временных сущностей (tempents), систем частиц, симуляция физики, вызов функции ClientThink() </font>
*** Обновление сущностей, временных сущностей (tempents), систем частиц, симуляция физики, вызов функции ClientThink() </font>
* <code><font color=green>CHLClient::View_Render()</font></code>
* <code><font color=green>CHLClient::View_Render()</font></code>
** <font color=purple>Рисует мир и UI</font>
** <font color=purple>Рисует мир и пользовательский интерфейс</font>
* <code><font color=green>CHLClient::FrameStageNotify(FRAME_RENDER_END)</font></code>
* <code><font color=green>CHLClient::FrameStageNotify(FRAME_RENDER_END)</font></code>



Revision as of 23:54, 16 January 2012

Template:Otherlang2

Движок

Движок имеет два режима работы - потоковый (многопоточный) и безпотоковый (однопоточный). Переменная host_thread_mode определяет, какой режим работы будет использован. Выделенные сервера игнорируют эту переменную и всегда используют безпотоковый (однопоточный) путь. XBox 360 по-умолчанию работает в потоковом режиме, в то время как ПК по-умолчанию работает в безпотоковом. Потоковый режим был введен вместе с Orange Box версией движка, и не существовал в Episode 1 или в предыдущих версиях.

Сервера-слушатели (listenservers) (например однопользовательские игры или сервера запущенные одним из игроков) выполняют все секции кода, вызывая функции из client.dll и server.dll в одном и том же цикле работы движка. Клиенты, подключенные к удаленному серверу могут выполнять только помеченные курсивом секции, а выделенные (dedicated) сервера могут выполнять только секции выделенные жирным. Сборки выделенного (dedicated) сервера (Linux или Windows SrcDs) могут выполнять только подчеркнутые секции.

Обозначения:

  • Жирный - код сервера, работает на любом сервере, только для серверов или серверов-на-клиентах
  • Курсивом - код клиента, работает на любом клиенте, только для клиента или серверов-на-клиентах
  • Подчеркнуто - код для выделенного сервера (Не подчеркнутые элементы не выполняются на выделенном сервере)
  • Зеленым - функции вызываемые движком внутри игрового кода

Безпотоковая модель

Потоковая модель

Секции

Обозначения:

  • Зеленым - функция вызываемая движком внутри игрового кода
  • Пурпурным - код существующий внутри игрового кода и доступный для изменения
  • Красным - специальная информация

Device input

Эта секция читает сообщения от операционной системы и указателей клавиатуры и события окна.

События кнопок отправляются по очереди сначала утилитам (PET, Actbusy и т.п.), затем к системе VGUI, клиентскому коду игры, и наконец движку. Если один из элементов цепи не может обработать полученное событие, то оно отправляется на обработку следующему звену.

  • При нажатии кнопки: CHLClient::IN_KeyEvent

Console commands

В этой секции подсчитываются и исполняются команды, введенные в игровую консоль. Если консольная команда это команда созданная игровым кодом, она выполнит возврат внутри игрового кода через ConCommand::Dispatch( const CCommand &command ) в файле convar.cpp.

Networking

В этой секции отправляются и принимаются сетевые сообщения. На сервере локального хоста она работает через локальную петлю (loopback). На экземплярах только для серверов или только для клиентов работает через соединение по протоколу UPD. Игровой код не вызывается в этой секции.

Input

Эта секция читает и исполняет входящие сообщения. Она работает только на клиенте или локальном хосте.

  • CHLClient::HudProcessInput()
  • Обработка console commands
  • Обработка команд перемещения игрока
    • CHLClient::CreateMove()
    • Помещение команд перемещения в очередь для передачи по сети на сервер

Server game code

Эта секция вызывает функции Think для каждой сущности и выполняет игровую логику.

  • Если это последний такт фрейма: CServerGameDLL::Think()
  • Читает сетевой ввод
  • Для каждого плагина: IServerPluginCallbacks::GameFrame()
  • CServerGameDLL::GameFrame()
    • Для каждой игровой системы: FrameUpdatePreEntityThink()
    • GameRules::Think()
    • Симуляция физики
      • Для каждого игрока: CBasePlayer::PlayerRunCommand()
    • Для каждой игровой системы: FrameUpdatePostEntityThink()
  • Если это последний такт фрейма: (Эта часть кода выполняется в отдельном потоке если движок работает в потоковом режиме.)
    • CServerGameDLL::PreClientUpdate()
      • Для каждой игровой системы: PreClientUpdate()
    • Передача очередных сетевых сообщений
    • Для каждого клиента:
      • Настройка упаковки данных для сети
        • CServerGameClients::ClientSetupVisibility()
        • CServerGameEnts::CheckTransmit()
        • В одиночной игре, Client logic работает через локальный сетевой интерфейс (используя memcpy вместо медленной сетевой петли)
        • Измененные таблицы данных сущностей упаковываются для передачи по сети и снимки (snapshots) отправляются клиентам
    • CServerGameClients::PostClientMessagesSent()

Client logic

Эта секция читает сетевые пакеты и обновляет сущности на клиенте.

  • Читает пакеты
    • Если сообщение является пакетом сущности:
      • Если это мультиплеер или особая команда:
      • CPrediction::PreEntityPacketReceived
      • CHLClient::FrameStageNotify(FRAME_NET_UPDATE_START)
        • Запрос на проверку векторов и углов
      • Обновление базовых данных, обновление таблиц данных сущностей
        • При необходимости вызов C_BaseEntity::PreDataUpdate.
      • CHLClient::FrameStageNotify(FRAME_NET_UPDATE_POSTDATAUPDATE_START)
      • Для каждой обновленной сущности: C_BaseEntity::PostDataUpdate()
      • CHLClient::FrameStageNotify(FRAME_NET_UPDATE_POSTDATAUPDATE_END)
        • CPrediction::PostEntityPacketReceived()
      • Если сущность вошла или вышла из потенциально видимый набор: C_BaseEntity::NotifyShouldTransmit()
      • CHLClient::FrameStageNotify(FRAME_NET_UPDATE_END)
        • Запрос на повторную проверку векторов и углов
      • CPrediction::PostNetworkDataReceived()
    • Если сообщение это сообщение сущности:
      • CHLClient::DispatchUserMessage()
    • Если сообщение это игровое событие:
      • ClientModeShared::FireGameEvent()

Client prediction

Эта секция выполняет код прогнозирования для локального клиента.

  • CPrediction::Update()
    • Выполнение прогнозирования. Для каждой команды перемещения игрока:
      • CPrediction::RunSimulation()
      • Для каждой прогнозируемой сущности:
        • Если таблица была изменена: C_BaseEntity::OnPreDataChanged()
        • C_BaseEntity::PhysicsSimulate()
          • CPrediction::RunCommand()
          • Если сущность это игрок:
            • C_BasePlayer::PreThink()
            • CPrediction::SetupMove()
            • CGameMovement::ProcessMovement()
            • CPrediction::FinishMove()
            • C_BasePlayer::PostThink()
            • CMoveHelperClient::ProcessImpacts()
          • Если сущность это не игрок:
            • Запуск физической симуляции и C_BaseEntity::Think()
    • CPrediction::Untouch()

  • Обновление углов в соответствии с исходными данными
    • CPrediction::SetLocalViewAngles()
  • CHLClient::ExtraMouseSample()

Rendering

Настройка отрисовки видимого мира, обновление всех сущностей и отрисовка сцены и пользовательского интерфейса.

  • CHLClient::FrameStageNotify(FRAME_RENDER_START)
    • CInput::CAM_Think()
    • CViewRender::OnRenderStart()
      • CViewRender::SetUpView()
        • CBasePlayer::CalcView()
      • Для каждого игрока: CBasePlayer::UpdateClientSideAnimation()
        • CMultiPlayerAnimState::Update()
      • ProcessOnDataChangedEvents()
        • Для каждой сущности с изменившимися данными: C_BaseEntity::OnDataChanged()
      • Обновление сущностей, временных сущностей (tempents), систем частиц, симуляция физики, вызов функции ClientThink()
  • CHLClient::View_Render()
    • Рисует мир и пользовательский интерфейс
  • CHLClient::FrameStageNotify(FRAME_RENDER_END)

Sound

Код обработки звука и воспроизведение звуков на клиенте. Это не делает вызовы в коде игры.

Client HUD update

Эта секция вызывает:

  • CHLClient::HudUpdate()
    • Обновление HUD и игровых систем