Game Movement

From Garry's Mod
(Difference between revisions)
Jump to: navigation, search
(Some cleanup, added links)
 
Line 1: Line 1:
Getting your head around how the game movement system works isn't easy. Here I will try to explain it.
+
Getting your head around how the game movement system works isn't easy. This page will try to clarify on what goes on.
  
 
= User Command =
 
= User Command =
  
The client creates a user command. A user command is created by looking at the player's keys and mouse activity. This is done in the {{HookFunction|GM|CreateMove}} hook.
+
The client creates a user command ({{Type|CUserCmd}}) which is created by looking at the player's keys and mouse activity. This is done in the {{HookFunction|GM|CreateMove}} and {{HookFunction|GM|StartCommand}} hooks.
  
This user command is then sent to the server. In a multiplayer game this is also used locally to predict the player's movement.
+
This user command is then sent to the server where StartCommand is again run. In a multiplayer game the user command is also used directly locally to predict the player's movement.
  
 +
StartCommand is a good place to change controls (prevent movement, etc) since everything else down the line depends on what happens there and it is run on both the client and server which is necessary to prevent clients from bypassing your changes.
  
= SetupMove =
 
  
The SetupMove hook is used to transfer data from the User Command to the MoveData structure, and set the origin/velocity of the entity you're moving (probably the player). The User Command's job is then finished.
+
= SetupMove =
  
This is called on the server - and also in multiplayer - on the client. If prediction is happening properly then given an identical user command on client/server - the outputted movedata should be identical too.
+
The {{HookFunction|GM|SetupMove}} hook is used to transfer data from the user command to a {{Type|CMoveData}} structure, and set the origin/velocity of the entity you're moving (probably the player). The user command's job is then finished.
  
This is a good place to change controls. For example - if you don't want a player to jump.. you can remove the jump button from the MoveData here. This has advantages over removing it from the usercommand in CreateMove - because it's controlled by the server - not the client.
+
This is called on the server - and also in multiplayer - on the client. If prediction is happening properly then given an identical user command on client/server - the outputted move data should be identical too.
  
 
= Move =
 
= Move =
  
The move hook does the brunt of the work.. but it should ONLY change the movedata structure. This is because SetupMove and Move can be called multiple times to work out prediction errors.  
+
The {{HookFunction|GM|Move}} hook does the brunt of the work. It should ''only'' change the move data structure. This is because SetupMove and Move can be called multiple times to work out prediction errors.  
  
 
So in this hook you would look at the MoveData structure, move its origin based on its other factors (buttons down, velocity etc). You'd also be doing things like collision detection here.
 
So in this hook you would look at the MoveData structure, move its origin based on its other factors (buttons down, velocity etc). You'd also be doing things like collision detection here.
  
 
<pre>
 
<pre>
function GAMEMODE:Move( ply, mv )
+
function GM:Move( ply, mv )
  
 
-- Get some variables for easy access
 
-- Get some variables for easy access
Line 43: Line 43:
 
= FinishMove =
 
= FinishMove =
  
The FinishMove hook is where you should actually apply the changes from the movedata into your entity.
+
The {{HookFunction|GM|FinishMove}} hook is where you should apply the changes from the move data onto your entity.
  
 
<pre>
 
<pre>
Line 60: Line 60:
  
  
= Or just use the Drive System =
+
= The Drive System =
  
The drive system was invented to make this all more modular, and make it so you can control not only the player - but other objects too.
+
The {{Lib|drive}} system was invented to make this all more modular, and make it so you can control not only the player - but other objects too.
  
 
[[Category:Modding Tutorials]]
 
[[Category:Modding Tutorials]]
 
[[Category:Lua Reference]]
 
[[Category:Lua Reference]]

Latest revision as of 22:21, 6 September 2019

Getting your head around how the game movement system works isn't easy. This page will try to clarify on what goes on.

Contents

User Command

The client creates a user command (CUserCmd) which is created by looking at the player's keys and mouse activity. This is done in the GM:CreateMove and GM:StartCommand hooks.

This user command is then sent to the server where StartCommand is again run. In a multiplayer game the user command is also used directly locally to predict the player's movement.

StartCommand is a good place to change controls (prevent movement, etc) since everything else down the line depends on what happens there and it is run on both the client and server which is necessary to prevent clients from bypassing your changes.


SetupMove

The GM:SetupMove hook is used to transfer data from the user command to a CMoveData structure, and set the origin/velocity of the entity you're moving (probably the player). The user command's job is then finished.

This is called on the server - and also in multiplayer - on the client. If prediction is happening properly then given an identical user command on client/server - the outputted move data should be identical too.

Move

The GM:Move hook does the brunt of the work. It should only change the move data structure. This is because SetupMove and Move can be called multiple times to work out prediction errors.

So in this hook you would look at the MoveData structure, move its origin based on its other factors (buttons down, velocity etc). You'd also be doing things like collision detection here.

function GM:Move( ply, mv )

	-- Get some variables for easy access
	local ang = mv:GetMoveAngles()
	local pos = mv:GetOrigin()

	-- If Jump is pressed, move pos forwards
	if ( mv:KeyDown( IN_JUMP ) ) then pos:Add( ang:Forward() * FrameTime() * 0.001 ) end

	-- Save the calculations back into the origin
	mv:SetOrigin( pos )

	-- Don't do the default
	return true

end

FinishMove

The GM:FinishMove hook is where you should apply the changes from the move data onto your entity.

function GM:FinishMove( ply, mv )

	--
	-- Move the player to the worked out position
	--
	ply:SetNetworkOrigin( mv:GetOrigin() )

	-- Don't do the default
	return true

end


The Drive System

The drive library system was invented to make this all more modular, and make it so you can control not only the player - but other objects too.

Personal tools
Navigation