Ru/Frame Order: Difference between revisions
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 | Сервера-слушатели (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>''''' | ||
* | * На каждом такте: | ||
** '''''<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]]'' | ||
* | * Для каждого такта сервера: | ||
** ''[[#Input|Input]]'' | ** ''[[#Input|Input]]'' | ||
** '''''[[#Networking|Networking]]''''' | ** '''''[[#Networking|Networking]]''''' | ||
Line 49: | Line 49: | ||
Обозначения: | Обозначения: | ||
* <font color=green>Зеленым - функция вызываемая | * <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, клиентскому коду игры, и наконец движку. Если один из элементов цепи не может обработать полученное событие, то оно отправляется на обработку следующему звену. | ||
* | * При нажатии кнопки: <code><font color=green>CHLClient::IN_KeyEvent</font></code> | ||
===Console commands=== | ===Console commands=== | ||
В этой секции подсчитываются и исполняются команды, введенные в игровую консоль. Если консольная команда это | В этой секции подсчитываются и исполняются команды, введенные в игровую консоль. Если консольная команда это команда созданная игровым кодом, она выполнит возврат внутри игрового кода через <code>ConCommand::Dispatch( const CCommand &command )</code> в файле <code>convar.cpp</code>. | ||
===Networking=== | ===Networking=== | ||
В этой секции отправляются и принимаются сетевые сообщения. | В этой секции отправляются и принимаются сетевые сообщения. На сервере локального хоста она работает через локальную петлю (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> | **** <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| | *** Если сущность вошла или вышла из [[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> | **** <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>Рисует мир и | ** <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
Движок
Движок имеет два режима работы - потоковый (многопоточный) и безпотоковый (однопоточный). Переменная host_thread_mode
определяет, какой режим работы будет использован. Выделенные сервера игнорируют эту переменную и всегда используют безпотоковый (однопоточный) путь. XBox 360 по-умолчанию работает в потоковом режиме, в то время как ПК по-умолчанию работает в безпотоковом. Потоковый режим был введен вместе с Orange Box версией движка, и не существовал в Episode 1 или в предыдущих версиях.
Сервера-слушатели (listenservers) (например однопользовательские игры или сервера запущенные одним из игроков) выполняют все секции кода, вызывая функции из client.dll и server.dll в одном и том же цикле работы движка. Клиенты, подключенные к удаленному серверу могут выполнять только помеченные курсивом секции, а выделенные (dedicated) сервера могут выполнять только секции выделенные жирным. Сборки выделенного (dedicated) сервера (Linux или Windows SrcDs) могут выполнять только подчеркнутые секции.
Обозначения:
- Жирный - код сервера, работает на любом сервере, только для серверов или серверов-на-клиентах
- Курсивом - код клиента, работает на любом клиенте, только для клиента или серверов-на-клиентах
- Подчеркнуто - код для выделенного сервера (Не подчеркнутые элементы не выполняются на выделенном сервере)
- Зеленым - функции вызываемые движком внутри игрового кода
Безпотоковая модель
- Device input
CHLClient::FrameStageNotify(FRAME_START)
- Console commands
- На каждом такте:
- Rendering
- Sound
- Client HUD update
Потоковая модель
- Device input
CHLClient::FrameStageNotify(FRAME_START)
- Console commands
- На каждом такте:
- Client prediction
- Для каждого такта сервера:
- Server game code (в отдельном потоке)
- Rendering
- Sound
- Client HUD update
Секции
Обозначения:
- Зеленым - функция вызываемая движком внутри игрового кода
- Пурпурным - код существующий внутри игрового кода и доступный для изменения
- Красным - специальная информация
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
Эта секция читает сетевые пакеты и обновляет сущности на клиенте.
- Читает пакеты
- Если сообщение является пакетом сущности:
- Если это мультиплеер или особая команда:
- Запуск prediction
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 и игровых систем