Ru/Frame Order: Difference between revisions
(Finishtranslation:ru) |
No edit summary |
||
Line 56: | Line 56: | ||
===Device input=== | ===Device input=== | ||
Эта секция читает сообщения от операционной системы и указателей клавиатуры и события окна. | |||
События кнопок отправляются в соответствии с приоритетом сначала утилитам (PET, Actbusy и т.п.), затем к системе VGUI, после чего к клиентскому коду игры, а в конце движку. Если один из элементов цепочки не может обработать это событие, то оно отправляется для обработки следующему звену. | |||
* | * Если нажата кнопка: <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>. | |||
===Networking=== | ===Networking=== | ||
В этой секции отправляются и принимаются сетевые сообщения. Она работает на локальном хосте сервера через loopback. На экземплярах только для серверов или только для клиентов работает через соединение по протоколу UPD. Игровой код не вызывается в этой секции. | |||
===Input=== | ===Input=== | ||
Эта секция читает и исполняет входящие сообщения. Она работает только на клиенте или локальном хосте. | |||
* <code><font color=green>CHLClient::HudProcessInput()</font></code> | * <code><font color=green>CHLClient::HudProcessInput()</font></code> | ||
* | * Обработка [[#Console_commands|console commands]] | ||
* | * Обработка команд перемещения игрока | ||
** <code><font color=green>CHLClient::CreateMove()</font></code> | ** <code><font color=green>CHLClient::CreateMove()</font></code> | ||
** | ** Очередь команд перемещения по сети на сервер | ||
===Server game code=== | ===Server game code=== | ||
Эта секция вызывает функции <code>Think</code> для каждой сущности и выполняет игровую логику. | |||
* | * Если это последний такт фрейма: <code><font color=green>CServerGameDLL::Think()</font></code> | ||
* | * Читает сетевой ввод | ||
* | * Для каждого плагина: <code><font color=green>IServerPluginCallbacks::GameFrame()</font></code> | ||
* <code><font color=green>CServerGameDLL::GameFrame()</font></code> | * <code><font color=green>CServerGameDLL::GameFrame()</font></code> | ||
** <font color=purple> | ** <font color=purple>Для каждой игровой системы: <code>FrameUpdatePreEntityThink()</code> | ||
** <code>GameRules::Think()</code> | ** <code>GameRules::Think()</code> | ||
** | ** Симуляция физики | ||
*** | *** Для каждого игрока: <code>CBasePlayer::PlayerRunCommand()</code> | ||
** | ** Для каждой игровой системы: <code>FrameUpdatePostEntityThink()</code></font> | ||
* | * Если это последний такт фрейма: ''(Эта часть кода выполняется в отдельном потоке если движок работает в потоковом режиме.)'' | ||
** <code><font color=green>CServerGameDLL::PreClientUpdate()</font></code> | ** <code><font color=green>CServerGameDLL::PreClientUpdate()</font></code> | ||
*** <font color=purple> | *** <font color=purple>Для каждой игровой системы: <code>PreClientUpdate()</code></font> | ||
** | ** Передача сообщений из очереди сети | ||
** | ** Для каждого клиента: | ||
*** | *** Настройка упаковки данных для сети | ||
**** <code><font color=green>CServerGameClients::ClientSetupVisibility()</font></code> | **** <code><font color=green>CServerGameClients::ClientSetupVisibility()</font></code> | ||
**** <code><font color=green>CServerGameEnts::CheckTransmit()</font></code> | **** <code><font color=green>CServerGameEnts::CheckTransmit()</font></code> | ||
**** | **** В одиночной игре, [[#Client_logic|Client logic]] работает через локальный сетевой интерфейс (используя memcpy вместо медленной сетевой петли) | ||
**** | **** Измененные таблицы данных сущностей упаковываются для передачи по сети и снимки (snapshots) отправляются клиентам | ||
** <code><font color=green>CServerGameClients::PostClientMessagesSent()</font></code> | ** <code><font color=green>CServerGameClients::PostClientMessagesSent()</font></code> | ||
===Client logic=== | ===Client logic=== | ||
Эта секция читает сетевые пакеты и обновляет сущности на клиенте. | |||
* | * Читает пакеты | ||
** | ** Если сообщение является пакетом сущности: | ||
*** | *** Если это мультиплеер или особая команда: | ||
**** | **** Запуск [[#Client_prediction|prediction]] | ||
*** <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>Absolute origin/angle queries invalidated</font> | ||
*** | *** Обновление базовых данных, обновление таблиц данных сущностей | ||
**** | **** При необходимости вызов <code><font color=green>C_BaseEntity::PreDataUpdate</font></code>. | ||
*** <code><font color=green>CHLClient::FrameStageNotify(FRAME_NET_UPDATE_POSTDATAUPDATE_START)</font></code> | *** <code><font color=green>CHLClient::FrameStageNotify(FRAME_NET_UPDATE_POSTDATAUPDATE_START)</font></code> | ||
*** | *** Для каждой обновленной сущности: <code><font color=green>C_BaseEntity::PostDataUpdate()</font></code> | ||
*** <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> | ||
*** <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>Absolute origin/angle queries re-validated</font> | ||
*** <code><font color=green>CPrediction::PostNetworkDataReceived()</font></code> | *** <code><font color=green>CPrediction::PostNetworkDataReceived()</font></code> | ||
** | ** Если сообщение это сообщение сущности: | ||
*** <code><font color=green>CHLClient::DispatchUserMessage()</font></code> | *** <code><font color=green>CHLClient::DispatchUserMessage()</font></code> | ||
** | ** Если сообщение это игровое событие: | ||
*** <code><font color=green>ClientModeShared::FireGameEvent()</font></code> | *** <code><font color=green>ClientModeShared::FireGameEvent()</font></code> | ||
===Client prediction=== | ===Client prediction=== | ||
Эта секция выполняет код прогнозирования для локального клиента. | |||
* <code><font color=green>CPrediction::Update()</font></code> | * <code><font color=green>CPrediction::Update()</font></code> | ||
** <font color=purple> | ** <font color=purple>Выполнение прогнозирования. Для каждой команды перемещения игрока: | ||
*** <code>CPrediction::RunSimulation()</code> | *** <code>CPrediction::RunSimulation()</code> | ||
*** | *** Для каждой прогнозируемой сущности: | ||
**** | **** Если таблица была изменена: <code>C_BaseEntity::OnPreDataChanged()</code> | ||
**** <code>C_BaseEntity::PhysicsSimulate()</code> | **** <code>C_BaseEntity::PhysicsSimulate()</code> | ||
***** <code>CPrediction::RunCommand()</code> | ***** <code>CPrediction::RunCommand()</code> | ||
***** | ***** Если сущность это игрок: | ||
****** <code>C_BasePlayer::PreThink()</code> | ****** <code>C_BasePlayer::PreThink()</code> | ||
****** <code>CPrediction::SetupMove()</code> | ****** <code>CPrediction::SetupMove()</code> | ||
Line 149: | Line 149: | ||
****** <code>C_BasePlayer::PostThink()</code> | ****** <code>C_BasePlayer::PostThink()</code> | ||
****** <code>CMoveHelperClient::ProcessImpacts()</code> | ****** <code>CMoveHelperClient::ProcessImpacts()</code> | ||
***** | ***** Если сущность это не игрок: | ||
****** | ****** Запуск физической симуляции и <code>C_BaseEntity::Think()</code> | ||
** <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 159: | Line 159: | ||
===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 166: | Line 166: | ||
*** <code>CViewRender::SetUpView()</code> | *** <code>CViewRender::SetUpView()</code> | ||
**** <code>CBasePlayer::CalcView()</code> | **** <code>CBasePlayer::CalcView()</code> | ||
*** | *** Для каждого игрока: <code>CBasePlayer::UpdateClientSideAnimation()</code> | ||
**** <code>CMultiPlayerAnimState::Update()</code> | **** <code>CMultiPlayerAnimState::Update()</code> | ||
*** <code>ProcessOnDataChangedEvents()</code> | *** <code>ProcessOnDataChangedEvents()</code> | ||
**** | **** Для каждой сущности с изменившимися данными: <code>C_BaseEntity::OnDataChanged()</code> | ||
*** | *** Обновление сущностей, временных сущностей (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>Рисует мир и UI</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 13:17, 16 January 2012
Template:Otherlang2 Template:Finishtranslation:ru
Движок
Движок имеет два режима работы - потоковый (многопоточный) и безпотоковый (однопоточный). Переменная host_thread_mode
определяет, какой режим работы будет использован. Выделенные сервера игнорируют эту переменную и всегда используют безпотоковый (однопоточный) путь. XBox 360 по-умолчанию работает в потоковом режиме, в то время как ПК по-умолчанию работает в безпотоковом. Потоковый режим был введен вместе с Orange Box версией движка, и не существовал в Episode 1 или в предыдущих версиях.
Сервера-слушатели (например однопользовательские игры или сервера запущенные одним из игроков) выполняют все секции кода, вызывая функции из client.dll и server.dll из одного и того же цикла работы движка. Клиенты, подключенные к удаленному серверу могут выполнять только помеченные курсивом секции, а выделенные сервера могут выполнять только секции выделенные жирным. Сборки удаленного сервера (Linux или Windows SrcDs) могут выполнять только подчеркнутые секции.
Обозначения:
- Жирный - код сервера, работает на любом сервере, только для серверов или серверов-на-клиентах
- Курсивом - код клиента, работает на любом клиенте, только для клиента или серверов-на-клиентах
- Подчеркнуто - код для выделенного сервера (Не подчеркнутые элементы не выполняются на выделенном сервере)
- Зеленым - функции вызываемые движком внутри игрового кода
Безпотоковая модель
- Device input
CHLClient::FrameStageNotify(FRAME_START)
- Console commands
- For each tick:
- Rendering
- Sound
- Client HUD update
Потоковая модель
- Device input
CHLClient::FrameStageNotify(FRAME_START)
- Console commands
- Для каждого такта:
- Client prediction
- For each server tick:
- Server game code (в отдельном потоке)
- Rendering
- Sound
- Client HUD update
Секции
Обозначения:
- Зеленым - функция вызываемая из движком внутри игрового кода
- Пурпурным - код существующий внутри игрового кода и доступный для изменения
- Красным - специальная информация
Device input
Эта секция читает сообщения от операционной системы и указателей клавиатуры и события окна.
События кнопок отправляются в соответствии с приоритетом сначала утилитам (PET, Actbusy и т.п.), затем к системе VGUI, после чего к клиентскому коду игры, а в конце движку. Если один из элементов цепочки не может обработать это событие, то оно отправляется для обработки следующему звену.
- Если нажата кнопка:
CHLClient::IN_KeyEvent
Console commands
В этой секции подсчитываются и исполняются команды, введенные в игровую консоль. Если консольная команда это ConCommand созданная игровым кодом, она выполнит возврат внутри игрового кода через 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)
- Absolute origin/angle queries invalidated
- Обновление базовых данных, обновление таблиц данных сущностей
- При необходимости вызов
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)
- Absolute origin/angle queries re-validated
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()
- Рисует мир и UI
CHLClient::FrameStageNotify(FRAME_RENDER_END)
Sound
Код обработки звука и воспроизведение звуков на клиенте. Это не делает вызовы в коде игры.
Client HUD update
Эта секция вызывает:
CHLClient::HudUpdate()
- Обновление HUD и игровых систем