Quantcast
Channel: C++ – Phil Hassey
Viewing all articles
Browse latest Browse all 10

Dynamite Jack: Component Object model

$
0
0

I’m gonna dig into some of the tech behind Dynamite Jack, so hold onto your seats.

So, a lot of devs are into Component Object game design. That article is by a friend of mine who goes into a good overview of a lot about the model. Anyway, you could probably spend all day reading the resources he links to. The short version (as I see it): Ideal Component Object game design is like a Normalized Database. It basically means, it’s kind of a chore to get it working but it’s super flexible and powerful.

I thought that was interesting. So I went to a talk at 360iDev by Gareth Jenkins. He demonstrated how to do component architecture with real concrete examples, which really helped me get my head around the idea. But the most profound bit of the talk was the end, where I remember him saying something like:

“It doesn’t matter HOW you do this, as long as you DO IT.”

That was super freeing for me. The idea that it didn’t matter how hacky I did it, but it would still give me all the benefits was very helpful. So here’s how I do the component object model in Dynamite Jack:

struct Entity {
  bool active;
  bool has_player;
  bool has_guard;
  bool has_light;
  bool has_position;

  int player_state;
  int player_cartridges;

  int guard_state;

  float light_angle;
  float light_radius;
  float light_degrees;

  float position_x;
  float position_y;
};

#define MAX_ENTITIES 64
Entity entities[MAX_ENTITIES];

Now, you’ll see the cool bit is that I have access to all data without creating anything, so no free / delete needed. The simple bit is activating a feature is just a matter of setting “has_light” to on or off. That’s how I actually turn on and off the player’s flashlight in the game.

In the game code, I just loop through all the items and dispatch to various functions for each component type.

void sys_loop() {
  LOOP_ENTITIES() {
    if (e.has_player) { player_loop(e); }
    if (e.has_guard) { guard_loop(e); }
    if (e.has_light) { light_loop(e); }
    if (e.has_position) { position_loop(e); }
  }
}

And I have a similar function for handling events, and painting the screen. It made it really great for prototyping the game and changing features. The “cave trolls” in the game (see at the start of the trailer) had their AI replaced quite a few times, and being able to just hack new things on and change things around without breaking my other entities was really nice!

One of the other nice things about having it explicitly in code, as opposed to “registering” things magically, is that I can see exactly in my code what order the components are being run in, so if something depends on something else, I can be sure they are in the right order.

Dynamite Jack has 20 different “components” but they all lie in the same big structure. Another cool one is having an “action” component, which doesn’t even exist in the game, it’s just a timer to trigger some future event. With everything being an Entity, it just gets it’s own loop called, and is able to do whatever.

So, yeah, my method gives me only a single Class, as many components as I like, and the flexibility to mix and match stuff. The power to toggle components on and off. And a fixed amount of memory used. So easy “save to file” style serialization of the game state.

Anyway, that’s the tech for the day. I definitely recommend component systems, it makes it SO EASY to try new things with your game, and be able to tweak them until they work “just right”.

-Phil

P.S. If you’re looking for the code on how to do this, it’s all in this post. It really can be THAT SIMPLE 🙂


Viewing all articles
Browse latest Browse all 10

Trending Articles