I have designed an entity system for an FPS. It basically works like this:
We have a "world"-object, called GameWorld. This holds an array of GameObject, as well as an array of ComponentManager.
GameObject holds an array of Component. It also provides an event mechanism which is really simple. Components themselves may send an event to the entity, which is broadcasted to all the components.
Component is basically something that gives a GameObject certain properties, and since GameObject is actually just a container of them, everything that has to do with a game object happens in the Components. Examples include ViewComponent, PhysicsComponent and LogicComponent. If communication between them is needed, that can be done through the use of events.
ComponentManager just an interface just like Component, and for each Component class, there should generally be one ComponentManager class. These component managers are responsible for creating the components and initializing them with properties read from something like an XML-file.
ComponentManager also takes care of mass updates of components, like the PhysicsComponent where I will be using an external library (which does everything in the world at once).
For configurability, I will be using a factory for the entities which will read either an XML-file or a script, create the components specified in the file (which also adds a reference to it in the right component manager for mass updates), and then inject them into a GameObject object.
Now comes my problem: I am going to try to use this for multiplayer games. I have no idea how to approach this.
Firstly: What entities should the clients have from the beginning? I should start with explaining how a single-player engine would determine what entities to create.
In the level editor you can create "brushes" and "entities". Brushes are for things like walls, floors and ceilings, basically simple shapes. Entities are the GameObject I have told you about. When creating entities in the level editor, you can specify properties for each of it's components. These properties are passed directly to something like a constructor in the entity's script.
When you save the level for the engine to load, it is decomposed into a list of entities and their associated properties. The brushes are converted into a "worldspawn" entity.
When you load that level, it just instanciates all the entities. Sounds simple, eh?
Now, for networking the entities I run into numerous problems. First, what entities should exist on the client from the beginning? Assuming that both the server and client has the level file, the client could might as well instanciate all the entities in the level, even if they are there just for the purposes of game rules on the server.
Another possibility is that the client instanciates an entity as soon as the server sends information about it, and that means that the client will only have entities that it needs.
Another issue is how to send the information. I think the server could use delta-compression, meaning that it only sends new information when something changes, rather than sending a snapshot to the client at every frame. Though that means that the server must keep track of what each client knows at the moment.
And finally, how should networking be injected into the engine? I'm thinking a component, NetworkComponent, which is injected into every entity that is supposed to be networked. But how should the network component know what variables to network, and how to access those, and finally how the corresponding network component on the client should know how to change the networked variables?
I'm having huge trouble approaching this. I would really appreciate if you helped me on the way. I'm open to tips on how to improve the component system design too, so don't be afraid of suggesting that.