A PlayerController takes input from the user and moves the player.
The simplest controller is a noclip controller. It moves the player relative to the direction they're facing.
The BasePlayerController class has a number of persistent common properties such as Position, Rotation, Velocity, GroundEntity. Note that Pos and Rot are deprecated.
To set the player controller on a player you can set the Controller property. You can do this in Respawn, or the player's constructor.
You can change this property at any point during the game to give the player a different controller. Or set it to null if you don't want the player to move.
The Player Controller shouldn't really ever access the player directly. It can, but it probably shouldn't.
The Player Controller is run on both the local client and the server.
When the Client gets the results from the server, it compares them. If they don't match it snaps the client back to what the server said it should be.
Your controller should always generate the same results on the client and server. This means that if you use a random number generator in your controller, it should produce the same value on the server and client.