There are different level of Entity System that you can use and they don’t all do the same thing.
- A first version of an Entity System is a system that will sort all your Entity for you automatically and when you want to get any Entity you just do something like getEntity(EntityID).
I don’t really like that because it implied that you don’t have any control of how your things are stored in the data structure and that’s one of the biggest performance issue. If you want good performance, the first thing you need to do is having good data structure (or the appropriate one).
Of course if you have an intelligent enough Entity System that will sort it all magically for you in the best possible way it will increase your performance, but that’s just fantasy.
- A second version of an Entity System is a system that will give you the ability to automatically save your world into a file or a database, which can be really useful if you have a permanent world or saved option. Another characteristics that often come with those design is that you can modify nearly everything in your game while the game is running which is really practical for a server application that can’t shutdown without frustrating user. (Check Java Debug Mode for some explanation. You can also go further and you only need to change the data in some file that are read by the server to change the behavior of the game).
While this type of Entity System could be really useful or even necessary for permanent world like MMO I don’t really see the point of using it if you don’t need those functionality (which is the case for most of the game we are making). It also add a lot of complexity in designing your structure and code for the game as well as a lot of verbose to your code making it slower to code and harder to read.
- The last type of Entity System are system doesn’t rely on any external code or library. It’s simply a new way to organize your code which make it a lot easier to understand. The idea is the same as with any Entity System : put every separate functionality into it’s own class (let’s call it a module).
Here is an example :
You have a gigantic class Unit that does a lot of things. Moving, attacking, receiving damage, gathering things, hitting obstacle, etc. That class became so big that it’s really hard to understand what happen in it and you might always be wondering what part of the code do what functionality. The solution to that is to split the class.
Main class : Unit
Module 1 : Movement
Module 2 : Attack
Module 3 : DamageReceived
Module 4 : Gathering
Module 5 : HittingObstacle
etc.
Now it’s really easy to understand what each class does because it only do one thing so all the code in it is related to that functionality.
But there is still problems with that design : where do you store the data relative to the Unit. If you put it in the module that needed them you will soon realize that many module might interact with the same data which is problematic. If you put it in the Unit class, you will have to put getter and setter for everything in that class which is something that visibility teach us not to do. (Well in game programming I have a different opinion on that but it’s still good practice to put as low visibility as possible.
So what is the solution?
I came up with a design of my own to solve that problem. Basically I create a UnitData class that contains all the information on that Unit and every field in that class is public! Might sounds crazy at first but it’s not. The only class that will have access to the class UnitData is the Unit class and the modules. So the class UnitData is private to the UnitEntity and it’s module. That give you the flexibility of working within the same big class as well as having better code organisation that is easier to understand.
Now if you understand perfectly well with your gigantic class, keep working that way.
So in conclusion, it’s not all Entity System that might be useful for you. I only use the third version myself because I prefer to know how my Entity are store in the data structure and decide how I want to access them and I don’t need to have complex saving functionality.
N.B. : I wonder if we could put different functionality in different thread to increase performance on multi core system but that’s too complex to be worth trying :S and functionality often need to be updated one after another.