Usercmd
CUserCmd ("user command") is the networkable representation of the player's input, including keys pressed and viewangle. By default, updates are sent from client to server at a rate of 30 per second (cl_cmdrate) in the form of delta-compressed usercmds. Delta compression and decompression are handled in WriteUsercmd
and ReadUsercmd
.
Production
Usercmds intended for transmission to the server are created when the engine invokes IBaseClientDLL::CreateMove
(once per tick). The usercmds created are stored in a circular buffer (CInput::PerUserInput_t::m_pCommands
) until the engine invokes IBaseClientDLL::WriteUsercmdDeltaToBuffer
to compress and serialize them to the server.
The current client mode is also given a chance to manipulate the newly created usercmd via IClientMode::CreateMove
. The default implementation (ClientModeShared::CreateMove
) delegates to the local player via C_BasePlayer::CreateMove
, which in turn passes the usercmd to CBaseCombatWeapon::CreateMove
on the active weapon.
IBaseClientDLL::ExtraMouseSample
, which can be run by the engine between calls to CreateMove
, executes most of the same client code. However, in this case, the generated usercmd is effectively discarded after being used to update CPrediction::SetLocalViewAngles
.The default implementations of both of these IBaseClientDLL
methods in class CHLClient
delegate almost all of the work to the IInput
interface.
Consumption
Server
The incoming usercmds are consumed on the server when the engine invokes IGameServerClients::ProcessUsercmds
. This method handles decompressing the delta usercmds, and then dispatches them to CBasePlayer::ProcessUsercmds
. The player caches each such batch of commands together in a CCommandContext
object to be processed later.
Once IServerGameDLL::GameFrame
is called, the player's PhysicsSimulate
method executes the cached usercmds via CBasePlayer::PlayerRunCommand
. From here, the active CPlayerMove-derived class executes (pre/post)think for the player, as well as populating g_pMoveData and executing IGameMovement::ProcessMovement
for the player.
Client
The code path for most things that occur during client prediction is very similar to the equivalent server code path, but the entry point from the engine is IPrediction::Update
.
CPrediction::RunSimulation
invokes the client implementation of C_BasePlayer::PhysicsSimulate
on the local player. From here, the player calls back into CPrediction::RunCommand
, which very closely mirrors the server PlayerRunCommand
functionality: pre-think, think, game movement, and post-think are all executed for the local player using the values from the outgoing usercmd (stored in C_BasePlayer::m_CommandContext
).