Violent agreement on that point. In fact, I’d say even a complex game done by one developer can dispense with most of these complex abstractions. It would seem to be when you need to experiment with different designs without undergoing rewrites of the base system that fancy component systems come in handy, such as if you have an engine that isn’t rewriteable by people who aren’t source licensees.
Alright, I appreciate all the posts you’ve guys have made. You helped me alot as in this if my first time making an entity system. I’m sorry I guess I didn’t know you guys didn’t have the same definition as me, but anyways what would a good way be to this for a 2D game. I’m trying to handle movement, collision, level, stats. Every “Entity” should have them. So would I would have an Entity class that would contain all the entities, such as player, npcs/monsters and then each of them would have there own classes? How would this look?
Roquen’s should I use component based algorithm:
- Can I make a comparison and contrast of component based and prototype based, if no return no.
- Can I list at least 3 methods of design by composition, if no return no.
- Do I expect millions of active entities, if no return no.
- Am I writing in a language that support linear access to memory and caching hints, if no return pfff…hard call.
Any questions?
<-- What Roquen said.
And also - If you want to learn how to make entity systems for the purposes of just learning about them, Java is not a great choice, as it makes all the most important bits of entity systems extremely difficult and fiddly to do.
Cas
Yeah…go JavaScript or Lua.
What important bits are you talking about?
Can you give an example?
Is it because in many scripting languages, objects behave like hash maps but in Java you have to use hash maps explicitly?
Composition in Java is a joke. You can work around it by writing huge piles of boilerplate code and creating millions of superfluous objects.
The memory layout in Java defeats the entire purpose of entity systems. You can work around it with arcane rituals with mapped objects and flyweight patterns.
Cas
I think you are vastly exaggerating there. Of course Java syntax is more verbose than that of a scripting languages and hash maps are less comfortable to use but that’s about it. And what does memory layout have to do with an entity system? The memory layout describes what data is stored in what part of ram. In Java and also in scripting languages the memory layout is not even visible to the programmer.
The only plausible bullet point in favor a component based vs. other techniques is the ability to perform high processing rates by data segregation and linear ordering. And this is really only if you squint your eyes and don’t think too much because neither of these require a component based model.
As for verbosity, I’ve never seen a real component based implementation in Java that wasn’t horrible on the eyes. The lack of operator overloading (notable getters and setters) is a real hindrance. So IHMO if you want to play with these types of design models it seems like a good idea to do it in a language that designed for these types of abstractions rather than fighting the main design points of Java (class based + strong typing).
See below:
You’re only going to get this if you have control over the memory layout. If you read the T-Machine article on entity systems, the primary benefit being touted is the reference locality you get from slicing just the components you need, which is an awful nice thing if you’re targeting something like the PS3 where random fetches are death to performance.
You’ll also notice that it doesn’t espouse doing all this low-level frippery by hand, but having a good toolchain that supports component assembly instead. Unfortunately the article is handwavey enough on the implementation details that it seems to have been taken as a generic anti-OO rant, and I confess that’s how I read it the first time too.
I’ve seen millisecond gains, even with just 1000s of entities, when converting to a framework that does mapped objects. When you’re limited to 16ms for a single frame, a millisecond here and there is pretty important. You don’t have to wait until you’re processing millions of entities for the performance to become worth it.
I agree that Java doesn’t make it the easiest to apply entity-component systems, but I think the decoupling data from methods can lead to more flexible design. Sure this isn’t the only way to do it, but it is a way. But if you’re new to development and don’t care about that sort of thing, then it’s not very important to get it either.
As an example of why I decided to use components for my games is in material description: I have components for describing the different sources of diffuse coloring, they can optionally add emissive textures, or normal maps to turn on bump-mapping. They can use a different lighting model than Blinn-Phong but that still requires diffuse/specular colors. This can be conveniently described with a proper set of components.
Yes. Minimizing memory motion (and related issues like cache invalidation) are always a win. My 1 mill number stems from when you get to very high loads it gets to be super fiddly if you really want to maximize throughput. And in this situation using a well built component based systems “might” make sense.
Personally if I were to walk this path I’d punt and write a DSL. Also since Java doesn’t current support structures and arrays of structures I’d build on top of C or C++.
WRT: Material system. I’m not getting your point. What does that have to do with a component based model?
I found it to be a useful reason in my case to use a component based system, even if I don’t need the performance. It was mainly to point out that it is possible to find circumstances where the entity-component model isn’t useful purely for serious performance reasons. I could, and previously did, put all of my material logic into various OO types but they always progressed into a component model, so for me the performance gained from a mapped-object entity system is just extra win.
Hmm… you sure you’re not really just talking about composition rather than the whole “entity system” concept?
Cas
Sure, any other way of composing material descriptors could and would work. But when you have a problem that can actually be solved by composition, why not use an entity-component framework? It’s one possible solution and if it jives with the way you think, why not use it?
I dont use an entity sytem cause:
-only a few hundred entities
-dont need to change the game at runtime cause i am the only one involved and i have the debugger anyway
-dont need scipting support cause nobody willl write mods for the game and java compile time is irrelevant
-dont want to learn or create another engine wich is maybe fun but also stop me from coding the game
So instead i do composition over inheritance and avoid deep inheritance hierarchy wich is imho best practise.
i think the points are valid for most projects in this forum.
To make a brief nod to the OP. There are two problems in attempting to answer your question. The first is that there will major lack of agreement regardless (as you’re seeing). And the second is that it’s an impossible to answer question without know what your background is and what it is that you want to do.
I usually make an ArrayList of a class called Entity that all of the other entities extend. Then, I use a comparator to order the list according their y positions so that they’re drawn in a fashion where the lower objects are drawn over the higher ones.
My Entity class has x & y locations, an image, an enum of EntityType which tells me if it’s a player object, opponent object, player projectile, opponent projectile etc. My entity class also has hit points so I know how much damage it can take. Entity does not move. About the only time I use this base class by itself is if I want to place an object on the background. That object doesn’t move and usually has no collision properties. Entity has getImage() doUpdate(container, game, delta) and doRender(Graphics g) which all other entities inherent. It also has some booleans such as isCollidable and isVisible so I can turn collisions on and off and make them visible or not.
The Entity class also has my collision rectangles. Normally it’s just the rectangle of the image but I also have a list of rectangles which I use for oddly shaped sprites. Rectangle collision detection is fast and easy. Java’s Rectangle2D.Float extends RectangularShape which has the method public boolean intersects(Rectangle2D r) which is fast and precise enough for my needs.
Then I have a MovableEntity object which extends Entity. That has dx/dy speed, acceleration rate , deceleration rate and max speed.
I have a Startable entity which extends MoveableEntity. This is a class where I can set my dx/dy but not have the entity move until I give it the start command. This way I can set up objects offscreen and start them moving into the screen when I want to.
I also have ControllableEntity which extends MoveableEntity. This entity can be bound to keyboard or game controller events and can change the dx/dy, speed, and acceleration of the entity.
I recently added AnimatedEntity which will go between Entity and MoveableEntity. This way I can animate any of my entities as I do other things as well.
I created a Projectile class which extends MovableEntity. The Projectile knows if it has moved offscreen and if so places itself back into the bullet pool. Things which extend Projectile overload the image in the base class Entity with a static image so all the projectiles of a single type are using the same image in memory.
I place different entities in different Arraylist. My GameLevel class has these list:
private ArrayList<Entity> backgroundEntityList = new ArrayList<Entity>();
private ArrayList<Entity> midLevelEntityList = new ArrayList<Entity>();
private ArrayList<Entity> opponentEntityList = new ArrayList<Entity>();
private ArrayList<Entity> postOpponentEntityList = new ArrayList<Entity>();
private ArrayList<Entity> playerEntityList = new ArrayList<Entity>();
private ArrayList<Entity> postPlayerEntityList = new ArrayList<Entity>();
private ArrayList<Entity> hudEntityList = new ArrayList<Entity>();
private ArrayList<Entity> messageEntityList = new ArrayList<Entity>();
private ArrayList<Entity> playerProjectileEntityList = new ArrayList<Entity>();
private ArrayList<Entity> opponentProjectileEntityList = new ArrayList<Entity>();
These list allow me , for example, to draw all the background images, player images, opponent images, etc all in correct Z order. The 2 projectile list in particular make it easier to pool bullets. The postPlayer and postOpponent list allow opponent images to come out of caves which the player can fly over, or for the player to fly under a bridge.
The HUD list always paints next to last so the HUD (Heads Up Display) is on top of everything.
The Message list paints last. I use this for menu items and messages which need to paint on top of everything.
In my game loop I walk through every list in order and call the doUpdate of every entity. Then I do the same thing with doRender and it all works by itself.