Gamasutra: The Art & Business of Making Gamesspacer
View All     RSS
July 31, 2014
arrowPress Releases
July 31, 2014
PR Newswire
View All
View All     Submit Event





If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 
Game Engines 101: The Entity/Component Model
by Megan Fox on 12/08/10 06:06:00 pm   Expert Blogs   Featured Blogs

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

 

There are many approaches to game engine design, and this is far from the best in all cases, but it is certainly the most common overall.  Welcome to the wide world of component-based entities.

First, let's address the way most people fresh out of Data Structures, CS 101, etc think of game objects:

class Engine { int numberOfCylinders; .... }

class Car : Public Engine { bool hasComfySeats; bool numSeats; ... }

... which is, in a word - bad. In two words, really bad. In two different words, painfully inflexible. You can make a game this way, and many have, and it was even "the" way to do it way back in the day, but those days have passed, game engines have blossomed in size, and now we're willing to spent a bit of processing power on making our tech flexible and resuable.

Let's take a peak at why. Imagine you need 10 different enemies. Ok, great, now we have 10 different enemy classes. So far so good, right? So now we realize that each of those entities is 90% the same, and only 10% different. We don't want to copy-paste identical code that many times, it would be entirely unmaintainable as it grew and we wanted to tweak the base functionality of entities, so we think - "ah hah! we'll make a shared function for the equivalent bits!". Ok, great. But now one of those entities has a slightly different AI routine too, but the same everything else. So now we break the AI out of the shared code, and give him a unique AI section. Now there's another entity, that wants that AI, but has different physics, so now we have to break the physics out of that shared code, make a 2 versions of physics, and then the new entity has a unique physics but shares the other different AI and then AAARRRRRGGGGH.

So we stop just short of hanging ourselves, back out, and realize that that route is unsupportable. So we go back to thinking about keeping each entity separate, and just copy-pasting code around, and even if it's identical - whatever, if we change one, we just remember to change them all. Now a year later, you have 100 entity types... and you realize you made a typo in their physics stepping. All of their physics routines have to be changed. AAAAARRRRRRGGGHHH.

Thus - enter components. Which, and excuse the extremely rough pseudo code, might go something like this...

class Entity {

void AttachComponent(ComponentType, argumentList, name)

void DetachComponent(name) void UpdateComponents()

void UpdateComponentType(ComponentType typeOfComponentToUpdate)

void HandleMessage(MessageType message) // echoes to all attached components

...

BaseComponentList attachedComponentList

.... }

 

class BaseComponent {

virtual void Startup()

virtual void Update()

virtual void Shutdown()

virtual void HandleMessage(MessageType message) .... }

 

class RenderComponent: Public BaseComponent {

virtual void Startup() // (registers the renderable mesh with the rendering system)

virtual void Shutdown() // (removes the renderable mesh from the rendering system)

... }

Abolish the idea of an object. There is no such thing as a "chair", or an "orc" - there is only data, and components, that together may resemble such. A chair has "physics", "rendering", and "the ability to be sat upon" (which we'll call "interaction"). An orc has "moving physics" since it can walk, "rendering", and "AI". Each of these components, and this is a very stripped-down example, stands alone, and has no actual knowledge of whatever else may be attached to a given entity. The entity itself, such as it is, only has a list of components attached to it, and a generic data "bucket" that all components can write to or read from. It may also have a messaging system, which lets it broadcast one of a list of messages out to every attached component, and the components may be able to themselves send messages to the entity they're attached to (which then broadcasts the message out to all components attached to the entity... including the component that sent the message, but it's smart enough to ignore it). This messaging system is also likely exposed to the world, allowing other actors in the world to send messages to the entity, and thus all components attached to that entity, but more on that in a sec.

Now the beauty of this is reusability. Two rendering components are basically the same thing - they take a mesh and make it render - meaning that every renderable object in your game can, mostly, share that one component. All that changes, really, is the argument you pass the component on creation, which'll probably be the filename of a mesh to render amongst other things. Even if you have a few different classes of renderables, particles vs skinned objects vs rigid vs whatever, that's still just a handful of renderable components that are easily tracked, which can all be transparently assigned to whatever entity you choose. Physics are likely even more generalizable.

Things will likely break down if you assign a ton of physics components to a single object, which is to say that not EVERY component can be put on one object with the expectation of them all just working things out, but the point is flexibility, not being completely idiot-proof. You still have to consider component interactions, and in general the idea is that some components expect that only one of its class of component will be attached at a time - if a given component wants to "own" a particular chunk of data that lives on the entity, like the name of an attached mesh resource or the entity's physical position, ideally you will have attached nothing else that also tries to own that data. There's also a balancing act with how aware a component is allowed to be of other attached components, with one extreme being no communication allowed aside from messaging and data putting/reading, the other extreme not looking much different from never having used components in the first place. Generally, you want to start with isolated components, and only skew the other way as you note performance problems (THROUGH PROFILING! DO NOT PRE-OPTIMIZE!) and rework your component interactions.

Your update cycle thus becomes something like this: your world manager says "update the world", and that update the world function likely has some specific order in which it updates components - physics needs to come before rendering, and so on - and for each class of component, it gathers a list of all entities with that component, and says "update your physics." So the entities run Update() on their list of components of that type. Not everything will necessarily update that way - rendering probably keeps track of meshes directly and renders them directly, with rendering components just updating their mesh's information during their Update() step, and the actual physics-sim portion of physics would do likewise - but much will.

If you're still not getting it, let me give a practical example of how this might work:

You have a mobile animated creature. It has a skinned mesh component, and a mobile physics component, and a movement AI component. The AI component calculates a movement vector and puts it into the entity's data store, the mobile physics component takes the movement vector data from the entity and physically moves the entity along (and adds current velocity data to the entity), and the skinned mesh component determines if the object is moving based on velocity and either does a walking animation or a standing animation depending.

You have a second entity, which is a trigger physics component and an explosion AI component. The trigger physics component defines a bound you can walk through, it just waits for a collision, which sends a message to the attached-to entity when anything collides with it. The explosion AI component waits until it gets a collision message, waits 5 seconds, and then does a collection (by asking the entity manager) for any nearby entities - and to each, sends a physical impulse message.

The player, walking in the circle, eventually enters the explosion region, and then 5 seconds later gets the physical impulse message. Its render and AI components ignore it, but the physics component recognizes that message, and applies the requested physical impulse - launching the player up and away. The player lands, and then continues walking in a circle as defined by the other two components.

Done. A complex interaction broken down by components, that can be varied in a hundred different ways while writing barely any new code. You could change the way the entity responds (maybe the player's AI ignores the explosion message, whereas an enemy's AI responds by running away - but all you do to do that is change the enemy's AI component), the arguments to any of those messages, etc, and nobody has to go editing 20 different entities by hand to do it.

Now there is another important aspect to components - namely that they easily allow for your engine to be data-driven. However, that is a topic for another posting, so... for the moment, just stick with what we've got here.

[see more from Megan Fox at her primary site, Glass Bottom Games]


Related Jobs

YAGER Development GmbH
YAGER Development GmbH — Berlin, Germany
[07.31.14]

Senior Graphics Programmer (f/m)
Square Enix Co., Ltd.
Square Enix Co., Ltd. — Tokyo, Japan
[07.31.14]

Programmers
Raven Software / Activision
Raven Software / Activision — Madison, Wisconsin, United States
[07.31.14]

Senior UI Engineer
Disney Consumer Products
Disney Consumer Products — Glendale, California, United States
[07.30.14]

Contract Game Programmer






Comments


Jonathan Jou
profile image
There are definitely times to go object oriented and times when the amount of boilerplate outweighs the gains of extensibility, reusability, and modularity, but I'm not sure this is one of those examples. I'll go into why.



The pattern you're talking about is just as easily referred to as the case for multiple inheritance: you want class A to have behavior B but not behavior C, and class D to have behavior C but not behavior B but they both share behavior E, etc... The common solution to this is to implement the different behaviors at higher level parent classes, and have them inherit as they make their way down. In languages such as C++ where multiple inheritance is supported, it's possible to inherit AIBehaviorOne and RenderingMethodTwo from two different and unrelated parent classes, which accomplishes more or less the sort of requirements you have here. For languages which don't support this, on the other hand, there are Interfaces, and you could just as easily write a Class that contained an IArtificialIntelligenceHandle and an IRenderer, which you could specify in a text file if the language supported reflection. You only implement the logic for any individual component once, and create and use it just as your Entity/Component model describes.



Inheritance vs. Aggregation is a very sound and useful distinction to make--there are a lot of cases where inheritance alone won't do you any favors, but it's important to remember the tradeoffs you make when deciding between the two, as one is not universally better than the other. In fact, in general it' s not only a good idea, but very useful to have a bit of both.



Inheritance produces (perhaps enforces, even) a clean hierarchy; when you derive from a parent class, you know exactly what you're making, and exactly what it's supposed to do. In any situation where you're designing a runtime library or such, for instance, you want people who derive from the IOStream class to get compiler errors when they forget the write() function, and for them to be able to trust that the IOStream parent class handles Allocate() on its own constructor for them. A well-designed object-oriented architecture is easier to understand, maintain, and extend.



Aggregation allows for far more freedom, since you're assembling different behaviors into one class, but this means that someone who's trying to use your code has to actually see each component (and all its variations), which components your class contains, and understand how your class uses them together to do what you want it to do before they can start writing their own classes. Aggregation makes it more difficult to understand how every individual piece works together, and simultaneously requires anyone trying to work with the code to do so instead of abstracting it away for them. In many ways some object-oriented design is required to reduce the code into cleanly isolated components--just like poorly implemented inheritance introduces unnecessary boilerplate and can causelarge architectural change, aggregation that isn't well thought-through will confuse and distract from the interesting parts of the code in large part because of the added flexibility.



For instance, the classic Model-View-Controller pattern, which handles the same problem you're talking about, aggregates and inherits in an intuitive, logical fashion without eschewing one or the other quite so passionately as you seem to be doing: the model represents everything in the world, updating as time passes, the view renders the images the player sees, and the controller manipulates the world according to player input. A game engine could aggregate a Model, View and Controller without any knowledge of what they are (and you can create alternate engines by swapping them in and out), while implementations of IView could inherit the basic draw APIs so that every View would draw a blue rectangle the same way without copy-pasted code. The two are not mutually exclusive, so it's perhaps a good idea to not mislead the reader into abandoning a tool in the programmer's toolbox for another.

Michael Carr-Robb-John
profile image
Hi Jonathan,



I don't disagree with what you have written, I'm a strong supporter of good programming practices and methodology. However there is a reason why components have come into existence and supplanted the traditional inheritance model for game entity's, to put it simply the old way doesn't adapt well to changes in design.



I was wandering what sort of complex entity inheritance system have you worked with in the past? Just some rough breadth and depth numbers. Also what sort of game was it and how much did it's inherited structure change from beginning to end?



Thanks

Michael

Sean Farrell
profile image
I completely agree with you Michael, if you exceed a depth of 3 and have more than 2 parents, something is flawed in your design. In general you should favor aggregation over inheritance, especially when concerning code reuse.



The above noted example could be gracefully solved with refactoring common code into common classes and aggregating them. But then that would start to look allot like the entity/component model...

Jonathan Jou
profile image
Thanks for the reply, Michael. I'll be the first to admit that my experience in software design is definitely on the shallow end of the pool, especially in game development. I work in a world where thousands of people are editing roughly twenty million lines of code (and growing) on a daily basis, where aggregation has given developer flexibility and then manifested itself in an unending trail of bugs when new people try to use old code. There are three types of smart pointers and an unknown count of stream implementations in this code base, since everyone wants to use their own when, if nothing else, inheriting the code that worked for 10 years would save them and all their partner dependencies several months of headaches.



The streams in the small subset of the code I work with have four layers of abstraction, each with different and important behavior, and a whole gamut of components mixed and matched in as needed. After the several hours it took for me to really understand the what was going on, I've come to the opinion that sufficiently complex code warrants incredibly complex design. Complex code can be elegant, to be sure, but I don't know of any way to put together a truly large number of features without combining a series of simple designs into a complex network of dependencies. That said, I'm all for aggregation when inheritance produces classes you don't use, and a stout believer of inheritance when you have a function you can refactor out of four places into one.



Sadly, I've never been paid to write a game engine; my own implementations (I wouldn't be here if I wasn't at least an aspiring hobbyist) took the MVC pattern to heart, and I believe that if I hadn't distinguished the engine into the aggregation of a Model, a View, and a Controller, the inheritance hierarchy would've changed even more than the several dramatic overhauls I put it through. I chalk that up to inexperience, myself, but I do stand by my belief that it's a good idea to inherit when you can, and aggregate when you need to.



I'd be happy to talk with you further about you experiences--I am by no means a veteran of any field, and am open to any potential error in my ways.



Thanks again,

Jonathan

Chris Masterton
profile image
Very well said. Having written scene graphs and managers with entities and inheritance, it's unsettling how simple components are to use - and maintain. Why didn't we think of this before? Plus contiguous lists of components are cache-friendly and well suited to multi-core/multi-threaded job systems. I'm a component proponent.

Mark Taylor
profile image
It was though of before, but it was called tables, and is the basis for SQL. Your entity is your ID, and the components are lines in a table with matching ID. You perform array/database operations rather than working upwards from virtual base classes to overloaded functions.



Example:

Favour cats.meow(): dogs.bark(); monkeys.howl() to animals.communicate();

Mark Taylor
profile image
Sorry, should be foreach(animal a in animals) a.communicate()

Robert Schmidt
profile image
I don't think chris is talking about the invention of tables rather the application of this concept to games.

Mark Taylor
profile image
Ultima Online, which was released before 2000, used SQL tables for entities, so it is not new. 'Component' is OO-speak for 'row'. 'Entity' is OO;speak for 'ID'

Manu Varghese
profile image
I have noticed that _ease_ of writing/implementing a new component (in C++, at least) often conflicts with making components cache-friendly and multi-threadable, especially if you want to make it run on the SPU. I know that Insomniac has a system that manages to update components on the SPU (GDC Canada 2010 talk), but from what I saw, writing such a component involves more work than implementing the simpler-looking interface described in this article (and I'm more used to implementing components the simpler way).



I would love to read any article you might know of that talks about simplifying how I write cache-friendly, multi-threadable components. Or is it just that "if I want it to run faster, I have to do more work per component"?

Michael Carr-Robb-John
profile image
I've been using component based entitys since 2001 and I couldn't agree with you more, components are one of the best pieces of tech available to game programmers today.



Over the years, I've gone through a number of different implementations of components from pure 100% data driven, to compile time configuration and even a hybrid system with the old style entity heirachy with attached components. Each implementation has there own good and bad points which was a driving force behind their development. Anyway, anyone that is looking to experiment or get their heads around components and inter-component communication I would highly recommend having a play with Unity3d which implements components in a way that makes building a game entity a pleasure.

Sean Farrell
profile image
One of my common critiques of game engines are that they mange simulation and presentation. This if commonly done for a simple reason, lack of tool support. Take for example the example of the different requirements noted in the article. The problem arises because the developer tries to jumble multiple responsibilities into one class. This is bad, since it is a clear violation of the Single Responsibility Principle.



Now the entity/component model addresses very well the Single Responsibility Principle and solves it quite elegantly. But I have a critique about it, that is you bind the simulation to the presentation. Think about what you would do when you want to build a server? You definitely don't want to bring up some rendering or sound code on the server. Of course the trick here is to filter the presentation components out when instantiating. The problem is, can you grantee that the system even works properly without them? What is if you want your world to be "skinable"? Swap out the components on instantiation...



As Jonathan Jou points out, Model View Control might be a better solution. (I look at a slightly different angle here.) The nice thing here is that MVC makes things clearer and is almost idiot proof. Let me explain.



Starting with the model, which is mostly simulation data and no behavior. Here you probably have either a very concrete inheritance hierarchy or a data driven model. You know what data makes an Orc.



The view is simple, a representation of the model. This can be audio only, 3D, 2D text based you name it. A game can have different views, each showing different types or even styles. The single camera problem many FPS have is a nobrainer to solve.



And finally the control. This is rather interesting, since you can define different controls for one type of model you can swap from AI to human controlled without changing any other part of the code.



With MVC you can trivially solve many problems. For example network synchronization becomes a really simple task, on the one end it is a view and on the other it is a control...



Of course you can have components on each part of MVC, which adds flexibility. I am thinking at something like Blender's Sensor / Actor system.



P.S. For the Car -> Engine inheritance you would fail my OO class; a Car HAS and Engine not a Car IS an Engine. Just to be a little nit picky here...

Megan Fox
profile image
Oh fine, yes yes, so instead of an Engine you have a Vehicle base class, which just happens to have an engine, etc. Still a painful approach though. ;)



For server vs client, yes, the expectation is that your system is stable with components removed. So long as you maintain your components properly and separate responsibilities clearly and consistently, it shouldn't be a problem - but there are edge cases, of course. Often your picking will rely on your visual mesh, which itself comes from your rendering component, and perhaps you want some threadbare app on the server that supports picking for debug dumps, meaning your server might swap in a just-the-mesh component instead of loading the full renderable component (or you might use fancy #ifdef'ing within your renderable based on server vs client). You might also load a different physics comp, and so on... but still, it does work quite well, so long as you design your components with server vs client in mind.



The big problem I have with MVC is that it tends to be a coder-enforced and policed system - it tends inflexible to everyone but programmers, and does not play as well with data-driven development. Components, on the other hand, can be made to even hot swap at runtime, which is a huge, huge boon for iterative development, bug tracking, systems reuse by designers, etc. Like I said though, data-driven development is a different discussion, and probably the next article I'll do.



Still, to be honest, I've never used MVC in a large project. Maybe it's amendable to being data-driven as well, if you massage it just so? Do tell, if you've tried that. I'm also of the mind that components are far better for cache coherency and parallel processing, but that could also be a simple lack of experience with MVC on a large scale.



Really though, I didn't write this to toot the horn of components as The One True Path. I'm honestly on a bit of a functional programming kick right now, and am kind of inclined to think that THAT is more The One True Path. But, components are hugely prevalent, and if you go into games programming, you WILL eventually work on an engine that uses them... hence, this article - to just try and introduce folks to thinking in terms of them, and to get them familiar with the pattern.

Sean Farrell
profile image
No offense meant. Entity/Component solves a problem and solves it quite well.



Here is a problem to solve for you: You have one "state" and you want to show it in two different ways. For example a RTS that has a 3D view and a minimap. Now add a 3D tactical display where all units are represented by schematics. With a component model this becomes quite cumbersome, with MVC you just add more views.



If done properly you can make MVC quite data driven. The big problem here is tool support. You can't just export any scene graph and expect perfect results. You need a object/entity editor that first builds the model part, then offers the ability to build the corresponding views. Controls are probably done problematically, but can probably be also configured.



MVC is good software design, the problem is humans don't really think that way. Often secondary views such as a minimap are a afterthought in the design.

Megan Fox
profile image
Oh, no offense taken at all - and it's far from the best tool for every job, and it's fun to discuss alternatives.



To your RTS example, the solution I would suggest is separating your data elements from your functional elements. That's also how I would suggest solving my own mentioned problem of picking being tied to rendering. Have components that do nothing but provide data - one that gives you a mesh, one that does just AI, the data-side - and then components that do nothing but operate on that data - so they find and render a mesh, they move you physically based on AI input, etc.



Your RTS example then boils down to a single entity with data exposed. You then attach 2 sets of components - 1 set takes that data and makes it make sense in the game view, the other takes that data and communicates with a minimap system to phrase it all in minimap terms (it uses the same position, probably, but might visualize vertical movement differently, it uses an icon instead of the mesh, and so on).



... which, in a sense, does start to resemble MVC, or even more so, functional programming. Data elements and transformers/operators, with strict separation between the two. Components are just a way of constructing the basic world hierarchy that happen to fit well with how people logically construct concepts, which makes it possibly a better fit for designers and artists, and might be easier to expose to them. Though as you say, there are ways around that for MVC too.



(for a personal example, we solved the minimap problem by simply having a minimap component that uses the position, and uses data from a few other components - like the overhead icon component - to visualize it in the minimap. Attach that component, that object starts appearing in the minimap. Disconnect it, it is removed / not shown in the map. There was some data duplication between the renderer and the minimap, but nothing heinous.)

Mark Taylor
profile image
Perhaps C++ is the wrong language for entity systems. In games you want thing processes that evolve over time, such as getting an animal from A to B, with C++ you end up with a messy state machine. A better language suited for the job should use co-routines. C++ can"t do that in a portable way. C++ is a system programming language, great for sound, graphics and input, but for abstract concepts you end up exposing too much implementation detail to get anything done. There is no good way of exposing enumeration in C++ without compromising something. Compare to C# IEnumerator and foreach - vastly superior.

Megan Fox
profile image
C#'s IEnumerator and foreach are simply bits that make iterating through a list / enumeration easier. You can implement them for your engine in C++ in a few hours if you want them (though you'd probably make a slightly more domain-specific iterator - for instance, a foreach that only iterated through a set of given types and ignored those not in that set, or rather, a system that broke your list into multiple sub-lists based on class for fast and cache-coherent iteration). Ditto for implementing smart pointers to hide memory management, and so on. A good C++ engine will have most of these already.



Don't get me wrong, they're handy. C# gives you a great, great many of those handy little things "for free". They're just not unique to C# - C# is simply a slightly higher level language.



If you want to talk about languages that make phrasing entities easier, rather than just a language that gives you a few extra high level general tools, you need to go elsewhere - it could be argued that LUA has certain properties that make it easier, or SQL, both for how "classes" become "tables", and MEL script has some nice properties too for that matter. Unity's implementation of Javascript is another stand-out example (where messaging is a default interaction means rather than a separate system / every member function is a message listener), and UnrealScript has also been purpose-built to the task. But C#, eh, it's really just a higher level general purpose language.

Mark Taylor
profile image
The problem is that there is NO good way to expose enumeration at an API level in C++. Using iterators and templates exposes too many details of the underlying container, and is not portable, outside of C++. Using callbacks is cumbersome, especially when one wants an index in the enumeration. Using a GetCount, GetItem(i) pattern is not efficient for all containers. Enumeration is not a small issue. Almost all code, at whatever level, requires enumeration. When it is cumbersome in a language it makes the code laborious and error prone. One may increment the wrong iterator, or pass the wrong context value for example - stuff that is hard for the compiler to detect.



C#'s real limit is being too much constrained to the Windows platform. It is VASTLY superior to C++, though not for system programming. Reflection, clean efficient enumeration and lambda functions can double or triple development speed and reduce the sources for errors by the same ratio. Unfortunately it does not support co-routines, which means it is not good for writing complex games.

Sean Farrell
profile image
I really can't see how a specific language can mean any difference in the context of entity/component. It seams you like C# and hate C++ and try to map that onto entity/component.



It seems to me that any C# feature you listed has anything to do with the general design of the system. You talk about reflection and iteration concepts and just can't see what they have to do with it. True there will be some iteration but a properly designed system does not need any form of type inspection.



All should be clearly solved though polymorphism and delegation, no need for C#'s fancy language features to solve that. Many C# specific features, especially reflection, seem to me to favor worse design. Don't get me wrong, there is a validity in all design concepts of C#. The question is, is it the right tool for the task.



You talk of GetCount and GetItem, any system I build would never iterate over anything like that. Nor would it expose internal containers. Delegation is your friend here.

Mark Taylor
profile image
1. Give an example of delegation that is used as a general mechanism for iterating over any given container.



2. C++ vs C# is not a question of hate, but of role. C++ is for memory management, or hardware control. C# is for building complex applications on top of such APIs.



3. Language feature do effect the design of a system. You can always mimic a feature of one language with the features of another, but the point is not efficiently. Reflection is a perfect example. When you want reflection as powerful as C# in C++ it becomes a major hassle, messy ugly code. It needs to be done in the compiler. If you think otherwise then in my opinion you have spent too long in one language. One language may fit all, but it is a bad fit, a bit like a unisex jump suit for all sizes.

Robert Schmidt
profile image
Great article Megan, I had been struggling with MVC for a while before moving on to components for all the reasons you mention. Software development is a series of compromises, many based on personal values rather than clearly defined rules. You can't have everything. For the engine developer the component model is much simpler to implement. I used MVC primary because of the ability to grab pieces of an object and send them off for processing. The component model does this much better and, as you indicated, is more flexible in this way. Posts on actual game coding seem to be rare here so I greatly appreciate your post.

Evan Bell
profile image
Great blog topic and good treatment. Unity 3d uses the component model and it is very effective. Also, the component model is easier to translate into systems for data oriented design. Performance gains and easier to write unit tests are some of the other benefits to be realized with this approach.

Jamin Messenger
profile image
After reading this article, I now understand how little I know (amateur programmer here)

Though I'm still struggling to understand the concept... I am going to try re-reading the article 6 or 7 more times as I think I want to utilize this technique.

Jared Thomson
profile image
Something I learned in school is... "Don't expect to learn in school". Not every College is the same, but my professors are really only there to teach me the basics, and how to self learn. All of the above concepts that I'm perhaps unfamiliar with, I'm itching to try. Rather then a re-read, might I suggest a similar approach? :)

Robert Schmidt
profile image
@Jamin Messenger, download the Unity3D engine. It's free. It will give you a good sense of what Megan is talking about. Based on my own experience, I wouldn't recommend building an engine until you have experience using an existing engine. It is a lot of work so you want to minimize the trial and error. Learning from other people's mistakes (and successes) is much cheaper.

Jamin Messenger
profile image
I was using the base framework from XNA Game Studio for the engine. I have also downloaded the U3D engine, but it was a little too overwhelming. I was more comfortable with C# and found excellent tutorials that got me up and running very quickly (I was able to build a tetris clone to prove I could use it). I am now working on a simple 2d strategy game that I am going to try and design for xbox360. Since it is still just practice, if I can incorporate this technique, it might serve me well in the future. The last thing I want to do is teach myself how to program using inadequate or outdated techniques.

Steven Liss
profile image
I wouldn't look at it that way. If your building a very small game the monolithic approach can be pretty handy. The benefit of it is that everything is clear and quickly accessible. It's not that monolithic is outdated it's just not very scalable. If I was making any game under 20,000 lines of code I'd probably use it. Of course you did say a strategy game, which tend to have a lot of small similar parts, a pretty ideal situation for a component system.

Pierre Fortin
profile image
Interesting article, which explains the component philosophy quite well.



I think most modern game engines architectures have embraced the component philosophy for it's benefits, not only Unity ... Our team has made the switch 3 years ago, but we still face issues with people having trouble designing architectures in such a way.



I do, however, have some questions for you. Why do you need entities at all ? Can't components and the interactions they have with each other define the context of the entity ? Can't it be an abstract concept ? Why not go further and remove the entity concept ? Why store movement in the entity, when it could be stored in the physical object or within the transform matrix component ? The only purpose I see to entities is the container aspect they provide, which can be done by implementing a specific entity like component, which acts as glue defining this containment.

Megan Fox
profile image
Yep, that's one approach - it's just somewhat more difficult to explain, since then you have to couple component updates et al directly to your central component factory/manager scheme. Certainly cool, though.

Robert Schmidt
profile image
@Pierre, I think you answered your own question. Although, I'm not sure what you mean when you ask why you need entities and then ask, "why store movement in the entity, when it could be stored in the physical object". First, there is no physical object, this is code. Second the entity is the object. You are right when you say the entity acts like glue. They also control how those components talk to each other and the outside world and share data. How would components work without an entity?

Pierre Fortin
profile image
What I meant by physical object is more something like "Rigid Body".



What I want to express is this : The entity is an hoax ! Why not express the entity itself as a component ? Why would you want to store data in the entity itself, and not the components ? Why should components need to speak with the entity in order to speak with another component ? Can't they get along without someone bossing them around ?



Our implementation does not have an entity system built-in as a aggregate of components. An entity, from the point of view of a game programmer, is only a component who knows other components and controls their interactions. The core of the engine doesn't know a single thing about the entity concept. He knows of component and knows how to enumerate them by a given type.



Our main loop itself is made of components, who execute sequential treatment on all instances of a given component type. Since all objects of a given type are treated sequentially, you have much less ICMs than if you have to ask each entity to call each update of each type. Also, since we control the allocation of each component, we can have those components who are to be processed sequentially stored in a contiguous memory region which helps tremendously when it comes to DCMs.



Don't get me wrong : I'm not saying that entities should not exist in concept. But they don't need to exist as part of the system. The entity IS a component, not made of components.



I hope this clarifies my earlier post !

Mark Taylor
profile image
Is 6 an entity? Is the universe an entity? Is a dog an entity? Is an atom an entity?



Perhaps 'entity' is a poor choice of name for an object or class.

Brian Ernst
profile image
@Mark Taylor

No, 6 is an idea or a concept. Yes, the universe is, and so is a specific dog; but dog itself is an idea/concept until you're talking about a specific instance of one. And yes, an atom making up my body is an entity.



So no, I don't think entity is a poor choice of a name for an object at all. Frankly, I don't see why that even matters, you're arguing over mere semantics.

Mark Taylor
profile image
Good programmers are always searching for better names.

Philip Fortier
profile image
@ Pierre: This sort of sounds like the "Systems" in the Artemis framework: http://gamadu.com/artemis/



There is still the concept of an entity, but also the concept of a system that operates over sets of components. Components themselves have no logic, it's all in the systems.



For instance, the rendering system declares that it is interested in entities with both the "Placement" and "Aspect" components. Whenever an entity is added to the world with both those components, it is added to the rendering system.



The rendering system is iterating through entities, but only requesting the Placement and Aspect components for each. Depending how you store the components, you could still achieve the benefit of less DCMs.



The use of "systems" also addresses issues with "which components need to talk to other components". No component talks to other components directly - all this logic is in the systems.



I'm wondering if anyone has opinions on this.



I think this also ties into some of the Entity-Component vs MVC discussion. This confused me at first, because I don't see it as a choice between one or the other. With a framework like Artemis, I think MVC essentially fits right into the Entity-Component framework. The Components are the Model, and the systems are the View and/or Controller.

Philip Fortier
profile image
@ Pierre: This sort of sounds like the "Systems" in the Artemis framework: http://gamadu.com/artemis/



There is still the concept of an entity, but also the concept of a system that operates over sets of components. Components themselves have no logic, it's all in the systems.



For instance, the rendering system declares that it is interested in entities with both the "Placement" and "Aspect" components. Whenever an entity is added to the world with both those components, it is added to the rendering system.



The rendering system is iterating through entities, but only requesting the Placement and Aspect components for each. Depending how you store the components, you could still achieve the benefit of less DCMs.



The use of "systems" also addresses issues with "which components need to talk to other components". No component talks to other components directly - all this logic is in the systems.



I'm wondering if anyone has opinions on this.



I think this also ties into some of the Entity-Component vs MVC discussion. This confused me at first, because I don't see it as a choice between one or the other. With a framework like Artemis, I think MVC essentially fits right into the Entity-Component framework. The Components are the Model, and the systems are the View and/or Controller.

Erick Passos
profile image
What wonders me is how so many people is unaware of such a basic software pattern that's been commodity in (modern) game engine design for the past tens years.



The topic has been covered extensively, and I recommend reading the following article for a very comprehensible explanation and example implementation:

Game Programming Gems 6 – “Game Object Component System” – by Chris Stoy.



Unless you're trying to write a specific, very simple toy-game, such as pacman or tetris-like, component-based entities (aggregation) is the way to go.

Ted Brown
profile image
Bookmarked! Not just for the initial article, but the detailed discussion as well...

Fred DiSano
profile image
Great article!



I'm designing my first mobile title now and I'm really considering using a component based system over a hierarchical just to mess around a little. Either or would would work fine for this project.



So with respect to event/messaging between entities and sub-systems. You could still have an Entity class with all these aggregated components but have the Entity class inherit an IListener type interface to become an event listener? Then a central, singleton event manager is taking in messages from various systems and shooting them out to all respective listeners.



Or is event handling another component?



Thoughts anyone?


none
 
Comment: