I'm going to put this here both as a note to myself and as a way of getting commentary on this from anybody who is interested in player physics, server-side. Please do correct me if anything is wrong here.
So how does player physics work? At the very base are the CUserCmds that are fed into the server. CServerGameClients (I will be referring to these by implementation, not interface) gets these through ProcessUsercmds() and passes them on to CBasePlayer's ProcessUsercmds(). They're buffered there. Now there comes a time when GameFrame() is called in CServerGameDLL. The call chain of interest is: CServerGameDLL::GameFrame() Physics_RunThinkFunctions() Physics_SimulateEntity() CBasePlayer::PhysicsSimulate() Now is where the CUserCmds are actually used. For each CUserCmd, this happens: Each CUserCmd is passed into CBasePlayer::PlayerRunCommand(). CPlayerMove::RunCommand() is called, calling these three: CBasePlayer::SetupMove() [prepares the CMoveData] CGameMovement::ProcessMovement() [updates pos, vel, etc.] CBasePlayer::FinishMove() [copies the updated data back] The VPhysics shadow object is updated with new pos and vel. Ok then, all CUserCmds are processed. Then, CServerGameDLL::GameFrame() calls IGameSystem::FrameUpdatePostEntityThinkAllSystems(), and this happens: CPhysicsHook::FrameUpdatePostEntityThink() PhysFrame() In this function, the entire physics environment is first simulated. Then, CBasePlayer::VPhysicsShadowUpdate() is called. This is where the fun stuff is, where the player entity's position is reconciled with what the physics system thinks it is. Then, after all this, data is sent off to the client, yadda yadda. **** SO **** What's the moral of the story? Here's what I get out of the code: For player movement, what happens is that player's aren't really physically simulated at all! Everything (movement, gravity, swimming, etc.) is handled by the CGameMovement class. With every CUserCmd: 1. CGameMovement "simulates" the player and derives new pos/vel. 2. A physics "shadow object" is updated with the new pos/vel. This happens for every CUserCmd. Then, after all the CUserCmds have been processed that frame, the physics simulation actually occurs. At this time, _all the VPhysics shadow updates for that frame are processed at once_. Let's say, there were 3 CUserCmds from the player processed this frame, then the 3 shadow state updates will happen sequentially in the same frame. After physics simulation occurs, the player entity is reconciled with the VPhysics entity. Any VPhysics damage or position/velocity differences are copied back into the entity. Then the ent data is packaged and shot off to the clients. **** QUESTIONS **** 1. Are we guaranteed only 1 CUserCmd processed per frame? **** OTHER THOUGHTS **** I haven't seen any GoldSrc code before, but I suspect that the only way to _exactly_ reproduce GoldSrc player physics would be some crazy coding in VPhysicsShadowUpdate(), or even stripping the player of VPhysics simulation entirely. You'll likely do a _lot_ of copy-pasting of GoldSrc code either way. I think, to be honest, that you'll have to go the latter route (nuking VPhysics) because there's no way that VPhysics will exactly reproduce GoldSrc physics. You'll have to do it all in CGameMovement. John Sheu _______________________________________________ To unsubscribe, edit your list preferences, or view the list archives, please visit: http://list.valvesoftware.com/mailman/listinfo/hlcoders