Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Entities in my game are nothing more than a collection of components, tied together with an entityID. I have (near) data-only components, and systems that work on the data.

One of these components is HitPoints. It is one of the few components that has a little bit more than just data: it houses a Dying event that triggers from the HitPointsSystem when the hitpoints go below 0. One of the event listeners is my user interface, while an entity is selected, it listens to the current selection's Dying event. On-death, the entity is dis-selected. Having entities selected draws little circles around the selection. It works great... Right up until I have an entity without HitPoints that can still die.

I have a Missile in my game which does not have HitPoints, but it can be selected, and it can die. When a Missile is selected, my user interface recognizes that it does not have HitPoints, and therefore also does not have a Dying event, which later causes the draw loop to attempt to draw a "selected" and dead Missile, causing a crash.

You might guess that you could just add HitPoints to the Missile and everything would be fine, but my AI targeting system looks for enemy HitPoints because those are the only things it can damage. I don't want missiles to be targeted, and I don't want to add a special rule either.

So... if all entities can die (or be deleted), where do I place the Dying event? Should I be making a new component? Either a component for all things that can die (almost everything), or a component for AI targets? Or is there a better place to put an event like this?

share|improve this question
2  
I think you need to keep a distinction between EntityRemoved and 'Dying'. Dying should call remove - but removing isn't necessarily 'dying'. That would solve your problem, wouldn't it? –  Vaughan Hilts Aug 3 '13 at 4:35
    
Hmm, wouldn't I still need a Removing event? Where does that go? I have no Entity class. –  John McDonald Aug 3 '13 at 4:37
    
Related chat room conversation: chat.stackexchange.com/rooms/9937/… –  John McDonald Aug 3 '13 at 5:22

2 Answers 2

up vote 2 down vote accepted

I've read up a little bit since our conversation last night, because I was (still am) woefully inexperienced with this particular game architecture. One article I read was Mick West's preeminent talk/case study about using a component-only system. In it, he describes an effort to get rid of a badly written class hierarchy and instead use an entity manager.

One thing that jumped out at me: Mick was indicting classes...but he wasn't really presenting good evidence. He said that their team started with bad code, wrote good code, and solved their problems. That could just as easily have been "we had a terrible entity management system, and we replaced it with a good class hierarchy, and things improved." My point is that bad code is bad, good code is good, and any architecture can occupy either role.

I think the problem with your system is that it doesn't achieve the goals that Mick needed: encapsulation, no tight coupling, simple components that can be added freely.

By relying on Hitpoints to do too much, you've run into problems. They are at the core of your AI's targeting. Depending on their value, they fire an event. That event affects your user interface. You user interface affects your rendering, which checks Hitpoints again to see how to draw. You've got spaghetti.

What happening is that, in spite of using a component-only system, you still have brittle interdependent systems. You don't have encapsulation. You can't add new features to objects without breaking manager systems. You have to add redundant code to (ID value-only) entities, just to keep unrelated functions working. Which, according to Mick, is the original problem you were trying to avoid:

the objects tended to be heavyweight. Objects had unnecessary data and functionality. Sometimes the unnecessary functionality slowed down the game. Functionality was sometimes duplicated in different branches of the tree.

I like your Targetable component, I think that's a step in the right direction. But you probably also need Selectable, Dying, Render...everything as a true single-purpose component. It will be challenging to maintain that stricture when those systems need to talk to each other (and real-world compromise is unavoidable, says Mick), but the alternative is to lose all that your entity system promised to give you.

share|improve this answer
    
I think you're right. I need more, smaller components. Bunches of them, well... 2 more than I have right now: Selectable and Perishable. –  John McDonald Aug 5 '13 at 16:45

As a temporary measure, I have created a Targetable component that I have added to all of the targetable entities, then I added HitPoints to the missile. My AI now targets only Targetable entities, and my UI can listen to the death events for my Missile. This feels like a half-measure. The next entity that comes along and is able to be selected and deleted will also need to have HitPoints, which could be wrong.

Perhaps in the long term, I need an Entity class that can store this? Or maybe every Component should have a death event.

share|improve this answer
    
Why not a Perishable or even Destructible component that's used solely for life/death-events? Your UI could listen for that and both the missile (if you want it selectable) and your units could have it. But the AI would only look for HitPoints for example, which the missile would not have, just Perishable. I guess what I'm saying is: decouple being having hitpoints and being able to die in this case... –  Aktau Aug 5 '13 at 9:07
    
Yeah, I think you and Seth are right. I need more, smaller components. –  John McDonald Aug 5 '13 at 16:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.