Component based game objects

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?

Have a look at the Artemis Entity System. The page also includes a link to an articles about this on t-machine.org.

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?
super(Transform.class, Velocity.class); // Components represent the aspect

Transform.class = Position.class?

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

Cas :slight_smile:

+1, that’s what I do =D

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.

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

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 :slight_smile:

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.

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.

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:

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…? >_<

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. :slight_smile:

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. :stuck_out_tongue:

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.
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 :slight_smile:

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.

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.

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

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

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.

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 :slight_smile:

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