Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Component based game objects  (Read 8757 times)
0 Members and 1 Guest are viewing this topic.
Online theagentd
« Posted 2011-10-03 10:29:57 »

Hello, I've gotten to the point where I need to design a good system for handling my game objects. It should be a pretty simple problem as I don't have that many things to worry about, but I can't decide on a good system to use. Some people seem to religiously use a hardcore component system, where a GameObject is just a list of Components. They even seem to keep position and graphics in Components! I don't really understand how I actually link everything together, both inside GameObjects (Component - Component communication) and Game - GameObject communication (where is the render() method? xD) in such a system, and it seems overly complex for a RTS game, which is what I'm making. I believe that every object needs to have certain features, like positions, movement and graphics, but some things are optional, like item inventory, some abilities (AI mostly), e.t.c. I've tried looking at articles and stuff on this topic, but they don't seem to actually contain much information besides how awesome component based systems are. I found this article though: http://obviam.net/index.php/design-in-game-entities-object-composition-strategies-part-1/ which I thought was pretty good.

I think I'll have some needed components like in the droid class, but also some optional things so I'll also have a Component list too.

Why is this so complicated?! Does anyone know of a good tutorial or article on game object systems, especially in RTS games?

Myomyomyo.
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 77
Projects: 15


★★★★★


« Reply #1 - Posted 2011-10-03 10:37:57 »

Have a look at the Artemis Entity System. The page also includes a link to an articles about this on t-machine.org.
Online theagentd
« Reply #2 - Posted 2011-10-03 11:26:13 »

Ah, I see. The mini tutorial kind of explains a lot! If you have used Artemis, would you mind explaining some things on how to use it?
 - Entities have Components, which contain data but no logic for processing it, correct?
 - EntitySystems process Entities that have the required Components, correct? How does an EntitySystem know which Entities it can/should process?
 - Is this line a typo?
1  
super(Transform.class, Velocity.class); // Components represent the aspect

Transform.class = Position.class?

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

JGO Kernel


Medals: 365
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #3 - Posted 2011-10-03 12:33:51 »

Bleh, massive overkill. And of dubious efficiency. A shallow class hierarchy will do you just as well with a fat base class.

Cas Smiley

Offline Cero
« Reply #4 - Posted 2011-10-03 12:41:22 »

Bleh, massive overkill. And of dubious efficiency. A shallow class hierarchy will do you just as well with a fat base class.

+1, that's what I do =D

Online theagentd
« Reply #5 - Posted 2011-10-03 13:24:20 »

I agree that it seems kind of overkill in some ways, but at the same time it seems incredibly powerful. I just got a basic test (the one on the website) working after fiddling a bit. I like the concept... ._.
The reason I like it is that I don't really have a complete plan on how I want to do this yet, and this seems easier to handle and edit later. I think the code will look nice at least. xd And also (assuming this is a good implementation of a component based system) wouldn't it be a good idea to try this out? I mean, I'm curious! =S If you guys say that this sucks and I should turn around and run as far as I can from it, I won't use it, but at the moment it seems really attractive.
Pros:
 - Powerful (?)
 - Pretty easy to use (?)
 - Easy to edit later (?)
 - A good learning experience (?)
Cons:
 - Overkill (too complex for what I'm doing?)
 - Performance (?)

Myomyomyo.
Offline pitbuller
« Reply #6 - Posted 2011-10-03 14:06:49 »

I agree that it seems kind of overkill in some ways, but at the same time it seems incredibly powerful. I just got a basic test (the one on the website) working after fiddling a bit. I like the concept... ._.
The reason I like it is that I don't really have a complete plan on how I want to do this yet, and this seems easier to handle and edit later. I think the code will look nice at least. xd And also (assuming this is a good implementation of a component based system) wouldn't it be a good idea to try this out? I mean, I'm curious! =S If you guys say that this sucks and I should turn around and run as far as I can from it, I won't use it, but at the moment it seems really attractive.
Pros:
 - Powerful (?)
 - Pretty easy to use (?)
 - Easy to edit later (?)
 - A good learning experience (?)
Cons:
 - Overkill (too complex for what I'm doing?)
 - Performance (?)

Performance shoud be better not worser.
Online theagentd
« Reply #7 - Posted 2011-10-03 14:14:25 »

I believe that would depend on how insanely nested another implementation would be VS the overhead of retrieving components, e.t.c.

Myomyomyo.
Offline princec

JGO Kernel


Medals: 365
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #8 - Posted 2011-10-03 14:26:42 »

Musing on recent posts about data-oriented programming I'd say that an entity system based on lots of little Java objects and interfaces is pathologically the worst case for performance. Of course you won't be worried about performance if you've only got a couple of thousand objects. But then if you've only got a couple of thousand objects why bother with entity systems like this in the first place eh?

Cas Smiley

Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #9 - Posted 2011-10-03 14:47:58 »

Of course you won't be worried about performance if you've only got a couple of thousand objects. But then if you've only got a couple of thousand objects why bother with entity systems like this in the first place eh?
For something like a roguelike you might have thousands of semi-procedurally generated creature types, made by plugging components together, but only a handful of them active on any given level.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline sproingie

JGO Kernel


Medals: 202



« Reply #10 - Posted 2011-10-03 15:08:42 »

Entity systems have certain advantages in C++ where with placement allocators you can control the layout of your data, and they take advantage of that layout optimization on consoles, which have less memory than any desktop PC.  Java does not let you lay out your objects by hand, so a super-fine-grained entity system may well do more harm than good as performance goes.

There's still something to recommend decomposition into components as flexibility goes.  Avoiding deep inheritance hierarchies is just plain good design, as is avoiding one-off subclasses regardless of depth.   To go with the roguelike example above, a roguelike as complex as, say, Nethack should be using some kind of Domain Specific Language (DSL) to customize behaviors, where you'd attach complex behaviors as scripts and/or declarative properties (Dwarf Fortress for example does the latter) and not design a new subclass for every single new kind of object or monster.
Offline lhkbob

JGO Knight


Medals: 32



« Reply #11 - Posted 2011-10-03 15:21:03 »

Entity systems have certain advantages in C++ where with placement allocators you can control the layout of your data, and they take advantage of that layout optimization on consoles, which have less memory than any desktop PC.  Java does not let you lay out your objects by hand, so a super-fine-grained entity system may well do more harm than good as performance goes.

I'm working on an entity-component system that is able to map most simple types, vectors, and matrices into primitive types and store those in arrays to get better cache locality (why C++ is better in this case); this is similar to Riven's MappedObjects although it doesn't use nio yet. I usually see speed ups of 2 to 8 times depending on the test run and the amount of processing.  Of course this won't help when you have to pass around Object references.  It should be done soon  persecutioncomplex

Online theagentd
« Reply #12 - Posted 2011-10-03 16:48:06 »

Musing on recent posts about data-oriented programming I'd say that an entity system based on lots of little Java objects and interfaces is pathologically the worst case for performance. Of course you won't be worried about performance if you've only got a couple of thousand objects. But then if you've only got a couple of thousand objects why bother with entity systems like this in the first place eh?

Cas Smiley
So having lots of small components would be terrible for performance... I see. So, how many and how big components are best for performance, and how big is the actual performance cost? I'll probably not need very many for each object, probably <10.

BTW, shouldn't/couldn't that be a JRE optimization...? >_<

Myomyomyo.
Offline tberthel
« Reply #13 - Posted 2011-10-03 16:54:41 »

I have the coolest game object ever:

https://github.com/AllBinary/AllBinary-Platform/blob/master/j2me/games/GameJ2MELibrary/src/allbinary/game/layer/AllBinaryGameLayer.java
https://github.com/AllBinary/AllBinary-Platform/blob/master/j2me/games/DamageGameJavaLibrary/src/allbinary/game/layer/special/CollidableDestroyableDamageableLayer.java

I have RTSLayer and AdvancedRTSLayer somewhere. Smiley

Note: My RTS game gets 60 fps on cheap hardware.

One thing I notice with many coders is casting to interfaces and abstract class usage.  Both destroy performance.  What you want is all concrete classes that implement interfaces instead like mine.  That way you get a component feel without getting the dynamic component performance.  Tongue

Offline princec

JGO Kernel


Medals: 365
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #14 - Posted 2011-10-03 18:23:29 »

That's not true, casting is virtually free, as is calling interface methods. At least it is on Android 2.2 and above, and any desktop version of Java since as long as I can remember.
<edit>Actually, I'm full of shit - I know for certain the desktop makes no difference but for Android I'm just going by Google's own performance tuning docs. That's what they say.

Cas Smiley

Offline JL235

JGO Coder


Medals: 10



« Reply #15 - Posted 2011-10-03 18:40:20 »

Bleh, massive overkill. And of dubious efficiency. A shallow class hierarchy will do you just as well with a fat base class.
Thirded.

An inheritance based approach solved the common case pretty well, so that's the bulk of your code sorted.

It's only in small, niche corner cases that it fails, and where component based systems prove to be a better alternative. But for the common case, it's more bulk, and more boiler plate (i.e. a lot of 'getComponent', and potentially some null checks).

But since your building an RTS, I would build it a little like a GUI system. Items can receive events, i.e. keyboard, mouse clicks or drag events, which are passed to the most likely elements in order of z-index. You could also have focus in built, again like a GUI, so keyboard events only go to certain units.

Offline Gudradain
« Reply #16 - Posted 2011-10-03 19:41:47 »

There are different level of Entity System that you can use and they don't all do the same thing.

1. 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.

2. 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.

3. 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.
Offline tberthel
« Reply #17 - Posted 2011-10-03 19:56:44 »

That's not true, casting is virtually free, as is calling interface methods. At least it is on Android 2.2 and above, and any desktop version of Java since as long as I can remember.
<edit>Actually, I'm full of shit - I know for certain the desktop makes no difference but for Android I'm just going by Google's own performance tuning docs. That's what they say.

Cas Smiley

The method calls are slower for interfaces and abstract classes.  If you don't believe me run a test on a J2ME or Android 1.6 or earlier device.  J2SE had the same issue.  I don't know if it has changed or not.  Technically it should be about 30% slower because of the extra table look up in most c/c++ implementation of Java that are used.  Not the actual casting.  You can cast all you want.  And you still should use interfaces just don't cast to them when calling methods that are called a bunch.


Offline princec

JGO Kernel


Medals: 365
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #18 - Posted 2011-10-03 20:18:13 »

J2ME and Android 1.x are dead, though. Especially as regards generally everyone developing games here on JGO, with the possible exception of yourself.

Cas Smiley

Offline Gudradain
« Reply #19 - Posted 2011-10-03 20:25:08 »

@tberthel. Just read the article that you link. It's nearly the same thing that I'm doing. It works great. Aggregation is indeed a way better option than simple inheritance.
Offline tberthel
« Reply #20 - Posted 2011-10-03 20:40:07 »

@tberthel. Just read the article that you link. It's nearly the same thing that I'm doing. It works great. Aggregation is indeed a way better option than simple inheritance.

I did not link an article.  I agree that you should use Aggregation/Composite over inheritance.  I still have it 4 deep though.

Offline tberthel
« Reply #21 - Posted 2011-10-03 20:46:24 »

J2ME and Android 1.x are dead, though. Especially as regards generally everyone developing games here on JGO, with the possible exception of yourself.

Cas Smiley

J2ME support has 1+ billion devices strong so it will never die.  In twenty years people will still have old BlueRay players that can run my games as JavaTV.

Android 1.x pretty small according to most but it still has more than 5% according to my high score servers.  Although, 1.0 - < 1.5 is pretty much gone.  So, it is still about 12 million or so 1.5 and 1.6 devices.

So you are correct that no one codes for them anymore except for me, but J2ME and early Android is far from dead.

Offline Gudradain
« Reply #22 - Posted 2011-10-03 21:53:14 »

Oups was talking about the link of theagentd
Online theagentd
« Reply #23 - Posted 2011-10-04 05:04:50 »

Since my main concern seems to be performance I made a small test, which might not be very accurate considering the results. Basically it's this code

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
//Initializing an entity
Entity e = world.createEntity();
e.addComponent(new Position(0, 0, 0));
e.addComponent(new Velocity(1, 0, 0));
e.refresh();

//In MovementSystem
Entity entity = entities.get(i);
Position p = positionMapper.get(entity);
Velocity v = velocityMapper.get(entity);
p.setX(p.getX() + v.getVX() * world.getDelta());
p.setY(p.getY() + v.getVY() * world.getDelta());
p.setZ(p.getZ() + v.getVZ() * world.getDelta());


vs a combined position-velocity component:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
//Initializing an entity
Entity e = world.createEntity();
e.addComponent(new PositionVelocity(0, 0, 0, 1, 0, 0));
e.refresh();

//In MovementSystem
Entity entity = entities.get(i);
PositionVelocity pv = pvMapper.get(entity);
pv.setX(pv.getX() + pv.getVX() * world.getDelta());
pv.setY(pv.getY() + pv.getVY() * world.getDelta());
pv.setZ(pv.getZ() + pv.getVZ() * world.getDelta());


I have 100k entities just updating movement. The results are weird:
With the Position + Velocity code, the FPS instantly goes to a stable ~501 FPS (1.996ms) and about 40 MBs of RAM usage.
With the combined component code the FPS sits at ~440 FPS and memory usage at about 27 MBs. Huh After running it for about 30 seconds it suddenly starts running at ~493 FPS (2.028ms) and RAM increases to 40MBs, very similar to Position + Velocity but still slightly slower. Well, 1 vs 2 components isn't a very realistic scenario anyway... xD
I'm using the Server VM BTW, so that isn't the problem. Next I'll try a benchmark of a basic game object class (theoretical of course) VS Artemis entities to see how much performance loss(/gain?) there is.


Putting the performance issue aside, my main problem is the fact that I have never gotten a decent object system working. I tried to do it earlier using a pretty fat base class which was extended by other even fatter classes, which also had components which interacted and everything exploded into a world of bloody spaghetti. I have this kind of mental thing that I want everything to be perfect from the start, so I try to think out a lot of stuff before I start coding, but I could never come up with even a somewhat decent solution. I ended up rewriting and rewriting and eventually dropped the whole project (which was mostly for learning, but whatever). Of course I realize there is no perfect way of doing this, but to me it seems that Artemis comes pretty close to be honest. I think I could actually implement this in a pretty nice and readable way, which I think is THE most important thing for something that's this hard to get right, at least for me.
So, an pure inheritance based system is pretty much out of the question. I've had so much problem with it spiraling out of control that I just want to try something else. Even if you guys think it would be "enough" for my game to use basic inheritance (which I don't really agree with), I value the structuring and extendability more than performance. But like I said, if I'm doing things completely wrong then PLEASE stop me.

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.
This seems very very similar to Artemis, but with that gigantic class split up into components. A component system seems a little bit more flexible though.

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.
Yes, I really wish to multi-thread the CPU hogging parts. Multi-threading inside systems is completely overkill if you ask me, but running multiple systems at the same time would be awesome. I found this in the EntitySystem code:
1  
2  
3  
4  
5  
if(checkProcessing()) {
    begin();
    processEntities(actives);
    end();
}

All of these are abstract functions, so it seems to be all up to the coder to ensure that it is thread safe. The point is that Artemis shouldn't have a problem with it at least.

I'll be back with more benchmarks! Meanwhile, alternatives to Artemis and random thoughts are welcome! =D

EDIT:
A new benchmark. Doesn't use Artemis.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
//Initializing
ArrayList<Entity> entities = new ArrayList<Entity>();
for(int i = 0; i < 100000; i++){
    entities.add(new Entity(0, 0, 0, 1, 0, 0));
}

//Update loop
for(Entity e : entities){
    e.update(10);
}

//Entity update code
public void update(int delta){
    x += vx*delta;
    y += vy*delta;
    z += vz*delta;
}

Much faster of course. I get 693 FPS (1.443ms) with this code. But really, I doubt that performance is very important here. I'll probably not have much more than 1000 objects. If I were to go crazy I probably wouldn't even have 10 000 objects, not to mention 100 000 objects! Considering the lightness of the updating (movement) I think this benchmark highlights the "low" performance in Artemis, but in the reality the overhead of Artemis is a lot smaller than the game logic. That's what I think at least, and haven't you guys been telling me not to do premature optimizations?  Wink

EDIT 2:
A basic inheritance system performs approximately 1.5-2.2x as fast as Artemis for basic movement, depending on the number of entities, with Artemis closing in on inheritance systems as the number of entities increases.
A final benchmark, confirming my overhead hypothesis:
By changing the movement integration to something more CPU heavy the overhead of Artemis gets a lot smaller as it is memory bandwidth bottle necked. I changed the movement updating to:
1  
2  
3  
4  
5  
6  
7  
//Artemis:
p.setX(p.getX() + Math.sqrt(v.getVX() * world.getDelta()));
//Same for Y and Z

//Inheritance:
x += Math.sqrt(vx*delta);
//Same for x and z

With up to 10 000 entities, Artemis performs exactly the same as basic inheritance. If I go over 10 000 Artemis starts to lose ground. At 1 000 000 entities, Artemis gets 45 FPS VS inheritance 61 FPS. I think I can live with these performance numbers though. Smiley

Myomyomyo.
Offline tberthel
« Reply #24 - Posted 2011-10-04 15:52:51 »

I realize the Artemis system is amazing and this may be the most important thread for beginning game developers.

Personally I have position as permanent property.  How many game objects don't have position.  The answer should be zero.  So why have the extra method calls.

I look at your example and I think it has many method calls and uses abstract classes, but I love the Entity ideals.  

I follow simple rules to keep performance and minimize complexity.

1.  Don't use inheritance more than 4 deep per project. (Artemis obviously fixes this problem for game objects)
2.  Don't let classes exceed 1200 lines.
3.  Don't have more than 7 properties without converting it to yet another composite.
4.  Keep 90%+ of methods to less than 12 lines.
5.  Don't make methods for less than 3 lines of code.
6.  Minimize static references. Yes they are slower than non static.
7.  Don't cast to an interface or abstract class in the game loop.
8.  Don't create objects in the game loop when in a gameplay state unless you really must
9.  Don't have a collection of objects that don't have a base class other than object unless object really is the base.  
(This is one that Artemis breaks)
10.  I have many more...

The point being that getting around the God class issue is important but don't destroy sensibility in the process.  

Just think through your current game object implementation and ask yourself does this make sense.

Offline Gudradain
« Reply #25 - Posted 2011-10-04 16:10:08 »

Just a thought like that. Appel once tell me that he stopped using Artemis because it felt too restrictive and it was imposing on the coder to do things in a certain way while it would be better to do it otherwise (or easier).

Last time I check he was developing a new Entity system called Appolon.

Any way, can you sort your Entity in the data structure that you want with Artemis because if you can't your performance will be crap
Offline tberthel
« Reply #26 - Posted 2011-10-04 17:07:07 »

Just a thought like that. Appel once tell me that he stopped using Artemis because it felt too restrictive and it was imposing on the coder to do things in a certain way while it would be better to do it otherwise (or easier).

Last time I check he was developing a new Entity system called Appolon.

Any way, can you sort your Entity in the data structure that you want with Artemis because if you can't your performance will be crap

Can you redo your last sentence.

Offline Gudradain
« Reply #27 - Posted 2011-10-04 17:36:36 »

I said that if you can't chose the data structure in which you store your Entity, performance will be bad.

A simple example. Imagine that you have a list of thousands of enemies and in that list you have a few like 4 or 5 that have some special behavior that you need to update into a different part of the code then the other enemies. If you have something like that iterating over your list of, let's say, 10 000 Entity to get the 4 or 5 that you need is a very bad waste of ressources. Those 4 or 5 Entity should be store in a different list.

On another side, those 4 or 5 special Entity might need to be updated at the same time than other Entities for some behavior, so you need be able to iterate over all those in one time.

That's a very simple example, but as soon as you begin to create something more complex you will find that a lot of those things happen. You need to carefully chose the datastructure to get good performance and I don't think that Entity System can do that for you.

How can calling a method World.addEntity() or World.createEntity() can store that Entity in the best datastructure, sort it in the fastest possible way, giving access to it in the fastest possible way, being able to remove it in the fastest possible way, etc.

I just can't see a way that all that can be true. Bad datastructure will be responsible for the majority of your performance problem, so not being able to decided exactly how the things are stored is a HUGE weakness.
Offline lhkbob

JGO Knight


Medals: 32



« Reply #28 - Posted 2011-10-04 17:51:21 »

I said that if you can't chose the data structure in which you store your Entity, performance will be bad.

A simple example. Imagine that you have a list of thousands of enemies and in that list you have a few like 4 or 5 that have some special behavior that you need to update into a different part of the code then the other enemies. If you have something like that iterating over your list of, let's say, 10 000 Entity to get the 4 or 5 that you need is a very bad waste of ressources. Those 4 or 5 Entity should be store in a different list.

On another side, those 4 or 5 special Entity might need to be updated at the same time than other Entities for some behavior, so you need be able to iterate over all those in one time.

In examples like this, all you really need is for the entity system to handle lists of entities based on having a component (or a set of components). You then move the special behavior for the 4-5 entities into a separate component (like AdvancedEnemy) and you can do your queries on them quickly.  Since they'll also have the plain Entity component, you can still process them with everything else.

Entity systems are tricky because they require a different way of thinking about how to solve your problems.

Online theagentd
« Reply #29 - Posted 2011-10-04 17:52:48 »

Guys, stop posting all the time when I'm trying to post! T___T

@Tberthel
I agree that having position as an (optional) component is kind of weird, but at the same time I think it's really hard to know where to draw the line. I found it easy to always create some kind of exception to the base class. It's also very hard to refactor if everything is built this way. Like I said, this is all just my opinions.
Just a thought like that. Appel once tell me that he stopped using Artemis because it felt too restrictive and it was imposing on the coder to do things in a certain way while it would be better to do it otherwise (or easier).

Last time I check he was developing a new Entity system called Appolon.

Any way, can you sort your Entity in the data structure that you want with Artemis because if you can't your performance will be crap
I see. I will probably try using Artemis and if I find some major flaw I might drop it. What is Appolon? Does it have a website? Is it even released?

I said that if you can't chose the data structure in which you store your Entity, performance will be bad.

A simple example. Imagine that you have a list of thousands of enemies and in that list you have a few like 4 or 5 that have some special behavior that you need to update into a different part of the code then the other enemies. If you have something like that iterating over your list of, let's say, 10 000 Entity to get the 4 or 5 that you need is a very bad waste of ressources. Those 4 or 5 Entity should be store in a different list.

On another side, those 4 or 5 special Entity might need to be updated at the same time than other Entities for some behavior, so you need be able to iterate over all those in one time.

That's a very simple example, but as soon as you begin to create something more complex you will find that a lot of those things happen. You need to carefully chose the datastructure to get good performance and I don't think that Entity System can do that for you.

How can calling a method World.addEntity() or World.createEntity() can store that Entity in the best datastructure, sort it in the fastest possible way, giving access to it in the fastest possible way, being able to remove it in the fastest possible way, etc.

I just can't see a way that all that can be true. Bad datastructure will be responsible for the majority of your performance problem, so not being able to decided exactly how the things are stored is a HUGE weakness.
EntitySystems filter out the entities that have all the required components (set in the constructor) and stores them in a Bag (an optimized ArrayList I think). There is no need to iterate over all entities just to find a few specific ones. And it's not World.createEntity() that handles the data structure setup, it's Entity.refresh() which you must call whenever the Components of an Entity changes. I think Artemis actually covers all or at least most of the problems you specified...
If I turn your criticism around: Do you have any examples on how to do this better than Artemis does?

Myomyomyo.
Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (15 views)
2014-08-28 18:26:30

CopyableCougar4 (25 views)
2014-08-22 19:31:30

atombrot (38 views)
2014-08-19 09:29:53

Tekkerue (33 views)
2014-08-16 06:45:27

Tekkerue (32 views)
2014-08-16 06:22:17

Tekkerue (20 views)
2014-08-16 06:20:21

Tekkerue (29 views)
2014-08-16 06:12:11

Rayexar (66 views)
2014-08-11 02:49:23

BurntPizza (42 views)
2014-08-09 21:09:32

BurntPizza (34 views)
2014-08-08 02:01:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!