Component based >? Inheritance based design

Started by
26 comments, last by Jabzor 11 years, 12 months ago
I am working on a scrolling shooter in C++ / SFML, and without knowing anything about component and inheritance based design, I have intuitively started designing my engine and game objects that mostly resembles to inheritance based design.

I have stumbled upon a discussion about this then did some further research, and got to the conclusion that mostly in the 90s Inheritance based design was used in game development, but later on due to several reasons the standard shifted towards component based design, most modern games use that, and that I should probably consider rewriting what I already have following that (since I am mostly doing this for learning).

1. First of all, I would like to ask those who have some experience in this, whether this is mostly true. So is component based design in game development preferable in most cases against inheritance based, or is it not that simple? Are there cases when the opposite is true?

2. Could some of you please recommend me some material about game development related component based design?
Probably the ideal and best thing is to read through some huge book, but for me that doesn't really work when I am introduced to a new idea. It would be much more helpful if I could look at some smaller working examples, a few-page article, perhaps some general rules of thumb, stuff to look out for, or some direct comparison with inheritance based design.

Any assistance / shared opinions, experiences on this subject will be much appreciated.
Thanks in advance! smile.png
Advertisement
Regarding #1 - This isn't just applicable to component-based game entity systems, this is a fundamental teaching of OOP!
There's a ton of writing on composition vs inheritance, and the general rule of thumb is that you should default to composition, and use inheritance only when you have to (and only where you satisfy the promises that an "is a" relationship implies, such as the LSP).
Game component/entity systems are just a fancy way of making use of the software engineering principle of composition.

Excessive inheritance usage was popular in games in the 90's because most people were new to OOP and/or misunderstood OOP in the 90's wink.png
When you're new to OOP, it feels very natural to use inheritance to solve every problem, but there's often an alternative.

N.B. many great games were/are made using this coding style, so while being wrong IMHO, it obviously still works.
I see, thanks for your input!
I've been experimenting with both in my own game and noticed that the main difference is that inheritance-based system tends to be far more "hard-coded" whereas a component-based one tends towards being "soft-coded." As far as pure DATA it doesn't matter that much, but it plays into LOGIC and you need to ask yourself, who do you want designing it - the programmers or the designers? The latter approach is increasingly popular because, much like contemporary games that rely on what-you-see-is-what-you-get editors and visual script/material systems, are all about empowering the designers so they can make and prototype without having to go through the programmers.

While it may seem that a component, designer-friendly component system would be the better choice, it does come at a price. Firstly, you will actually need a framework for handling logic by designers somehow. After all, they may assing whatever properties they want to entity (PhysicalBody, PartOfAFaction, InventoryOwner etc.), which basically destroys the concept of a "class." Think about it. You no longer have a "class CLever" but merely an entity with some CAnimatedModelComponent and CUsable, which triggers the animation and opens some door.

Either you have some flexible scripting framework that you can attach to the OnUse Event, or you hardocde a CUsableDoorOpeningSwitch that also requires a CAnimatedModelComponent to be placed on the entity... but at that point it would have actually been easier to simply make a CLeverEntity with AnimatedModel and TargetDoor properties.

The second problem is that it basically becomes a "weakly typed entity system." So it's great for fast prototyping, but is VERY prone to bugs. Suddenly the designers need to make sure the entity has all the right components that interact properly or unexpected errors will pop up. Worse yet, it is much harder to debug or account for those edge-case scenarios, and many of them wont pop up unless you do a lot of QnA.

In my experience, a component system is far more flexible and faster when set up right; but setting it up requires a lot more work and maintenance, and lack of proper support results in hard-coding very specific components that only apply to very specific types of entities, in which case you would be better off with an inheritance base system from the start.

In a nutshell: Honestly, consider what kind of a game you have, and what kind of entities you need, and go from there. If you dont need too many, inheritance is better. If you need a lot of rapid prototyping, component is the way to go.
Comrade, Listen! The Glorious Commonwealth's first Airship has been compromised! Who is the saboteur? Who can be saved? Uncover what the passengers are hiding and write the grisly conclusion of its final hours in an open-ended, player-driven adventure. Dziekujemy! -- Karaski: What Goes Up...
Thanks for sharing your experience regarding this, I think I understand what you mean. With what I have worked with so far I have actually liked dealing with inheritance based entities, knowing the strict properties and capabilities of each one and treating each differently based on their type. It feels very limiting how in component based design I cannot differentiate entities, or assume any properties one might have, all have to be treated the same from the outside. I assume after some getting used to time it gets more comfortable.

I think my game would actually work just fine with the inheritance based entity structure that I currently have, but I am trying to design my engine similarly to how most modern games are designed, to get relevant experience in game development in hopes of getting a job in the field once I graduate.

Assuming that component based design is more relevant nowadays, I am planning to rewrite that way.

EDIT:
I am wondering, in component based design, is inheritance ok to be used between components, or all components are (or should ideally be) unique, and inheritance in that design model is something to be avoided altogether?
I've currently been looking into both design structures myself. Like yourself, I found my first games automatically leaning towards inheritance. However after looking into component structure it seems the better way to go (allowing for dynamic creation/modification of game entities at run-time is a big plus for me). The way I see it, is that you should almost certainly use inheritance within a component system if it makes sense to do so. An example of this might be a 'Mover' component, you could have both a 'KeyboardMover' and 'AIMover' that would inherit from Mover and imo I can't see any immediate problems in doing that - I could be wrong on that though. That being said, I haven't had much experience in component design but I'm looking to make my next game using exactly that. If anyone has links to good articles on the subject I would greatly appreciate it.
Thanks for your reply.
I found a pretty nice ppt from GDC showing how the development team transitioned from Inheritance based design (that they used for Hulk: Ultimate Destruction) to component based design (that they used for Prototype), and showing how component based design seems superior.

http://www.gdcvault.com/play/1911/Theory-and-Practice-of-the

It doesn't really go into specifics however.
Does anyone know of a good tutorial or project with some sample code that is built on composition?
No problem, that powerpoint sounds interesting might give it a read. You might also find this video helpful: [media]
[/media]
They explain some pros/cons of both designs. Their original engine used an inheritance structure but they've now moved over to a component one.
Interesting links, the GDC and the video. I think there's also room for a mixed approach, especially when it comes to performance. You could do it by distinguishing between "engine" components (graphics, audio, physics etc.) and "gameplay" components (Usable, Inventory, Health, etc.) since the former often require greater optimizations and are less likely to be be rapidly prototyped by designers, whereas "gameplay" components will be constantly swapped around and readjusted.

The GDC mentions that RenderBehavior and PhysicsBehavior as attachable to GameObjects, right next to MoverBehavior or probably things like TriggerBehavior or InventoryBehavior. But what if, instead, you hard-coded that all GameObjects must have the Render/Physics/Audio components (or NULLs) and keep a free list of Gameplay Components? This way you can use direct function calls and make assumptions when it comes to rendering, physics and AI (as it relies on world visible/physical data), but still allow for flexible gameplay prototyping with messages/attributes between components.

You could even go ahead and make a few "base" GameObjects that force certain components; so a CCharacter would always have a RenderableBehavior and CRagDoll, a CProp would always have a CRenderalbe and CPhysics etc. While this does bring back some of the inheritance issues, if you design it right, it could potentially make engine-code much more cleanly separated from Gameplay/AI/Scripting code, and allow for necessary optimizations.
Comrade, Listen! The Glorious Commonwealth's first Airship has been compromised! Who is the saboteur? Who can be saved? Uncover what the passengers are hiding and write the grisly conclusion of its final hours in an open-ended, player-driven adventure. Dziekujemy! -- Karaski: What Goes Up...
In my inheritance based structure, I could have my ship entity that owns 2 wing entities that move and emit particles based on the ships velocity, and can own weapon entities, that are also animated, and can use auto targeting (turn toward and target the closest enemy).

With component based design how is this implemented? Should the ship, wings, weapons be separate entities (each with its own set of components) that are tied together somehow, or I should just have my ship entity and the wings, ship weapons, wing weapons be components?

This topic is closed to new replies.

Advertisement