Page 1 of 5
Component Systems (formerly: Component Oriented Programming)
Posted: Fri Aug 20, 2010 9:21 pm
by EccentricDuck
Due to the interest that this topic seems to have triggered for several users, myself included, I wanted to make a dedicated thread for it in the programming section. Here's the topic where we previously talked about it:
http://thechaosrift.com/viewtopic.php?f=11&t=5269
Feel free to talk about design questions related to it, talk about how you're doing it in your project, or even your general thoughts on it. I know I'll have several questions as I implement this sort of system into my game. I'd like to draw a graph that shows exactly how it's implemented in my game once I get further along (including how the components interact with lower level managers). On that note, what was the program that Falco used for displaying the AssetIO Component framework in video 2 of AiGD 17? I've heard people mention both XCode and Visual Studio, but I haven't heard either of those confirmed. Also, where would you go to access it in its respective program?
Currently, my game is structured like this:
I have the entry point which is in my main Game class. This class creates a GameComponentCollection (this is built into the game class in the XNA framework through inheritance - same idea as the entity-component system but on a lower level), ScreenManager (which is a game component), and some other fundamental managers/devices. From there, the ScreenManager "creates" (through one of the other screens) the GameplayScreen (there's other screens, like for the Menu and Lobby which come first, but they don't have particularly complex logic). The GameplayScreen creates a World Object. That World object then creates Entities which create Components.
So essentially: Game --> ScreenManager --> GameplayScreen --> World --> Entity --> Component
I'm using XNA's GameComponent or DrawableGameComponent as a base class for my entity Components. It has some nice functionality which helps to manage and run Update() and Draw() methods as well as adding and disposing of the components. It so happens that my ScreenManager class also derives from DrawableGameComponent. I was concerned at first , but it really makes quite a bit of sense the more I think about it. It allows me to use a common framework for adding and removing functionality at high and low levels.
I'm debating what functionality to add into the Entity class itself. I'm assuming giving it a position coordinate and alive flag is essential, but beyond that I'm not entirely sure what to separate into a component and what to include in the class. For now I think I'll just add that and see if anything else strikes me as essential for all entities.
Re: Component Oriented Programming
Posted: Fri Aug 20, 2010 11:09 pm
by XianForce
EccentricDuck wrote:I'm debating what functionality to add into the Entity class itself. I'm assuming giving it a position coordinate and alive flag is essential, but beyond that I'm not entirely sure what to separate into a component and what to include in the class.
Doesn't adding anything into the Entity class besides a container of components somewhat defeat the purpose of a component based system?
Re: Component Oriented Programming
Posted: Fri Aug 20, 2010 11:30 pm
by dandymcgee
XianForce wrote:EccentricDuck wrote:I'm debating what functionality to add into the Entity class itself. I'm assuming giving it a position coordinate and alive flag is essential, but beyond that I'm not entirely sure what to separate into a component and what to include in the class.
Doesn't adding anything into the Entity class besides a container of components somewhat defeat the purpose of a component based system?
Yes.
Entities are SOLELY a collection of components.
Components contain ONLY data, no methods.
Systems (or
Managers if you prefer) contain the methods and logic to update their respective components' data.
At least this is the most solid design I've yet seen put forth. Component Oriented Programming is EXTREMELY undocumented in comparison to the almighty OOP paradigm. In reality, a component-based system is whatever the hell you define it to be.
As a great man once said:
"That is the beauty of programming. There is never one right way, but there are always many wrong ways."
Re: Component Oriented Programming
Posted: Sat Aug 21, 2010 4:18 am
by ismetteren
At least this is the most solid design I've yet seen put forth. Component Oriented Programming is EXTREMELY undocumented in comparison to the almighty OOP paradigm. In reality, a component-based system is whatever the hell you define it to be.
Why do some of you insist that programming your entities with components instead of hierarchys makes it less OOP and therefore have to call it Component Oriented programming as opposed to OOP. I mean, one of the GOF OOP design principles is the favor composition over inheritance(okay, i don't know if it actually was the GOF who said it, but i'm pretty sure, it is a pretty known principle at least)?
Re: Component Oriented Programming
Posted: Sat Aug 21, 2010 5:13 am
by K-Bal
I now have a system for creating and adding components, which is inspired by
this and
this article. I still need to create a game event system to make it less hardcoded.
Code: Select all
int main()
{
sf::RenderWindow window( sf::VideoMode( 300, 200 ), "Test", sf::Style::Close );
window.UseVerticalSync(true);
ComponentFactory factory;
factory.RegisterComponent( "Movement", &MovementComp::Create );
factory.RegisterComponent( "Rendering", &RenderComp::Create );
factory.RegisterComponent( "Collision", &CollisionComp::Create );
GameObject player( factory );
player.AddComponent( "Movement" );
player.AddComponent( "Rendering" );
player.AddComponent( "Collision" );
GameObject stick( factory );
stick.AddComponent( "Movement" );
stick.AddComponent( "Rendering" );
stick.AddComponent( "Collision" );
while( window.IsOpened() )
{
float delta = window.GetFrameTime();
player.UpdateComponents( delta );
player.UpdateProperties( delta );
stick.UpdateComponents( delta );
stick.UpdateProperties( delta );
sf::Event event;
while( window.GetEvent( event ) )
{
switch( event.Type )
{
case sf::Event::Closed:
window.Close();
break;
default:
break;
}
}
const sf::Input& input = window.GetInput();
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(0.f, 0.f));
if(input.IsKeyDown(sf::Key::Down))
{
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(0.f, 50.f));
}
if(input.IsKeyDown(sf::Key::Up))
{
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(0.f, -50.f));
}
if(input.IsKeyDown(sf::Key::Left))
{
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(-50.f, 0.f));
}
if(input.IsKeyDown(sf::Key::Right))
{
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(50.f, 0.f));
}
window.Clear();
window.Draw(player.GetProperty< sf::Sprite >("Rendering:Shape").Get());
window.Display();
}
return 0;
}
Re: Component Oriented Programming
Posted: Sat Aug 21, 2010 4:45 pm
by dandymcgee
ismetteren wrote:At least this is the most solid design I've yet seen put forth. Component Oriented Programming is EXTREMELY undocumented in comparison to the almighty OOP paradigm. In reality, a component-based system is whatever the hell you define it to be.
Why do some of you insist that programming your entities with components instead of hierarchys makes it less OOP and therefore have to call it Component Oriented programming as opposed to OOP. I mean, one of the GOF OOP design principles is the favor composition over inheritance(okay, i don't know if it actually was the GOF who said it, but i'm pretty sure, it is a pretty known principle at least)?
Because they're two completely different paradigms. Just because they can both be used in the same project doesn't make them the same thing. That's like saying a data type and a function are the same thing because you can put them both in a class.
Re: Component Oriented Programming
Posted: Sat Aug 21, 2010 8:31 pm
by GroundUpEngine
K-Bal wrote:I now have a system for creating and adding components, which is inspired by
this and
this article. I still need to create a game event system to make it less hardcoded.
Re: Component Oriented Programming
Posted: Sat Aug 21, 2010 9:35 pm
by K-Bal
GroundUpEngine wrote:K-Bal wrote:I now have a system for creating and adding components, which is inspired by
this and
this article. I still need to create a game event system to make it less hardcoded.
Code: Select all
[/quote]
Nice man![/quote]
Thanks, but don't take my approach too seriously. I haven't gathered some real use case experience, yet.
Re: Component Oriented Programming
Posted: Sun Aug 22, 2010 11:24 pm
by EccentricDuck
XianForce wrote:EccentricDuck wrote:I'm debating what functionality to add into the Entity class itself. I'm assuming giving it a position coordinate and alive flag is essential, but beyond that I'm not entirely sure what to separate into a component and what to include in the class.
Doesn't adding anything into the Entity class besides a container of components somewhat defeat the purpose of a component based system?
I don't think it would totally defeat the purpose - not if it's functionality that is essential to every entity. Those two (position and an alive flag) are really the only things I could think of though... and I suppose I could theoretically use an entity for something that doesn't have a position... like using it for level music - it might be nice for someone who's scripting to add an entity that implements a music component for general background music. Would keep the different methods that a scripter might need access to at a minimum (after all, not all scripters are fully competent programmers).
Yeah, I think an alive flag would be useful for every entity. If the alive flag is turned to off I can get rid of the entity object and all the components attached to it. Then again, perhaps just calling a method to do that would be simpler than changing an alive flag to false so that an if statement in one of my update loops can check the flag and then call the same method (or implement it directly I suppose). I suppose that getting rid of the entity and components from one of the components (like health) would break tight encapsulation which is probably why I haven't seen it, but whatever, it's implementing the same thing either way only with less overhead...
I came to totally opposite conclusions to what I started saying in both those paragraphs. There should be a word for that. Hmm... guess that's what happens when I let the voices in my head argue
Re: Component Oriented Programming
Posted: Sun Aug 22, 2010 11:26 pm
by EccentricDuck
K-Bal wrote:I now have a system for creating and adding components, which is inspired by
this and
this article. I still need to create a game event system to make it less hardcoded.
Code: Select all
int main()
{
sf::RenderWindow window( sf::VideoMode( 300, 200 ), "Test", sf::Style::Close );
window.UseVerticalSync(true);
ComponentFactory factory;
factory.RegisterComponent( "Movement", &MovementComp::Create );
factory.RegisterComponent( "Rendering", &RenderComp::Create );
factory.RegisterComponent( "Collision", &CollisionComp::Create );
GameObject player( factory );
player.AddComponent( "Movement" );
player.AddComponent( "Rendering" );
player.AddComponent( "Collision" );
GameObject stick( factory );
stick.AddComponent( "Movement" );
stick.AddComponent( "Rendering" );
stick.AddComponent( "Collision" );
while( window.IsOpened() )
{
float delta = window.GetFrameTime();
player.UpdateComponents( delta );
player.UpdateProperties( delta );
stick.UpdateComponents( delta );
stick.UpdateProperties( delta );
sf::Event event;
while( window.GetEvent( event ) )
{
switch( event.Type )
{
case sf::Event::Closed:
window.Close();
break;
default:
break;
}
}
const sf::Input& input = window.GetInput();
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(0.f, 0.f));
if(input.IsKeyDown(sf::Key::Down))
{
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(0.f, 50.f));
}
if(input.IsKeyDown(sf::Key::Up))
{
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(0.f, -50.f));
}
if(input.IsKeyDown(sf::Key::Left))
{
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(-50.f, 0.f));
}
if(input.IsKeyDown(sf::Key::Right))
{
player.GetProperty< sf::Vector2f >("Movement:Velocity").Set(sf::Vector2f(50.f, 0.f));
}
window.Clear();
window.Draw(player.GetProperty< sf::Sprite >("Rendering:Shape").Get());
window.Display();
}
return 0;
}
I like the look of that implementation K-Bal, thanks for the code and the links. One of the things I've been struggling with is how exactly I should implement add/remove component methods and communication between entities (or more specifically how the managers implement that logic).
Re: Component Oriented Programming
Posted: Sun Aug 22, 2010 11:30 pm
by EccentricDuck
dandymcgee wrote:ismetteren wrote:At least this is the most solid design I've yet seen put forth. Component Oriented Programming is EXTREMELY undocumented in comparison to the almighty OOP paradigm. In reality, a component-based system is whatever the hell you define it to be.
Why do some of you insist that programming your entities with components instead of hierarchys makes it less OOP and therefore have to call it Component Oriented programming as opposed to OOP. I mean, one of the GOF OOP design principles is the favor composition over inheritance(okay, i don't know if it actually was the GOF who said it, but i'm pretty sure, it is a pretty known principle at least)?
Because they're two completely different paradigms. Just because they can both be used in the same project doesn't make them the same thing. That's like saying a data type and a function are the same thing because you can put them both in a class.
dandymcgee** has a point, they're both OOP. It's just that OOP usually infers inheritance (at least in my mind) where as a component approach eschews it - so it's kind of useful to specify it more precisely and "component oriented progamming" helps to do that.
**Sorry, I meant to say ismetteren in reference to OOP. My follow up point though followed what dandymcgee said since I think it's worth mentioning "component oriented" or some other term that specifically refers to that approach instead of inheritance based hierarchies.
I've been making mistakes like mad over the past few days.
Re: Component Oriented Programming
Posted: Mon Aug 23, 2010 11:17 am
by ismetteren
dandymcgee wrote:
Because they're two completely different paradigms. Just because they can both be used in the same project doesn't make them the same thing. That's like saying a data type and a function are the same thing because you can put them both in a class.
I understand that you can use two different paradigms in one project, but programming entities with components is still OOP. OOP doesn't have to include very deep and complex inheritance trees, most people actually agree that it is bad OOP design, and that composition should be favored over inheritance.
I do agree that it is useful that have a name for the component based approach to programming entities, but you talk as if it is something completely different from OOP(or i am just misunderstanding you? ... "
they're two completely different paradigms" okay, i guess i'm not).
Re: Component Oriented Programming
Posted: Mon Aug 23, 2010 4:51 pm
by Falco Girgis
"Component" systems are a mere OO design pattern. They ARE object-oriented by nature. Calling it COP is like calling using the Factory design pattern FOP.
Re: Component Oriented Programming
Posted: Mon Aug 23, 2010 5:30 pm
by EccentricDuck
GyroVorbis wrote:"Component" systems are a mere OO design pattern. They ARE object-oriented by nature. Calling it COP is like calling using the Factory design pattern FOP.
Hmm, I see both your points. I suppose just saying something like a "component system" might be better then in order to distinguish it from an "inheritance tree". It's definitely useful to call it by something, but I can see how calling things "XXXX oriented programming" could get excessive.
Re: Component Oriented Programming
Posted: Tue Aug 24, 2010 1:11 pm
by dandymcgee
GyroVorbis wrote:"Component" systems are a mere OO design pattern. They ARE object-oriented by nature. Calling it COP is like calling using the Factory design pattern FOP.
Again, it all goes back to this:
dandymcgee wrote:At least this is the most solid design I've yet seen put forth. Component Oriented Programming is EXTREMELY undocumented in comparison to the almighty OOP paradigm. In reality, a component-based system is whatever the hell you define it to be.
Everyone agrees that a "component" is a composed object. What one does with the idea and how strictly one applies "component-based" determines whether it is being used as OOP strongly favoring composition, or an entirely different paradigm altogether.
As such, I was referring to the strictest implementation (so-named "entity system" by the author who is defining it) I've seen thus far. It is presented in this 5-part article (which has been posted already):
http://t-machine.org/index.php/2007/09/ ... nt-part-1/
Anyone can use make a class called "Component", compose a list of objects within a skeleton class called "Entity", and say "Look, I made a component-based system!". My point is that without a solid definition of what this classification means (or rather whose definition we are going by), and which approaches are eligible to be referred to as such, it's anybody's guess.
Moral of this long ass story: This is Falco's board. When he says, "Component" systems are a mere OO design pattern" that is the definition he has chosen to go by, and therefore is the definition we all should go by. If you choose otherwise, state so in your post to avoid confusion.