I'm thinking something along those lines Heldenhaft, though not sure about what network library to use yet.
I guess I'll give a quick overview of what I'm experimenting with at the moment.
1. Entity System.
The basic idea behind an entity system is to represent entities as a composition of components. Components only contain data (no logic), and entities themselves are just identifiers used to group them. For example a GelatinousCube may have a Location component for where it is in the world, a Collision component for how it collides, a Mesh component to display it, a MovementController to hold movement directions, and an AIBehaviour to hold behavioural state.
Then you have a number of systems, each of which work across entities with a desired set of components. A Renderer system would render entities with both a Location and Mesh component for instance.
One of the major benefits of an entity system is the use of composition to produce different behaviours. It becomes possible to add new items, monsters, and so on simply though different compositions of components and different settings for those components. Take a gelatinous cube, add a particle effect component producing fire particles and increase the scale on the mesh component you can get the dreaded Giant Fire Cube for instance. More advance modding can introduce new systems and/or components as well.
I've rolled my own implementation for the moment, while I experiment with things. It probably can be improved with some of the Artemis performance trickery at some point. A version built on some sort of database (perhaps OrientDB) may provide some interesting features too.
2. Event System
Working hand in hand with the Entity System, I've started putting together an event system that allows you to "send" an event to an entity, which is propagated to event handler systems that have subscribed to events where particular combinations of components are present.
For instance, you could have a UseEvent that is sent when a player interacts with an item in the world:
Code:
public class UseEvent implements Event {
public EntityRef user;
}
And register an EventHandler that reacts to UseEvents on entities with an ItemDispenser component:
Code:
public class ItemDispenserSystem implements EventHandler {
@ReceiveEvent
public void onUse(UseEvent event, EntityRef entity, ItemDispenserComponent component) {
// ... Functionality goes here
}
}
Then you just send the events against the entities and the correct systems get propagated the events.
I'm still messing with how exactly this should work, and there are some considerations I still need to explore (how do you handle the case where you have a lock component + event handler that should intercept the UseEvent and stop it reaching other systems? Priority + boolean return value to end the event?).
One thing I have done is added events around Component lifecycle events - when they are added to an entity, removed from an entity or updated.
3. Prefabs
This is the other core element for the entity system - a way to define recipes for entities that can be instantiated. Basically these are very similar to entities - groups of components - except they are never processed, only copied to create new entities. One thing is that components should be allowed to have references to prefabs so they create them - for instance a projectile weapon could have a reference to the prefab for the projectiles it shoots.
These can be set up to be defined in groovy config files.
Multiplayer
I've been musing about how this may work in a multiplayer game. Systems are probably fairly simple - you'ld have some systems that would only run on the server or client, and others that run on both but may behave a bit different depending on where they are.
Each component may also either be marked up or have some simple methods to determine whether they need to be replicated from server to client, and which properties need to be replicated, perhaps something like:
Code:
@ReplicatedComponent
public class Player implements Component {
@Replicate(onCreateOnly=true) public String name;
@Replicate public int score;
public String password;
}
A somewhat artificial example, onCreateOnly means it only needs to be sent when the Component is first added or the Entity becomes relevent for a player, and is otherwise constant. There may also be a specific component to provide additonal replication information or to say a given entity should be replicated at all. Then a central system would replicate new or changed entities to players, if the entites are relevent and at a rate that won't flood the network.