Categories
Game Development Geek / Technical

State of the Art Game Objects

Years ago, I wrote about Component-based Game Design, in which I talked about the advantages of breaking down your game objects into components. Inspiration came from a number of places, including:

My Experience

Over four years ago, I even managed to implement a simple test program as part of my application for my last day job, and at the time I thought it was easy and fun to do. The hardest part was setting up all of the basic infrastructure to support registering components.

In four years, however, I never wrote code that resembled that test program.

Why not? Because it turned out that it wasn’t all that easy or fun, and I didn’t like the idea of making a full game with it because even a small test program was a bit painful to build up. My implementation of a board game was heavily based on Hannah’s concepts of States and Actions, so it might be a bit more complex than what is typically considered the state of the art. Actually, it’s probably more accurate to say that the implementation was based on my understanding of Hannah’s article, so I probably did things terribly wrong and made it more painful than it had to be.

Each Action typically interacted with multiple States, and so there was a lot of dynamic_cast calls. Practically speaking, adding a new State and its associated Action meant a lot more work than I would have liked. I might as well have stuck with the monolithic game object, and in the years following my original post on the topic, I pretty much did. Most of my projects were small in scope and had very specific designs that didn’t change much, and the code base was manageable enough that it wasn’t a problem when the designs did change.

The Motivation

With Stop That Hero!, I wanted the flexibility to change the design of the game as it was being developed. That isn’t to say that I wanted the ability to make a first-person shooter halfway through the project, but I did want the option of experimenting with new monster types, different player actions, and objectives for a level. I want to be able to change the design of the game without requiring me to change the code drastically. I also wanted the ability to drive the game through the data, which would allow me to create custom scenarios and interesting game experiences, and it would allow players to create their own mods.

I already understood the basic concept of component-based game objects. Instead of monolithic, inheritance-based objects that are hard to change, objects should be identifiers with the components that make up an object being tied to that object identifier. If the design changes, the impact on the project might simply be the assigning or removing of components. For instance, I could have enemies that walk on land or fly in the air. I could introduce a new amphibious enemy by assigning it the ability to walk on land and create a new component related to swimming in water. The code involved is minimal and low-impact on the rest of the project.

What I didn’t understand was how to go about implementing a component-based game object system that wasn’t cumbersome and annoying to use. In my experience, having ready-made components was great for game design, but creating the components and the system to use them was a pain.

The Research

And so, once again, I find myself looking into component-based game design. I found quite a few more resources over the span of a few days as well as some that I have read in the last few years. I’ll quickly list them in case you’re interested in pursuing this topic yourself:

Terrance Cohen’s presentation led me to discover that Insomniac Games has a public-facing research and development page, which led me to his presentation Three Big Lies: Typical Design Failures in Game Programming, which introduced me to the concept of data-oriented design.

And from there, I realized I needed to clarify what it was that I was looking for.

I wanted to learn how to do data-driven, component-based game development in a relatively simple way. What I realized was that I was looking for three different things that had little to do with each other.

One, I wanted my game to be data-driven, which isn’t all that hard. So long as the game is pulling in data from somewhere and acting on that data, it’s data-driven. It’s possible to have the inheritance-based hierarchy of game objects and still run the game based on external data, and it’s possible to use that external data for component-based systems.

Two, I wanted my game design to be easy to change. A component-based system is superior to the inheritance-based one in this regard. With an inheritance-based system, any design change might impact the carefully-planned hierarchy. It can quickly be hard to manage, and changes become more and more painful. Components are easier to change. Add them or remove them, and an object’s behavior changes, and it works on the fly as well.

Three, I wanted to figure out how to write the code for such a system without the complexity I dealt with last time. Seriously, dynamic_cast everywhere a component needed to talk to another component made the creation of new components quite painful. There had to be a new way.

Data-driven games are much more powerful with a component-based system, but it’s outside of the scope of what I want to focus on here. What I was most interested in was the answer to the question “What is the best way for me to implement a game object in my game?”, and frankly, it wasn’t enough to know I wanted components aggregated together. I wanted to know how.

Which brings me back to data-oriented design. According to DOD, the only purpose of code is to transform data. That’s it. Traditionally, programming was focused on algorithms and code, modeling the problem in terms of classes and objects. The problem is that the models tend to add more complexity to the original problem of modifying data.

Now, data-oriented design isn’t the same thing as data-driven design. The former is about programming, while the latter is about game design. See Noel Llopis’ Data-Oriented Design (Or Why You Might Be Shooting Yourself in The Foot With OOP):

OOP is so ingrained in the current game development culture that it’s hard to think beyond objects when thinking about a game. After all, we’ve been creating classes representing vehicles, players, and state machines for many years. What are the alternatives? Procedural programming? Functional languages? Exotic programming languages?

Data-oriented design is a different way to approach program design that addresses all these problems. Procedural programming focuses on procedure calls as its main element, and OOP deals primarily with objects. Notice that the main focus of both approaches is code: plain procedures (or functions) in one case, and grouped code associated with some internal state in the other. Data-oriented design shifts the perspective of programming from objects to the data itself: The type of the data, how it is laid out in memory, and how it will be read and processed in the game.

One thing that wasn’t clear to me while doing all this research is that data-oriented design is not terribly compatible with object-oriented programming, and since most of us game developers know OOP as THE way to program, it’s difficult to see it any other way.

The thing is, it isn’t a normally a problem. OOP can still get you to a correct implementation, especially when performance isn’t your primary concern. The code will run the way it is expected. One of the major advantages touted by all of the data-oriented design articles I found was efficiency. As an indie game developer who doesn’t work on games that push the processor or memory requirements of my customers’ machines, I’m not usually worried about cache thrashing or performance issues. I’m not concerned about throughput on PS3 Cell processors or processing shaders quickly on the GPU. I’m not one of those people who thinks that processor speed is fast enough and memory is large enough for whatever horrible implementation I can come up with, but at the same time, I am not using the Crysis engine and gigabytes of data for my games. I don’t currently make games that take advantage of parallel processing and I most definitely wasn’t going to worry about the cost of calling virtual functions, so initially data-oriented design wasn’t very appealing.

But why I kept pursuing information on it was that it was supposed to be great for unit testing and modularity. Since I’m a big fan of unit tests, being able to write them more easily and with less dependencies would be a huge win. Being able to write simpler code would be another huge win because it can help in the creation of components.

So bottom line: data-oriented design looks like a fantastic way to help me develop a game object system. The code will be simpler and easier to test, and I get the extra benefits of having more efficient code! Nice!

Well, at least at a high level. I still need to figure out what it all means when I don’t have the benefit of an existing company’s proprietary engine. I figured that I needed to explore this data-oriented design thing a bit more.

The first three examples helped me understand how the actual code might be laid out, but it was that last one that really made me understand where OOP is causing problems. It focuses mainly on performance problems related to caching, but the idea of performing a bunch of unrelated actions on a single object at a time versus doing one action for lots of objects at once was really made clear, especially after seeing images 12 and 30-32.

The Frustration

Unless you’re one of the mainstream game developers who have used or implemented a component-based system as part of your job, it seems getting started is the hard part. Game development forums have a number of threads in which people are convinced of the benefits but don’t know how to get a system built.

The article in Game Programming Gems 5 by Bjarne Rene has sample code on the book’s CD, and the good news is that it is a complete solution, but it seems that the complexity of inter-component communication can be a problem. Plus, is it still relevant? It seems as if game developers have moved away from components that perform actions, at least according to what I’ve read.

I haven’t had a chance to look at Game Programming Gems 6, but apparently there is an article on game objects there as well, although it sounds like there is no example code so I’m not sure how hard it would be to follow. The blog T=Machine argues that there is a difference between Entity Systems and component-based systems. Fine, but your entity system is still aggregating components, so regardless of the differences, I need to know how to create a component system.

It seems that anytime there is code in any article or presentation, it’s incomplete or hard to follow. The article might say that you should use IDs and not create an actual object class, and yet the example code has a class. It might show a class deriving from some base that was never introduced or create a function signature without an explanation for why it is there. I almost wish the articles would unit test their way through their sample code just so I could follow along with the author’s intent. Also, it seems that there is no shortage of article series on the subject that never get finished. Some examples are MMO-specific, some are concerned about performance, and none seem straightforward. One article will suggest doing something that another says you shouldn’t do.

And so I felt like pulling my hair out when I sat down to try to implement my own system. At a high, conceptual level, it makes sense to me that an object is nothing but an ID, and it’s the components aggregated together that make up a game object. I understand that I should be able to create an object by creating components, associating them with the object ID, and adding those components to some manager. What was difficult was implementation, and part of the difficulty was about ownership of the data.

I had written an entity manager with a couple of components, only to throw it away after becoming frustrated with how limited it was. I apologize if you’ve read this far and were hoping for more insight into a component-based system. It was too much for me at this time, and I had to stop if I wanted to make progress on my game.

Ultimately, it seems that the component-based system isn’t going to happen, but I need to figure out how to make progress on the game itself. Somehow, in learning a lot more about components, entity systems, and data-oriented design, I feel frustrated and incompetent. Every time I want to write code, I have a dozen different alarms going off in my head warning me that what I want to do isn’t what this author suggests or is against what that author says. My existing code, which I was happy with before, is now feeling too constricting. Whenever I try to make progress, I feel like I have game developer’s block. I can’t see the next step, and even when I think I have, I don’t know how to start. It’s a bizarre feeling.

This post came off more whiny than I would have liked, but I’m not blaming anyone or feeling entitled. I’m just frustrated, and I’m trying to figure out why.

22 replies on “State of the Art Game Objects”

Interesting point. From my perspective, it’s taken all the time + effort so far just to get people to understand how these systems work. It would have been a complete waste of time to provide source code.

Been there, done that, and seen dev teams write pure OOP code in it and fuck up the system.

It’s only this year that I’ve seen a general level of understanding amongst people working with this stuff. When I started writing about these systems, everyone I spoke to couldn’t get their heads round it.

One step at a time…

This subject is also an interesting topic for me. I’ve been playing around with component-based systems for a couple of years now,and i’m doing my uni dissertation on this topic as well.

I’ve been through several wildly different implementations of the component object system, too. The system I have finally stuck with for now is one which gives ownership of the components to small manager systems, which then do whatever they need to do with them. It also gets rid of cast you have to do in Chris Stoy’s implementation (from GPG 6): instead you just query the correct manager for the desired component (for example, want the physics component? talk to the physics system!).

Coding a new component/component system is fast & easy, with a few superclass implementations which implement the common functionality (i.e. management of the collection of components).

I’m currently in the process of binding this system to Lua, which is a bit troublesome (considering i’ve never touched Lua before :P) but the reward should be worth it.

In the end, i’m happy with any system which moves work from the programmer to the designer.

-DBS

Thanks for the comments, everyone. In the end, I think my frustration came from so many competing thoughts and my lack of experience with making a game from scratch that wasn’t meant to be throw-away code after a 48-hour competition. The object system, which is so fundamental to the game, made the issues obvious.

This is a brilliant article. I’m so glad to be subscribing to your blog – mostly because you actually think things through and go the extra mile with your projects from a design sense. The most valuable thing for me are the links to the various articles you have researched along the way. Really handy for a guy like me who is also interested in new design patterns. I too have long felt that OOP isn’t always the best choice. Data-driven design is surely the way to go, especially in games where iterative development is the norm. Data-driven components are more pliable, more flexible, and more open to experimentation and evolutionary development. Keep up the awesome work.

I’ve been thinking about writing a blog post about this too. Maybe your post will motivate me to actually do it.

It doesn’t have to be very complicated. I have a really, really simple entity/component system that I use. You can see it in action in my lastest LD48 entry:

http://code.google.com/p/ld48jovoc/source/browse/ld18_IronAndAlchemy/entity.h
http://code.google.com/p/ld48jovoc/source/browse/ld18_IronAndAlchemy/behavior.h

This is not a great example because I didn’t get very far in the gameplay so you can’t see many examples of behaviors or interactions, but that’s pretty much how it would look like even in a large game.

The “makeEnemy” function in game.cpp is a good example of how this is used.

Entity – A thing in the scene. Owns a Graphical Representation of itself (in this case, it’s a sprite, it could be a 3d object.) Has behaviors.
Behavior – A collection of algorithms that act on the entity. Can have multiple tags (categorical ones like “movement”, “physics”, “enemy” or specific ones like “orc”)

So for example the Player Entity and the Enemy entity both have the “physics” tag, which means they will have game physics.

When an entity or a behavior needs to interact with other behaviors (which doesn’t happen a lot in this simple example) they look them up by tag. Usually I do this in the constructor so it doesn’t have to happen every frame, but it’s pretty fast anyways. For example, the Player behavior modifies at it’s entity’s “physics” behavior for movement based on user input.

The behaviors do know about each other, but only the ones they care about, so it keeps the inter-dependencies pretty much under control without it turning into some byzantine meta-object system. I’ve been thinking about adding a signal-slot system to eliminate even that level of coupling but haven’t found the need to do that yet, it works pretty well for small to medium sized projects as is.

I was also inspired by that Scott Bilas article. If you browse my code, you’ll find a lot of stuff I borrowed from him.

joel

I went through the exact same frustrations when trying to make an Ogre3D game. I never really got the C++ code to a point I was happy with, but I ended up going through the same process for an AS3 project and after a ton of research, planning, and pseudo code… I think I nailed it.

I always planned to write up a blog series on it, but never got around to it. If you’re interested though, the code for the whole thing is here:
http://www.kencation.com/downloads/componentGameDesign.zip

and the end results are here:
http://www.kencation.com/componentGameDesign

I thought about just using IDs as well, but I found that it was more intuitive to make a GameObject class, and that certain functionality fit well there. Hope it helps!

Great writeup.

I’m struggling with some of the same concepts for my current project. Thanks for helping me I’m not alone in struggling with this. Been going away from the computer many late nights head spinning with conflicting ideas and frustration,

Thanks!

I’ve made (and shipped) a couple of component-based games before, and my advice is to start simple and work your way up to the ideal of an id and list of components. As Ken mentions, it’s much easier to start conceptualizing, and get code up and actually running, if you think about a normal “game object” that is a class but is comprised only of a list of other objects. To be really hard core fast in the way that Mike is describing, you’ll eventually want to dissolve the GameObject class and throw the components into arrays of components sorted by type, but for most applications you may never need to go to that extreme (I always think about it but have never had any reason to do it–the simple implementation has always been fine).

The real difficulty with using aggregated objects like this is, as you touched upon, inter-component communication. Who owns the position of the object? That’s a field that many components will have to read and write all the time, but if there’s no central “object” into which you place data, where should it go?

As a first step, just identify the core state that all objects need (position is a good example) and throw it in the base GameObject. Components can reference it quickly without lookups or other infrastructure in the way.

To communicate between components, the *really* simple way is just to tie them together with pointers. This isn’t a long term strategy, but if you’re struggling with nailing down the basic code design, it’s an acceptable short cut. And for a small game, it’s a fine solution: I shipped one game this way and have no regrets.

Longer term, how you pass messages across components will affect a lot of other things in your engine. So far my approach has been to use a shared memory space, usually implemented as a name/value hash with some sort of caching mechanism, to allow components to read and write fields defined at runtime (this pattern is called a “tuple space” in networking circles and a “blackboard” in AI). This works, and I have used it several times, but it always feels like more overhead than it should be. Because I worry about the overhead, I end up making the signals I write across components pretty general, which is probably a good thing because it causes each component to be less dependent on other component implementations.

Anyway, tl;dr: it’s ok to take some shortcuts up front to get the structure of the code defined in your head. Later you can rework the structure of the shell code without changing the content of the actual components much. And restructuring is probably something you could do over the course of several games.

Speaking as one of the “mainstream game developers” who has worked on component system: Being on a big team doesn’t make it easier. There’s a complete dearth of information out there, especially on the pitfalls once you hit larger scale. (And I won’t in any way claim that our specific efforts solved those problems. Components are *hard*)

A couple of those:

* Efficient storage – storing components in a format that’s easy to access, yet doesn’t waste tons of memory
* Inter-component communication. (Don’t. Really. If you can avoid it at all, DO NOT DO THAT. If you have to, batch updates at end-of-frame seem a better way)
* mutable vs. immutable data
* How to structure your components. (Needs to be driven by engine, not designers. If that’s too confusing, do a remap when when cooking data)
* Tools vs. Engine component representation. They have quite different needs, and you better acknowledge that.
* Inheritance or composition? (Composition, always. Structural inheritance is sort-of OK, data inheritance is THE DEVIL)
* Multiple Inheritance? (No, NEVER! Yes, Thief did that. But the cost you pay is *high*)

Getting a component system *right* is a lot of hard work. It might be more than enough to kill any indy effort. So my advice would be, take the things you learned from reading all this (Excellent collection of research, btw!) and apply *as appropriate*

Let the needs of your game drive the code, not the desire to write “the perfect Engine(tm)”. Refine over projects, instead, and progress to whatever satisfies your projects’ specific needs.

I’d say component systems are *far* from a solved problems, and most articles focus on the advantages without talking about the issues and problems.

this is an excellent article, thanks!!

I’ve been working on a 2d game engine, component based in C++. It’s not perfect but Its getting better and better 🙂

@Rachel Could you make an example about how would you suggest to avoid direct component-component comunication??? Maybe they will just query a manager instead of talking “directly” to components??

Im really interested in this topic too, and all the reader coments are really helpful. hope we start to see more information about this topic soon 🙂

cheers

Thanks for the comments, everyone!

Nicolas, if you read adam’s articles at t-machine.org linked in this post, they give you some insight into how components communicate with each other. Essentially, they don’t. Components should just be data, and it’s the systems that make use of components that need to worry about how they deal with them.

So, for instance, you’ll need position data for physics, rendering, collision detection, etc. The Position component just is. If the position changes, the systems dealing with it will just deal with the new position data. If there is a system that requires some entity to know that another entity has moved, it’s that system that will recognize the change and handle it accordingly. So in fact, the entity doesn’t “know” anything. The systems simply run on the data.

Since writing this post, I’ve been able to implement something that works well enough. I have a handful of components so far, and I hope to write up what I’ve done.

Comments are closed.