Components, systems, subsystems, entities...*collapses*

So I've recently been reading into various articles and forum topics on Component-Based design, or Entity Systems (ES). This concept was probably first used in games when the first Dungeon Siege came out. Apparently it's closest neighbour is possibly that of Aspect-Oriented programming, which I know zero about. At first it seems like a complicated idea, but after I looked through a bunch of info on the net, I think I got the basic idea. Here's my attempt at giving an eagle-eye view of what it is, or rather, what I think it is in the context of a game:

You have three major concepts: entities, components, and systems.


Entity

An entity is a collection of components. These components describe how an entity functions. In terms of a game, an entity is a single instance of an object that exists in your game. So if you have two tanks of the same "type" in your game, you have two entities. Entities do not store data or contain logic. They are simply a means of identifying something.

Components

Components are the basic building blocks for entities. They store information and contain the functionality specific to their existence. For example, you might have a Renderable component in your game which contains all of the logic necessary for the rendering system to display an entity on the screen.

System

Systems have their own set of logic specific to the components that correspond to. I think it is technically possible to implement all of the logic in the system and the component simply be a data container, but I don't think I would like such a design. Often there is a [nearly] one-to-one correspondence between systems and components. You may have a RenderSystem to store all Renderable components and display them when necessary in your game loop. You could also have a PhysicsSystem, AnimationSystem, and so on.


That's my stab at defining those three concepts. The main task in designing your system/game/whatever is to follow the "separation of concerns" idea, each "concern" often mapping to a component/system duo.

So what do you get out of this? Well one thing, it's great for a large development team because, for example, the programmers can offer the game designers a set of components that they can freely use to construct a multitude of objects. These components can be added to an object at runtime to give a dynamic design.

For example, let's say you have a Targetable component which allows the player to select an entity as a target for his/her attacks. Well, let's say we have an NPC that is neutral to the player, but the player does something to provoke the NPC into a battle situation. All we have to do now is attach the Targetable component to this NPC and we're done. The logic surrounding what the player can and cannot attack is simply encapsulated in that component. In the classical OOP approach we would have to define an ITargetable interface that says whether or not the object described by the class is targetable. With ES the existence of a Targetable component on an entity implicitly tells us that the entity can be targeted. With the OOP style, we have to store a variable to say if that object is targetable or not at a specified time.

What one finds in this design is that the deep hierarchy often found in an OOP design is now almost completely flat. Object composition/aggregation is now one's guiding principle. Is this a good thing or a bad thing? One difficulty that often arises is inter-component communication, generally within entities. One could have these components store pointers/references to each other, register callbacks with each other, or use some messaging system to communicate. An example of such communication that seems to often arise is with a physics component. When updated, often animation/spatial components need to be notified of the result.

Well I'm really not sure at the moment whether this design is good or bad, but I think I'm going to give it a shot and document what I find. Things are slow-going with my game [engine] project because it's something I just pick at from time to time. I have no intention on getting a product out the door right away, so I use it to play with new ideas.

The reason I posted this entry was to look for other people's thoughts on this design style, and to give some concrete pros/cons from one's own experience. I'd love to hear about anything surrounding this topic, which includes other design patterns and styles that one found useful in one's own project.

Pointgrey Cameras

For anyone who doesn't know my research, I'm looking into stereo vision algorithms in an underwater camera array. What I'm hoping to do is a rough scene reconstruction that has improved results over blindly using an existing stereo algorithm.

Now on to what this post is about. I found a little subtle and, as far as I can tell, undocumented feature of the Pointgrey cameras. If you use the FlyCapture API then you would normally call flycaptureStart and flycaptureStop to start/stop grabbing images, respectively. For our purposes, we only need to grab single shots from the camera array, not streamed video. On top of that, we want the shots to be (for the most part) synchronized across the whole array.

Here's the twist, the start/stop calls aren't really what starts the "image grabbing" process, but simply powering up/down the camera (via the CAMERA_POWER register). The start/stop calls appear to only lock down/release a DMA context for the purposes of streaming. That means, if you have a firewire card with the TI chipset you can only start 4 cameras simultaneously.

So how do we grab a synchronized set of images using this knowledge? Well this is only applicable to the Grasshopper line of cameras since they have an on-board framebuffer that you can control. Here's what we do:

  1. Place the cameras in "image hold" mode by setting bit 6 to 1 in the IMAGE_RETRANSMIT (0x12F8) register. This will store images on the camera.
  2. Power up the cameras by setting bit 31 to 1 using the CAMERA_POWER register.
  3. Simply wait around long enough for the frame buffers to fill up
  4. Put each camera in trigger mode by setting bit 6 to 1 in the TRIGGER_MODE (0x830) register. What this does is prevent any more images from getting stored in the frame buffer.
  5. For each camera
    1. Start the camera so you can transfer data over to your system
    2. Set bits 24-31 to 0x01 in the IMAGE_RETRANSMIT register to transfer an image.
    3. Stop the camera

This works great for using the cameras in a non-streaming context where you only have a single firewire bus/system to work with. If you want the images to be synchronized, be sure to set them all to the same FPS, and enable image timestamping (FRAME_INFO register, 0x12E8). Now all you do is find the set of images across all cameras which are closest together.

One other subtle thing I found with is that if you start the camera with the same dimensional parameters, but with a different bandwidth parameter, the on-board frame buffer will be flushed. Anyways, that's it for this post. I thought it would be nice to post this information just in case someone else out there has had, or will have, a similar issue. Cheers!

First Look

So what's this score editing application I've been talking about in my posts? We've decided to give a pre-beta teaser. Minus a couple of rendering issues, here's what she looked like a couple of days ago (click image for larger preview):

Score Editor

For our first release we focused on guitar tabs, and making sure the application as a whole works together properly. Unfortunately this release will be a private beta, so everyone will have to wait. I think we have a pretty good app for ~4 months of work (sparse work too, since we're both busy with school and work). Hopefully I've tweaked your interest!