Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411423 Posts in 69363 Topics- by 58416 Members - Latest Member: JamesAGreen

April 19, 2024, 03:23:41 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Component-Based Architechture: Getting Away from Inheritance
Pages: 1 [2] 3 4
Print
Author Topic: Component-Based Architechture: Getting Away from Inheritance  (Read 37044 times)
Theotherguy
Level 1
*



View Profile
« Reply #20 on: January 02, 2010, 07:25:53 PM »

Rather then using integer constants to represent your values you could do it by type. i.e.

Thanks, that's even better than the string idea mentioned before.

It also doesn't bring anything new to the bulk of the problems in a game except potentially slightly more code. The component oriented structure only really solves specific corner cases (like a talking door), and I'd expect there are plenty of cases where inheritence can be far cleaner.

I should have put more emphasis on the fact that component-based interfaces play very nicely with data-driven design, and that new entities can be defined at run-time, which was my main reason for pursuing it.

In regards to your example above you could add an 'Interaction' interface that all entities can hold. A sub-class could be a 'TalkingInteraction' which handles the talking code. You add your TalkingEntity to your TalkingDoor and to NPCs. You might also add a marker interface, Interactable, which the player looks for when searching for interactable objects.
This would accomplish exactly the same thing. An extensible interface would the equivalent of a compile-time component.

While you would get the same code-organization benefit that components provide, you would not get the run-time definition of entities that components give you.
Logged

StudioFortress
Level 0
***



View Profile WWW
« Reply #21 on: January 02, 2010, 09:00:53 PM »

While you would get the same code-organization benefit that components provide, you would not get the run-time definition of entities that components give you.
You could use XML for describing the constructor parameters and other properties of any objects. The code behind those objects could all be structured using inheritence rather then a component driven model.

For things more complicated you could bundle an interpreter or compiler with your game. That would allow you to do anything.

For example Java comes with the Rhino Javascript interpreter and you can compile & load Java classes at runtime (although I'm pretty sure you'll need to redistribute the compiler yourself, but you can).
Logged

Mipe
Level 10
*****


Migrating to imagination.


View Profile
« Reply #22 on: January 03, 2010, 01:20:14 AM »

This thread has been an enlightening read, thank you for taking time to explain yourselves thoroughly! I certainly will be experimenting with this system in my roguelike project in Ruby. However I realize the limitations of this method and am thus going to use it sparingly.

I already use handlers; I have Inputable, Drawable and Updatable modules, which when included in the class make them automatically update, draw or process input without me having to call these procedures, though I have to be mindful of garbage collection. I view this method as an 'attribute' that alters how the object behaves. I believe this is quite similar to what you describe. Mine is an active system, however; I haven't thought of using it for actual game entity components.

I certainly will be experimenting!
Logged
synapse
Level 1
*



View Profile
« Reply #23 on: January 05, 2010, 09:22:48 PM »

I'm totally for the OP.  A component architecture rocked my world in an RTS I worked on.  I had components like:
-Anti Air Missiles
-Flying
-Building
-Walking
-Laser
-Health

By making them generalized, it was trivial to create a new unit that was a walking building that shot lasers, or a missile silo that shot invincible missiles that each used lasers.  It's maybe a goofy example, but it was extremely powerful with all the components we had.  Not to mention, because it's so effectively data-driven, it gives you user-modding for free.

The biggest hurdles are dependencies on shared data.  The two solutions are:
1) Push: Use an event system to publicize significant, medium/low frequency updates.  Things like: Entity death, damage dealt, etc.
2) Pull: For higher frequency updates, like position changes, hard-code any component dependencies.  Thus, the Walking component would require a reference to the Position component.  The dependency is very real, so don't try to pretend it doesn't exist.  This also prevents fringe cases where, for example, a Walking unit has no position (which makes no sense).  Then, your Walking component is able to read the required data at will.

These two simple changes make a component system far more powerful than any inheritance nonsense.
Logged
synapse
Level 1
*



View Profile
« Reply #24 on: January 05, 2010, 09:27:00 PM »

There are other considerations of course, and even more interesting solutions like using Obj-C just to implement the game objects, and providing an external interface (most likely in C) for other languages to interact with the Obj-C portion of the code.  Then you can take advantage of Obj-C message passing where you need it, and use some other language for everything else where you don't need it.

"More interesting solutions" aren't always better ones.  Frankly, two separate languages seems like a much more of a headache than spending 30 minutes to code up a generic entity-handling + component system.
Logged
Parthon
Level 1
*


View Profile
« Reply #25 on: January 05, 2010, 09:37:16 PM »

I should mention this makes much more sense if you're also using data-driven development, and all your entities are in data files separate from the code.

Aha! :D

I read about Component Design a while ago, but it didn't fit with the "every object is a class" idea of game design. Then I read about Data Oriented Design, and that made sense in terms of efficiency and easy of code use, but the question of inheritance still remained.

Looking at it again, it seems like the two go hand in hand perfectly. Data Oriented Design means that your code is sleek and minimal regarding internal data handling, while at the same time your code for game objects will be small because they are made up from components.

Going from regular OO design to Data Oriented and Component Oriented design is a major paradigm shift.

Do you have any more information on these models of design? I'm all excited now.
Logged
Theotherguy
Level 1
*



View Profile
« Reply #26 on: January 05, 2010, 09:58:51 PM »

I should mention this makes much more sense if you're also using data-driven development, and all your entities are in data files separate from the code.

Aha! :D

I read about Component Design a while ago, but it didn't fit with the "every object is a class" idea of game design. Then I read about Data Oriented Design, and that made sense in terms of efficiency and easy of code use, but the question of inheritance still remained.

Looking at it again, it seems like the two go hand in hand perfectly. Data Oriented Design means that your code is sleek and minimal regarding internal data handling, while at the same time your code for game objects will be small because they are made up from components.

Going from regular OO design to Data Oriented and Component Oriented design is a major paradigm shift.

Do you have any more information on these models of design? I'm all excited now.

Please note that there is a difference between "Data-driven development" and "Data-Oriented Design."

"Data-Driven Development" refers to defining all of your game objects at run-time using data files which are interpreted and serialized.

"Data-Oriented Design" refers to grouping similar operations together so that data of a similar type can all be processed at once to increase efficiency.

Of course, both are helped by having a component-based architecture, but I was referring to the former, and not the latter. Component-based architecture makes data-driven development easier by allowing new entities to be defined at run-time. It makes data-oriented design easier by allowing us to manage similar components (A.I, Physics, etc.) all at once.
Logged

Hima
Level 4
****


OM NOM NOM


View Profile WWW
« Reply #27 on: January 05, 2010, 10:03:56 PM »

I've been researching on this Component-based Design and this is a very good read.  

I've tried implemented something similar to this myself but I used both hash and vector to store the components ( std::vector for fast iteration to update and render each component, hashmap for fast access to each component ). But yeah I had problems and the code were messy when I have to deal with communication of each component. But that's probably because I was going and fell into a trap of trying to do something too broad for a game engine.

I'll try implement this with the visual novel game I'm working on. Data-driven design should suit visual novel too.
Logged

Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW
« Reply #28 on: January 06, 2010, 06:24:59 AM »

There are other considerations of course, and even more interesting solutions like using Obj-C just to implement the game objects, and providing an external interface (most likely in C) for other languages to interact with the Obj-C portion of the code.  Then you can take advantage of Obj-C message passing where you need it, and use some other language for everything else where you don't need it.

"More interesting solutions" aren't always better ones.  Frankly, two separate languages seems like a much more of a headache than spending 30 minutes to code up a generic entity-handling + component system.

Multi-language programming is dead simple.  You just need to figure out how each of your languages interfaces with a common medium, such as C (extern "C" for C++, pragma export/import for Ada, etc...)

I would think that using a language that directly supports your paradigm would much less of a headache than hacking together a way to "fake" it another language.  Would you use plain C for an obviously object-oriented problem?  Would you use Java for an obviously procedural problem?  It's the same situation.
Logged



What would John Carmack do?
Richard Kain
Level 10
*****



View Profile WWW
« Reply #29 on: January 06, 2010, 08:47:57 AM »

Anyone interested in seeing this programming methodology in action in an already-created engine should check out the PushButton Engine.

The PushButton Engine

This is a Flash / Actionscript 3 engine that was designed with component architecture in mind. It is also open-source, so you can get a good look how they implemented it in AS3.
Logged
Theotherguy
Level 1
*



View Profile
« Reply #30 on: January 06, 2010, 02:08:35 PM »

Anyone interested in seeing this programming methodology in action in an already-created engine should check out the PushButton Engine.

The PushButton Engine

This is a Flash / Actionscript 3 engine that was designed with component architecture in mind. It is also open-source, so you can get a good look how they implemented it in AS3.

Looks really cool.

I should also mention that Unity3D uses a component-based architecture.
Logged

Cthulhu32
Level 6
*


Brawp


View Profile WWW
« Reply #31 on: January 06, 2010, 02:50:25 PM »

Very cool tutorial Theotherguy, I also really enjoyed your PID tutorial. This is actually the first time I've read through component based engine design, I've always gone the polymorphism route and found clever inheritance tricks in C++. Components are definitely not the "only" way to do a game engine, but I think thats what makes this field so great. You can actually use a great deal of creativity coming up with your own hybrid engines, and there are so many advantages/disadvantages to each system, really you can use whatever you want for any situation.

Something to explore with components vs. inheritance: the Castlevania rpg series. Take a look at Castlevania: Dawn of Sorrow. There was a glitch that allowed you to find glyphs for other characters in the game. The cool part was that they worked! Your character would attempt the animation frames, the weapon would fire, and the game would continue like nothing happened. Would components work for this type of schema, where any player component can have any weapon? Or would this make more sense in an inheritance/polymorphism engine? It would probably work for both, but when you're building a game running on a little Arm9 chip, you have to think a bit about speed.

If you really like components, you should take a look at Virtools. The entire game engine is a component creator/linker/manager. http://images.gamedev.net/features/reviews/virtools/Image1.png
Logged

synapse
Level 1
*



View Profile
« Reply #32 on: January 07, 2010, 07:33:44 PM »

There are other considerations of course, and even more interesting solutions like using Obj-C just to implement the game objects, and providing an external interface (most likely in C) for other languages to interact with the Obj-C portion of the code.  Then you can take advantage of Obj-C message passing where you need it, and use some other language for everything else where you don't need it.

"More interesting solutions" aren't always better ones.  Frankly, two separate languages seems like a much more of a headache than spending 30 minutes to code up a generic entity-handling + component system.

Multi-language programming is dead simple.  You just need to figure out how each of your languages interfaces with a common medium, such as C (extern "C" for C++, pragma export/import for Ada, etc...)

I would think that using a language that directly supports your paradigm would much less of a headache than hacking together a way to "fake" it another language.  Would you use plain C for an obviously object-oriented problem?  Would you use Java for an obviously procedural problem?  It's the same situation.

1) Have you tried debugging a project that goes across more than one language?  It's nuts.
2) Programming something not native to a language isn't 'faking it'.  If it took 100 hours to program the support, sure, it'd be better to use another language.  But a generic component system takes like a couple hours at most.  Best part is, the infrastructure is totally reusable once its setup.

The final point is that it's not about using C++ over Objective C, it's about not being limited to Objective C.  If I was programming a game for Flash that used a component system, would you tell me to use Objective C because of 'the paradigm'?
Logged
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW
« Reply #33 on: January 07, 2010, 08:08:56 PM »

1) Have you tried debugging a project that goes across more than one language?  It's nuts.

Yes, and it's not nuts at all, at least with GDB.  The transitions between languages are pretty much transparent.  What debugger are you using?

If I was programming a game for Flash that used a component system, would you tell me to use Objective C because of 'the paradigm'?

Yes, I absolutely would, assuming a suitable compiler existed.

I liken it to building a house.  You can build a house using a screwdriver to pound all your nails, but wouldn't you rather use a hammer for that?  It's about using the right tool for the job.  People here seem to be all crazy about using languages like C++ in tandem with scripting languages like Lua, and this is fundamentally no different.
Logged



What would John Carmack do?
Kadoba
Level 3
***



View Profile
« Reply #34 on: January 08, 2010, 08:48:57 AM »

Hammers and screwdrivers have no learning curve. Hammers and screwdrivers do no need to interact with each other. Hammers and screwdrivers will work in any environment.

I'm not disagreeing with you but I think you're oversimplifing things just a bit.
Logged
DeadPixel
Level 2
**



View Profile WWW
« Reply #35 on: January 08, 2010, 10:19:57 AM »

I don't really think looking to implement this design pattern in a different language just because it may or may not offer the same sort of functionality as a feature of said language is the way to go.  Depending on your platform and language of choice this isn't always going to be an available or even reasonable option to implement.

Anyway, more OT, I think the write up was very good and offered very practical examples.  Thanks for that.  I've implemented the same pattern in C# (using class types as the key for the hashtable as mentioned before).  It's clean and works well and offers great modularity.  I don't believe it's a catch-all for all of your entity problems, and for a small scale game is likely over-complicating the matter.  When it fits, though, it's a darling to work with.

If you're looking for more info on the subject I'd suggest taking a look at Mick West's article http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/.
Logged

Karel
Level 0
**


View Profile
« Reply #36 on: January 11, 2010, 03:35:21 AM »

I totally love component-based architectures, but I severely dislike the implementation presented in this tutorial. There are several problems with it in my opinion.

Firstly, the fixed list of component types is a terrible idea, and should be replaced by a string-based system, or perhaps the type-based system proposed by someone else in this thread. You just don't want a central list in your code that has to be updated for every new component.

Secondly, it makes some assumptions about the behaviour of the components that might not hold. For example, it has an update and render method for every component, while some components might not need to update or render at all.

When I first set out to build a component-based architecture, I had a really difficult time adapting my mindset from inheritance-based thinking. When I finally made the switch, however, a whole new world opened up to me, and I'm never going back in game development. A good component-based architecture is so much more convenient and easy to work with than an inheritance-based system. And if properly implemented, it also deals with the issues of polymorphism raised by some of the readers here (while the method proposed here does not!)
Logged
Karel
Level 0
**


View Profile
« Reply #37 on: January 11, 2010, 03:38:58 AM »

Because I couldn't find a good open-source component-based framework library, I decided to build one myself. It's been available for a while on google code, but it hasn't been picked up by anyone yet, which surprised me, as I thought there would be a huge market for generic, easy-to-use component-based frameworks. It deals with all the issues I mentioned above, by using a powerful message-passing interface.

You can find it at:
http://code.google.com/p/cistron/
Tutorial/example code using Cistron

I have been using Cistron intensively over the course of two years while working on several large game projects of mine, so it is definitely mature enough to be used in a real-life, demanding environment.

The first strong point of Cistron of is its ease of use. I use several template tricks to hide programming complexities from the user, providing a smooth, yet powerful interface to interact with other components. The library is also extremely small and only depends on the boost library for its implementation, so it should work on any platform. Installation comes down to compiling the three source files and including Cistron.h wherever you want to use the framework.

Its second strong point is its speed. The overhead of sending messages instead of calling functions directly can be reduced to near-zero. The slowdown, caused by mapping a string (which is usually used to identify a message/event) to a set of listeners can be smartly avoided. How this is done is explained in the documentation.


It took me several iterations to get the framework to where it is now. It was a very long process because there is so very little information available on the internet about this type of paradigm. If you plan on using Cistron for one of your projects, please let me know. I would like to know what it is used for. Also, feedback is hugely appreciated!
Logged
westquote
Level 0
**


I make games in Philly. How rare!


View Profile WWW
« Reply #38 on: January 11, 2010, 10:33:25 AM »

1) Have you tried debugging a project that goes across more than one language?  It's nuts.

Yes, and it's not nuts at all, at least with GDB.  The transitions between languages are pretty much transparent.  What debugger are you using?

If I was programming a game for Flash that used a component system, would you tell me to use Objective C because of 'the paradigm'?

Yes, I absolutely would, assuming a suitable compiler existed.

I liken it to building a house.  You can build a house using a screwdriver to pound all your nails, but wouldn't you rather use a hammer for that?  It's about using the right tool for the job.  People here seem to be all crazy about using languages like C++ in tandem with scripting languages like Lua, and this is fundamentally no different.

I think you are vastly oversimplifying things by saying that using GDB makes debugging multiple languages easy.  You must understand that this is only true for some languages, and if you are using an IDE that supports GDB.  I know that Wii and DS programming, for instance, must be debugged through Codewarrior or Radix, and that 360 debugging must be done through Visual Studio.  So, for those people, GDB isn't an easy option.  It also assumes that your debugging information in all languages is represented in the form of Dwarf or stabs, or some other format that GDB supports.  It also assumes you are not using a popular game scripting language that is unsupported by GDB such as (I believe) AngelScript, GameMonkey, or Actionscript (such as through ScaleForm).  If the developer isn't within your implicit (and by no means given) constraint space, your statement is largely invalid.

It would have been nice if you had said something more qualified, such as "That's true, it can be nuts.  I get around that by using GDB, and making sure I never sign up to work in multiple languages unless I have access to an IDE and language that GDB supports.  YMMV, however, because I realize that not everyone can guarantee that."

As for your second point, you say, "Yes, I absolutely would, assuming a suitable compiler existed."  That is an asinine assumption to make in light of the context of the poster's question.  Such a compiler does not exist, and we are all well aware of that.  The original poster's question was rhetorical, and was intended to point out that he does not have access to such a compiler.  If he did, I don't think he wouldn't have said what he said in the first place.  I believe that his very point was that Objective C locks you into platforms that support Objective C.

All that being said, I agree that having access to Objective C might be handy for game development, as either a host or extension language.  I developed an iPhone game in Objective C++ (unified Objective C and C++), and I appreciated being able to use the right tool for the job in each situation that came up.  That being said, Objective C++ is uncommonly convenient because it allows both languages to access each others' object models, which I have found to be rare in multi-language programming.  C bindings, import/exports, and string messages introduce many complications that may or may not be worth it in a given game project.  In particular, you usually have to find a way to map language-specific programming constructs from one language onto another (types, structures, function objects, coroutines, constness, volatility, privacy, etc...), or to never allow those to bridge the gap.  In some cases, you may end up doing far more work in order to support a second language than you would have done implementing your system within the original language, or switching to the other language outright.  I have my doubts as to whether it would be a clear win to switch to Objective C just to be able to conveniently implement this particular object/message paradigm.

Also, there is a small distinction between Flash + Objective C and Lua + C++, which is that Lua was intended as an extension language, and as such tends to play nicely with other languages, by design.  Not all languages are created equally in this regard.
Logged

Twitter: @westquote - Webpage: Final Form Games
Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #39 on: January 11, 2010, 11:05:57 AM »

Because I couldn't find a good open-source component-based framework library, I decided to build one myself. It's been available for a while on google code, but it hasn't been picked up by anyone yet, which surprised me, as I thought there would be a huge market for generic, easy-to-use component-based frameworks. It deals with all the issues I mentioned above, by using a powerful message-passing interface.

You can find it at:
http://code.google.com/p/cistron/
Tutorial/example code using Cistron

I have been using Cistron intensively over the course of two years while working on several large game projects of mine, so it is definitely mature enough to be used in a real-life, demanding environment.

The first strong point of Cistron of is its ease of use. I use several template tricks to hide programming complexities from the user, providing a smooth, yet powerful interface to interact with other components. The library is also extremely small and only depends on the boost library for its implementation, so it should work on any platform. Installation comes down to compiling the three source files and including Cistron.h wherever you want to use the framework.

Its second strong point is its speed. The overhead of sending messages instead of calling functions directly can be reduced to near-zero. The slowdown, caused by mapping a string (which is usually used to identify a message/event) to a set of listeners can be smartly avoided. How this is done is explained in the documentation.


It took me several iterations to get the framework to where it is now. It was a very long process because there is so very little information available on the internet about this type of paradigm. If you plan on using Cistron for one of your projects, please let me know. I would like to know what it is used for. Also, feedback is hugely appreciated!

Thanks, I will probably check it out.
Logged

Pages: 1 [2] 3 4
Print
Jump to:  

Theme orange-lt created by panic