Ru/Frame Order: Difference between revisions
No edit summary |
m (Будем здоровы, DEBoshir!) |
||
Line 2: | Line 2: | ||
|title=Frame Order | |title=Frame Order | ||
|en=Frame Order}} | |en=Frame Order}} | ||
==Движок== | ==Движок== | ||
Revision as of 15:25, 16 January 2012
Движок
Движок имеет два режима работы - потоковый (многопоточный) и безпотоковый (однопоточный). Переменная 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 и игровых систем