Game Development Community

Basic component design question: real-world example

by Michael Vargas · in Torque X 2D · 04/19/2007 (11:25 pm) · 4 replies

Hi,

I'm trying to follow good component-based design (which is pretty new to me), so I wanted to throw out an example that I'm facing and see how the component gurus would handle it.

Consider a simple game in which there are destructible objects (say, space ships), and little health meters next to the space ships to display their current health. I want a way to component-ize this scenario.

So, health seems generic enough that it can be its own component, e.g. HealthComponent. Perhaps all this would do is store the object's maximum health and current health and have properties to change them. Then there could be a HealthMeterComponent, which retrieves its values through generic properties (and in my case they'll be updated from the HealthComponent) and contains some sort of GUI for drawing the health meter.

Does this seem like a sound plan? Should I also have a ShipComponent to tie it all together, or is that not necessary? Ideally (it seems), HealthComponent wouldn't depend on HealthMeterComponent and vice versa. But if these components didn't have any dependencies with one another, it would seem that I'd need somewhere to facilitate communication between the two. Where would that ideal place be?

Am I on the right track?

#1
04/20/2007 (7:18 am)
How could I resist the temptation of answering this and thinking myself as a "Component Guru" ;)

But I think you're on the track. Of course there are no absolute truths here, but your example sounds like a good way to go. A couple of "rules of thumb" that have worked for me:

- Create it in TGBX: It's usually a good sign, if your potential component would be something you can create & configure in TGBX by assigning it to a game object. Using your example, you would probably assign the HealthComponent to your sprite and set the maximum&start health.

- Multiple uses: You can create different kinds of game objects by changing the properties. You could probably use the HealthComponent to create players, NPC's and monsters with different amounts health.

- Independence: Creating/registering the component should optimally depend on only the .Owner of the component and things attached to it (other components and mounts). It can't be avoided completely, but it's a bad sign if you have to tweak the order of creating/registering/mounting the objects so that dependencies are met.

- Don't over do it: Don't get too academic about it by starting to create different components for tinyest actions. If your design is othewise solid, it's probably not a huge problem to separate things to components as they become apparent. When you in any case endup rewriting & restructuring the code, whether it's a class or component doesn't make a big difference.

Matias
#2
04/20/2007 (9:50 am)
Thank you for the very helpful feedback, Matias. I'm glad to hear that I'm going about this in a somewhat sane fashion. :)
#3
04/20/2007 (10:17 am)
@Michael - In your scenario, "health" seems like it's too isolated to merit the overhead of a component just for that. Wouldn't it just be a single variable? If you had a lot of different stats, maybe a "ship statistics" component or something would make sense. The HealthMeterComponent makes sense to me as a component, though. It's complex enough that it makes sense to have a chunk of functionality that you want to encapsulate inside a component, and it's general enough that I can easily see you using it for a variety of different objects in the game, and also potentially reusing it in a different game later.

You probably shouldn't have a "ship component" just to "tie things all together". What "ties things all together" is aggregating the components you want into a particular configuration, i.e. your ship object. Now, if you instead mean something like a "statistics" component or something that a lot of other components happen to interact with then that's fine. Just make sure that you're not trying to shoehorn the component system back into a hierarchical object mindset.

In terms of components communicating with each other, the "interface" system is supposed to be the standard way to do that. I'm not sure there are any good examples, though.
#4
04/20/2007 (12:50 pm)
Dan, I am not sure I agree with you. I can see alot of benifits to assigning a health component even if it means it is just a variable at the moment. Reason being that in the case of a project which might grow in size, he might want to expand upon the health component to encomapass functionality based on what particular health he is at. For instance, ship slows down at half health, or displays a different "damaged" animation state. Health is a big issue in games, I wouldn't be so quick to just cram it into the movement component or wherever else you wanted to put it, unless the scope of your game was small and you wern't thinking of adding too much too it. It also keeps the coding reasonable and understandable, as you have catagories such as health seperate from categories such as, canon, or shields.

As for interfacing, I spoke to some people from garage, and they told me interfacing is not always and in fact it is unusual when you would want to be using this method. Instead, use the torqueobject database, and findcomponent<>() method to get to your stats from remote places, such as a lazer.



Quote:Does this seem like a sound plan? Should I also have a ShipComponent to tie it all together, or is that not necessary?

edit: ShipComponent may be necesary probobly only in the case of wanting to cram two different components together. However it might be very useful if you are planning to add and remove mounted objects to the ship, a ship component could do that well. In the case of a fleet of ships, a ship component could be used to dictate the unique features of each ship, IE, name, type of guns, thrusters, etc. The point being, you don't need a ship component. You can just assign the object a "Type" such as "ship" and that will define it as a ship for the game.