Yes, send an event when a key state
changes or you press the fire button and so on. I would set it up like this:
- Client sends key events to server and simulates motion and actions locally (immediately)
- Server receives key events and changes player state internally, setting them in motion, turning or stopping them as required. Server also sends these events to all other clients (excluding the origin client)
- Other clients simulate motion and actions for the other players using the information they have
- Occasionally the server sends the current state of all player objects to all clients, syncing the game. All clients overwrite their locally simulated player positions and headings using this new information. This also includes the player object associated with that client. The sync time can be tweaked (around couple hundred ms, maybe?)
You can play around with the sync time depending on how twitchy the movement and gameplay is. Lower values are obviously better as long as it's not a constant stream of packets. It also depends on how many clients you have on each server.
You might also want to use TCP to send key events to server to make sure they get there, use UDP to broadcast these events to other clients from the server (as it has less priority as long as sync happens) and use TCP to send syncronization packets.
Obvious optimizations apply too, so don't send turning and moving events to all clients if they can't possibly see them. Only the weapon firing and other things like that.