Ru/Frame Order
Движок
Движок имеет два режима работы - потоковый (многопоточный) и безпотоковый (однопоточный). Переменная 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
This section reads messages from the operating system and handles keyboard and window events.
Key events are sent by priority first to tools (PET, Actbusy, etc) then to VGUI, then to the client game code, and finally to the engine. If one does not process it, it is then sent to the next.
- If a key is pressed:
CHLClient::IN_KeyEvent
Console commands
This section evaluates and executes commands input into the game console. If the console command is a ConCommand created by the game code, it will execute a callback into the game code through ConCommand::Dispatch( const CCommand &command )
in convar.cpp
.
Networking
This section sends and receives network messages. It runs on a localhost server through an internal backdoor loopback device. On server-only or client-only instances it runs over a UDP connection. No game code callbacks are made during this time.
Input
This section reads and processes input messages. It runs only on client or localhost engines.
CHLClient::HudProcessInput()
- Process console commands
- Process player movement commands
CHLClient::CreateMove()
- Queue movement commands to network to the server
Server game code
This section calls Think
functions for each entity and processes game logic.
- If this is the last tick in the frame:
CServerGameDLL::Think()
- Read network input
- For each plugin:
IServerPluginCallbacks::GameFrame()
CServerGameDLL::GameFrame()
- For each game system:
FrameUpdatePreEntityThink()
GameRules::Think()
- Physics simulations
- For each player:
CBasePlayer::PlayerRunCommand()
- For each player:
- For each game system:
FrameUpdatePostEntityThink()
- For each game system:
- If this is the last tick in the frame: (This part of the tree occurs in a separate thread if the engine is threaded.)
CServerGameDLL::PreClientUpdate()
- For each game system:
PreClientUpdate()
- For each game system:
- Transmit queued network messages
- For every client:
- Set up network pack data
CServerGameClients::ClientSetupVisibility()
CServerGameEnts::CheckTransmit()
- In a singleplayer game, Client logic is run through the local network backdoor (using memcpy instead of a slower network loopback)
- Changed entity data tables are packed for network transmission, and snapshots are sent to clients
- Set up network pack data
CServerGameClients::PostClientMessagesSent()
Client logic
This section reads network packets and updates the entities on the client.
- Read packets
- If message is an entity packet:
- If multiplayer or if there are extra commands:
- Run prediction
CPrediction::PreEntityPacketReceived
CHLClient::FrameStageNotify(FRAME_NET_UPDATE_START)
- Absolute origin/angle queries invalidated
- Update baseline, update entity data tables
- Calls to
C_BaseEntity::PreDataUpdate
as necessary.
- Calls to
CHLClient::FrameStageNotify(FRAME_NET_UPDATE_POSTDATAUPDATE_START)
- For every updated entity:
C_BaseEntity::PostDataUpdate()
CHLClient::FrameStageNotify(FRAME_NET_UPDATE_POSTDATAUPDATE_END)
CPrediction::PostEntityPacketReceived()
- If an entity has entered or exited the client's PVS:
C_BaseEntity::NotifyShouldTransmit()
CHLClient::FrameStageNotify(FRAME_NET_UPDATE_END)
- Absolute origin/angle queries re-validated
CPrediction::PostNetworkDataReceived()
- If multiplayer or if there are extra commands:
- If message is an entity message:
CHLClient::DispatchUserMessage()
- If message is a game event:
ClientModeShared::FireGameEvent()
- If message is an entity packet:
Client prediction
This section runs prediction code for the local client.
CPrediction::Update()
- Perform prediction. For every player movement command:
CPrediction::RunSimulation()
- For every predictable entity:
- If data table has changed:
C_BaseEntity::OnPreDataChanged()
C_BaseEntity::PhysicsSimulate()
CPrediction::RunCommand()
- If the entity is a player:
C_BasePlayer::PreThink()
CPrediction::SetupMove()
CGameMovement::ProcessMovement()
CPrediction::FinishMove()
C_BasePlayer::PostThink()
CMoveHelperClient::ProcessImpacts()
- If the entity is not a player:
- Run physics simulation and
C_BaseEntity::Think()
- Run physics simulation and
- If data table has changed:
CPrediction::Untouch()
- Perform prediction. For every player movement command:
- Update view angles with input information
CPrediction::SetLocalViewAngles()
CHLClient::ExtraMouseSample()
Rendering
Rendering code sets up the view, updates all entities, and then renders the scene and user interface.
CHLClient::FrameStageNotify(FRAME_RENDER_START)
CInput::CAM_Think()
CViewRender::OnRenderStart()
CViewRender::SetUpView()
CBasePlayer::CalcView()
- For every player:
CBasePlayer::UpdateClientSideAnimation()
CMultiPlayerAnimState::Update()
ProcessOnDataChangedEvents()
- For every entity with data changed:
C_BaseEntity::OnDataChanged()
- For every entity with data changed:
- Update entities, tempents, particle systems, simulate physics, call ClientThink() functions
CHLClient::View_Render()
- Draws world and then UI
CHLClient::FrameStageNotify(FRAME_RENDER_END)
Sound
Код обработки звука и воспроизведение звуков на клиенте. Это не делает вызовы в коде игры.
Client HUD update
Эта секция вызывает:
CHLClient::HudUpdate()
- Обновление HUD и игровых систем