Jump to content
  • Advertisement
Sign in to follow this  
l0k0

Unity Component Entity Model Without RTTI

This topic is 2349 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts


Is that close?

Getting closer, certainly...

I'd take to task your decision to have components attached to entities though. Just give each joint a reference to each transform it is connected to, and process them all as generic joints.

Share this post


Link to post
Share on other sites
Advertisement
Would each joint still be an entity though? I guess I see your point. There is no reason to attach components to each other if you don't have a reliable way to query for a specific type (or would want to). The car still needs to have some level of ownership of the joints though, otherwise they get created and then lost in the void. How would you destroy them later? Are you suggesting that the car entity just keep specific references to what it needs rather than use some generic attachment mechanism?

Share this post


Link to post
Share on other sites
Yes, pretty much.

When you create a joint you pass it the two transforms it requires. When you create the car, you would pass it a list of associated joints, because the car needs to keep track of joints, and destroy them when it too is destroyed (given that both the wheels and the chassis will likely survive the destruction of the car itself)

Share this post


Link to post
Share on other sites
Would recommend then the car itself not create the joints, but instead merely be assigned them by whatever function creates the car? It seems to me that the car should be responsible for creating the joints and maintaining them. Otherwise the system creating the car has to worry about internal details. Do you see a benefit to doing it the former way?

Share this post


Link to post
Share on other sites
it depends how much flexibility you are going for.

I would say that a car is any entity with 'Wheel's, a 'WheeledVehicle' behaviour, and a 'VehicleController' attached. What makes it specifically a 'Car', is that it is produced by a 'CarFactory' function, that incidentally sets up an 'OnDestruct' handler to destroy the joints.

(the joints have nothing to do with the Car-as-entity, they have to do with the Car-as-wheeled-vehicle, and as such, I don't see that the Car entity needs to know or care about them)

Share this post


Link to post
Share on other sites
The best example of an ECS Framework is by the folks who made the Artemis framework (http://gamadu.com/artemis/). They even have a couple of example games that use the framework so you can start seeing how to put things together. T-Machine.org lays-out the concept of an ECS framework fairly well giving tips on what to-do and what not to do and generally how to go about using a ECS framework. I also believe there are some articles out there from the dungeon seige II devs that "pioneered" some of the concepts.

I'm currently converting and modifying aspects of the Artemis framework for c# to suit my own needs and extend capability (like support for more than 32/64 systems / component types) and quicker type mapping (eliminating hash lookups via static type variables)

Share this post


Link to post
Share on other sites
Things are slowly becoming less blurry. Thanks for the Artemis link Net Gnome!

@SwiftCoder

So what you're getting at is having a fully generic entity type, but attach behavior and controller decorators to it? Do you have any sample code that demonstrates this technique (or a reference to a paper describing it?) I'm intrigued.

Here's basically how I understand the system to work:

A base entity is essentially an id. Components for this entity can be created and added to the world (which in turn delegates them to the appropriate component manager). The user can choose to create an actor class which basically holds the entity id and whatever explicit references to the components it needs to function. That actor then implements the game logic. This allows the actor itself to have weak links to its components, so we don't just create components and then let them drift off into the void, nor do we need to resort to a GetComponentOfType(...) function call. We eliminate this because an entity can have multiples of a given component. Additionally, components are coupled as they need (like Hodgeman pointed out).

Furthermore, the factory method itself might spawn several actors, such as a set of wheels for a car, along with the joints connecting them. The vehicle actor will want a reference to the joints, its health, etc. Additionally, the vehicle will connect several transform components to itself that delimit where the joints will connect. The factory function is then responsible for creating the set of entities and coupling them together as they need it. Thus, the vehicle actor knows nothing about the wheels unless it needs to (which it probably would if it wants to apply forces to them, etc), or the joints for that matter.

*sigh* This stuff is hard.

Share this post


Link to post
Share on other sites
So what you're getting at is having a fully generic entity type, but attach behavior and controller decorators to it? Do you have any sample code that demonstrates this technique (or a reference to a paper describing it?) I'm intrigued.


Your code you posted on the previous page was close to what Swift was describing but instead of deriving a class from Entity; you simply leave Entity as the final class. The entity class serves as a means to hold control information about the entity such as a unique ID, possibly a name/tag, and the list of components and behavior that give that entity instance it's unique traits and functionality.

The aim with ECS frameworks is about being data-driven. We can extract the pieces needed to construct a car entity and the instance values used by car entities from code. A lot of games do this by having a file that describes the template used to construct an entity by name/type and then another file that describes instance specific values based on an entity name/type. This "file" could also be a factory class if you want this managed inside your code or even a SQL database when we consider online games, but the goal here is that the data-aspect of an entity is completely isolated

I chose to use XML files for my first pass implementation. I have a template XML file that describes all components needed to create my entities, which provides similar functionality to your Create() method on your Car class. The second XML file is for instance specific values that describe data such as location, min/max velocity of my entity, scale of the model, etc. This way if I want to mass produce 500 entities of a car I could easily do so by having my entity factory load my template of a car entity once and then clone it the number of times needed. Afterward it is a simple setting of instance specific properties.

But at the core, you have 1 entity class that is generic and you allow the data to drive the aspects contained within.

HTH

Share this post


Link to post
Share on other sites

Things are slowly becoming less blurry. Thanks for the Artemis link Net Gnome!

@SwiftCoder

So what you're getting at is having a fully generic entity type, but attach behavior and controller decorators to it? Do you have any sample code that demonstrates this technique (or a reference to a paper describing it?) I'm intrigued.

Here's basically how I understand the system to work:

A base entity is essentially an id. Components for this entity can be created and added to the world (which in turn delegates them to the appropriate component manager). The user can choose to create an actor class which basically holds the entity id and whatever explicit references to the components it needs to function. That actor then implements the game logic. This allows the actor itself to have weak links to its components, so we don't just create components and then let them drift off into the void, nor do we need to resort to a GetComponentOfType(...) function call. We eliminate this because an entity can have multiples of a given component. Additionally, components are coupled as they need (like Hodgeman pointed out).

Furthermore, the factory method itself might spawn several actors, such as a set of wheels for a car, along with the joints connecting them. The vehicle actor will want a reference to the joints, its health, etc. Additionally, the vehicle will connect several transform components to itself that delimit where the joints will connect. The factory function is then responsible for creating the set of entities and coupling them together as they need it. Thus, the vehicle actor knows nothing about the wheels unless it needs to (which it probably would if it wants to apply forces to them, etc), or the joints for that matter.

*sigh* This stuff is hard.


ZBethel,

My dev journal (see my sig) has 4 parts covering my Component Based Entity System for a particular game I had previously created using plan OOP. It's a system where the components have both data and logic, and all information is passed between components and Entities via Events.

It is flawed, no doubt, as it was my 1st attempt at such a system, but maybe it will give you one other avenue to get ideas.

Good Luck

Share this post


Link to post
Share on other sites
The best way i've found to think of ECS Frameworks is to think of them like a database.

Components are Rows in a Table (Component Types), Entities are Primary Keys, and Systems are mechanisms that operate (Create, Read, Update, Delete) on one to many tables (component types) based on their current Primary Key (Entity) of interest.

Treat Entities like a unique ID (literally just an ID container, and nothing more). They shouldnt track anything, let an Entity Management class do that. Entities can literally be as simple as a bit array with their id being their index with true being active and false representing deactivated/unactivated entities. Although i prefer a very lightweight class with just an int for ID (allows me to map to component arrays to quickly establish ownership of a component in the array {it owns the component at the ID's index}). Components should strictly be data containers and nothing more (avoid observer patterns if you can, let a manager take care of that during an update cycle), and let Systems do all the work and communications. These simple concepts will help you do well, and keep things decoupled which will give you TONS of flexibility and allow for easier expansion as you add more features.

Granularity in your components is important. They should describe enough to get the job done, but not more than is required. Don't make them monolithic and dont make them microscopic. This prevents you from having too many specialized systems or too many component retreivals. If you find you use your Velocity component always with a positional component, perhaps you should merge them into a movement or spatial component. Instead of components for each joint in a model, perhaps just have a skeleton component that encompases all the joints required. Don't have a "player" component, just tag an entity as "the player" and build it as you would any other entity.

Finally, when you write your systems, try to keep them as generic as possible. A missile system shouldn't care if its a player or a monster shooting something, only that you have an emission point, a projectile, and a direction. This keeps specialization down and allows you to construct entities alot easier. Systems can be active (execute every update cycle), Passive (execute when called by another system or event), Semi-active (delayed or intermittent), etc. so don't think they all have to behave the same either.

Anyway, hope that helps

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!