Blog 2.1

It's been quite a while, for this I apologise. My previous entry has somehow accumulated over 1000 pageviews, I'm embarrassed to have that many people knowing how neglectful of this blog I have been!

First things first, you might (or might not) notice that I have a new page theme, it took me a while to design and it's pretty much finished. Behind the new theme is a new, slicker, better designed blogging engine, pages should now load far faster and I can do certain technical things to extend it that I couldn't before, for example tagging. The only thing left to do is comments, which are broken and I simply cannot figure out why. If you have something to say then feel free to email me (martindevans@gmail.com)

This blog post is really about entity systems, so let's get started. I heard about entity systems and composition oriented programming a few months back (just after my previous blog entry), a friend of mine linked me to a blog post (alas, I can't locate it now) about entity systems; at the time I thought "Hey, these are cool" and forgot all about them. Fast forward to three weeks ago, I started work on a module at university called "Team Java", in which a team of four people must build a game, I suggest to my team to use an entity system and the idea gets the go ahead - over these past three weeks I have totally reassess my view of entity systems from "cool" to "awesome".

"But Martin", I hear you asking, "what is an entity system? What is composition oriented programming?", well I'm glad you asked. Let's cover first the shortfalls of Object Oriented Programming (OOP).

OOP works on the basis that you can build a basic game object, and extend it with new behaviour as you need it, so for example if you had a bullet class, and you wanted a rocket, you can simply subclass bullet, modify a little bit of behaviour and now you have a rocket, reusing as much code as possible. The shortfall of this problem is that generally games will have many objects, each with different behaviours; sometimes you'll want something a little stranger than the subclass was really built for, now you either have to wedge your idea onto a base class that isn't really a good fit, or code a new base class which is very similar but not quite the same to the other - clearly both ways are bad.

Entity systems attempt to solve both this problem of a lack of code reuse for similar objects, and the problem of complex class hierarchies that become difficult to maintain.

Entity systems have three components: Entity, Component and Controller. These names are really standardised, but that's what I'm going to call them.

Entity based systems work on the basis that everything is an entity (somewhat like OOP "everything is an object"), an entity is simply a collection of Components. An entity can simply be implemented as a Dictionary (HashMap) which takes some unique identifier and returns the assosciated property. Importantly an entity does not contain any data, or behaviour - this means there is never any reason to subclass entity.

Components contain the data about an entity. Components are passed by reference, this means that a change to a component, will be reflected in the entity even without a direct reference to the entity itself. Like entities, components do not contain any behaviour, they just contain data. This is a minor lie, Components may contain some behaviour but shouldn't modify the data - for example a position component might have a GetTranslationMatrix method, which will generate a translation matrix from the position it's holding.

Finally Controllers are what modify the data. A controller contains references to properties, when a controller is updated it observes the data in the properties, and modifies the data in the properties in some way. Controllers also render data in a similar way, they hold references to properties, and render this data to screen.

A trivial example of this is a movable object. An entity with components:


  • VelocityComponent

  • PositionComponent

  • TextureComponent

Has two controllers attached. An integrator controller holds a reference to Velocity and Position (note, it does not contain a reference to the entity, there is no need), every time the integrator is updated it adds velocity to position - done! the second controller is a renderer, it holds a reference to texture and position, every time it is updated it draws the texture in the necessary place on screen. With this very simple scheme, we have a moving object being drawn on screen.

The magical thing about entity systems is code reuse, any entity that has Position and Texture can be added to the sprite renderer and it will be drawn in the correct position. If we have a sprite renderer and a 3D model renderer, and we decide to swap a particular entity from one ot the other, we don't have to modify the inheritance tree of the entity, we just remove TextureComponent, add Model3DComponent, and add it to the correct controller. Similarly if I have a piece of a menu system drawn to screen using PositionComponent and TextureComponent, and I want to make the menu system fly off screen (I don't know why you'd want to do this, but just pretend) then I can simply add a VelocityComponent, register it with the Integrator controller, and suddenly the menu moves with 100% code reuse.

A warning that was contained within the original article that I read about entity systems was that while they're brilliant to use, they can't do anything that OOP can't do, although it's generally easier to use entity systems instead of OOP. However, this means that you will have, on your team one person who will resist the introduction of entity systems all the way - I have one in my team java team. These people will generally be the people who use OOP the most and are probably among the strongest programmers on the team. Every time something is suggested to do with entity systems they will suggest that simply subclassing Entity/Property would make things simpler, this is very hard to argue against because they're correct, subclassing things is slightly easier in the short term, but in the long term when you change your mind about something you're going to end up modifying class hierarchies and rewriting similar code - which is what you're trying to avoid! Arguments to combat this attitude are:


  1. Link them to this blog post, and tell them to do some research on the subject. Every article will probably say the same thing about subclassing.

  2. Point out that subclassing is a short term solution, if you decide to change the bahaviour of the base class or the subclass you will probably gave to change your inheritance tree, this might mean keeping a copy of the old base class just so you can continue inheriting off it while you make a copy and modify that for some other purpose. Obviously this is a massive lack of code reuse, and leads to a mess of inheritance.

  3. Entity systems are simpler to manage, if this person is one of the best programmers on your team then point this out and tell them that while they might find it easy to manage large inheritance trees, the rest of you will struggle.

  4. More code reuse means less work

  5. Behaviour is in one obvious place (the controller), different behaviours are split across different controllers so maintanence is easier (generally any single controller will be fairly short and have an obvious purpose).

  6. No, just no, we're not subclassing entity.

?? views
Subscribe
recent
Topics