Networking Code Design. Who knows about User Input? Server/client code sharing.

Lately I’ve been working on some very basic game code.

I’m designing it to be a networked game from the beginning on. The problem I currently have is the question: Where does the User input information belong?

Let’s assume we have a server and two clients. Both clients have player entities which exist on the server and all clients.

When client 1 presses a key, it sends it to the server. Should the server send it to the other client?

Also, my question is also a little about code design.
I want to have the same code running on the server and both clients. But when I have my PlayerEntity, it expects Mouse input. But on client 1 I have both PlayerEntities from both clients, and it only has mouse input for one of them - the Player they are actually ment to play.

A possible solution I thought of was this: Every client already has a unique connection ID. Whenever a client creates an entity, the entity will be dedicated to a connection ID, if it needs to have specific client input, or not, when it’s an enemy for example (spawned by the server).
The client sends it’s input to the server and the server sends Input Deltas in the form of: Connection ID -> Mouse Input. All clients know of the inputs of all other clients and therefore they can even predict the movement of a player.

My actual question is: How would you solve it? How did you solve it? How do AAA games solve this problem?

Have you even had this problem?

… I could continue forever ::slight_smile:

I’m going to be quick, ask questions or for further explanation if you would like that and I’ll respond within a couple of hours. I have a really big head-ache and am quite tired right now.

You don’t need to design your game\engine with networking in mind. When I was developing JevaEngine, there was no consideration for networking. The networking isn’t apart of the engine or rpg game at all. It really shouldn’t be either because it obscures the purpose and function of the class with a bunch of networking and syncing code.

What you should do is design your entities so that they allow for Observers, using the Observer Pattern.

If you implement the observer pattern for your entities, you can observe them through another module (i.e, the server) and notify users of your observations. The users will then mutate their local entities to sync up with the server.

That is almost the right idea, the problem with doing it at such a level you describe (syncing input) is it is incredibly difficult to maintain synchronization through that method and it works on a much too abstract level for the server to optimally distribute accross clients.

Intead, while observing your entities you catch observations you want to be synchronized (i.e, pressing somewhere to move to some point B) The entity will begin moving to B and the server can broadcast taht observation to clients.

Here is how moving works in JevaEngine:

The client character class attempts to travel to point B. The client will dispatch a message telling the server that it would like to move to point B. The server responds by moving it’s corresponding player entity to point B (notice at this point the client’s player entity hasn’t actually moved yet.) The server will then notify the client of the mutations performed on the server-side entities and where it is moving. I.e, the client should never mutate an entity’s state unless it is told to by the server.

Sorry I am brief I have a killer head ache right now.

Send commands not raw input. Raw input is improper because it does not provide an appropriate level of abstraction. Individual objects should not care if I pressed the up, W, I, or 8 key or if I used the mouse or if I used a touch screen gesture. If you can, then aggregate multiple commands and remove canceled commands before sending them to reduce bandwidth. Your commands should be enough to reproduce a game on any client for the purposes of synchronization, debugging, or replay “videos” no matter what input method the user has. (Or even if their is no user, such as on a server or for an AI.)

Okey. Send commands, don’t send raw input, got it :slight_smile:

Also, I should then synchronize those commands on all clients.

In the Entity logic I use commands instead of raw logic.

Thank you :slight_smile:
I’ll post back if something isn’t completely clear for me yet.