I'm trying to get my head around component based entity design.
My first step was to create various components that could be added to an object. For every component type i had a manager, which would call every component's update function, passing in things like keyboard state etc. as required.
The next thing i did was remove the object, and just have each component with an Id. So an object is defined by components having the same Ids.
Now, i'm thinking that i don't need a manager for all my components, for example i have a SizeComponent
, which just has a Size
property). As a result the SizeComponent
doesn't have an update method, and the manager's update method does nothing.
My first thought was to have an ObjectProperty
class which components could query, instead of having them as properties of components. So an object would have a number of ObjectProperty
and ObjectComponent
. Components would have update logic that queries the object for properties. The manager would manage calling the component's update method.
This seems like over-engineering to me, but i don't think i can get rid of the components, because i need a way for the managers to know what objects need what component logic to run (otherwise i'd just remove the component completely and push its update logic into the manager).
- Is this (having
ObjectProperty
,ObjectComponent
andComponentManager
classes) over-engineering? - What would be a good alternative?
Answer
The simple answer to your first question is Yes, you are over engineering the design. The 'How far do I break things down?' question is very common when the next step is taken and the central object (usually called an Entity) is removed.
When you are breaking down the objects to such a detailed level as to have size on its own then the design has gone too far. A data value on its own is not a component. It is a built in data type and can often be called exactly what you have started calling them, a property. A property is not a component, but a component does contain properties.
So, here are a few guide lines I try and follow when developing in a component system:
- There is no spoon.
- This is the step that you have already taken in getting rid of the central object. This removes the entire debate of what goes into the Entity object and what goes into a component as now all you have are the components.
- Components are not structures
- If you break something down to where it just contains data then it is not a component any longer, it is just a data structure.
- A component should contain all the functionality needed to accomplish a very specific task in a specific manner.
- The IRenderable interface provides the generic solution to visually display anything in the game. CRenderableSprite and CRenderableModel is a component implementation of that interface that provides the specifics to render in 2D and 3D respectively.
- IUseable is the interface for something that a player is able to interact with. CUseableItem would be the component that either fires the active gun or drinks the selected potion whereas CUseableTrigger could be where a player goes to hop into a turret or throw a lever to drop the drawbridge.
So with the guideline of components not being structures, the SizeComponent has been broken down too far. It contains only data and what defines the size of something can vary. For example, in a rendering component it could be a 1d scalar or a 2/3d vector. In a physics component it could be the bounding volume of the object. In an inventory item it could be how much space it takes up on a 2D grid.
Try and draw a good line between theory and practicality.
Hope this helps.
No comments:
Post a Comment