• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
jaeg

Basic Component Based Entity

68 posts in this topic

[quote][color=#1C2837][size=2]Communication for me has probably been one of the hardest aspects of using this pattern. I am still by no means comfortable with my current approach but its a crude, elementary, but working solution that I look at being something I can tune and refine at a later point. [/size][/color][/quote]

This tends to be my problem too. I'm not yet comfortable with my own design skills which is why I created this topic in the first place. I am feeling more comfortable with my current system now than I was before with the help of the people here. Now if my design is actually practical is totally another story. I'll find out soon after I get my entityFactory finished and parsing the levels I've already made.
0

Share this post


Link to post
Share on other sites
[quote name='jaeg' timestamp='1321032984' post='4882988']
[quote][color="#1C2837"][size="2"]Communication for me has probably been one of the hardest aspects of using this pattern. I am still by no means comfortable with my current approach but its a crude, elementary, but working solution that I look at being something I can tune and refine at a later point. [/size][/color][/quote]

This tends to be my problem too. I'm not yet comfortable with my own design skills which is why I created this topic in the first place. I am feeling more comfortable with my current system now than I was before with the help of the people here. Now if my design is actually practical is totally another story. I'll find out soon after I get my entityFactory finished and parsing the levels I've already made.
[/quote]

My first pass at my CBES project was using singletons. I knew that wasn't the route I wanted to go long-term, but it made coding much easier and I didn't have to worry about dealing with inter-communication as much. Basically the update() loops on my subsystems would use the singletons to get the components for my entity if they existed, worked a certain way if those components existed, and other ways if they didn't. Was that practical; nope :).

Several iterations ago I decided to rewrite my code and I decided to take a radically different approach to communication. Instead of using singletons and exposing portions of each system to another, I introduced an event mediator class. This class handles all inter-communication between subsystems in the entire framework. Any subsystem can register callback handlers based on specific events they are interested in. Events that are dispatched to the mediator can either be:

1. Queued for delayed delivery either at the next frame or some future time
2. Immediately

The first scenario is more aligned with a typical message loop described in windows or any double dispatch type event handler. I use this mechanic when a situation is reached in code during the current frame where I should impact another subsystem on the next frame. This is for non-critical events along with where I am not interested in getting any form of a response. It's your send it and forget type of trigger.

The second scenario is more like your typical boost signals or libsig++ mechanic where an event/signal is raised and those interested are immediately notified. The benefit of this approach would be where a subsystem reaches a state where it needs to know something immediately. The nature of my event class allows me to dispatch the event and the callback(s) all can modify the event object. When the callback finishes, the subsystem that made the call gets control again and can examine the event object and based on the data collected, proceed accordingly. This has been useful where say my physics engine needs a piece of data from my render engine and some information from my transform component. Rather than dispatching two events, I can create a single event, both subsystems are dispatched in sequence, they add their data to the event object and voila. :)

Again, is my approach ideal, probably not. But it's an interesting concept and likely not something used mainstream, unless someone here comments and tells me otherwise :P.

EDIT: I should also add that my mediator does not use an interface callback handler but instead allows the registering class to provide a class member function as the callback. The mediator essentially invokes those methods with the event object under both scenarios. This avoids the need for virtual methods and allows me to specify specific methods for specific conditions without needing to use switch statements or other conditionals.

Examples:

void OnEntityAddedToScene(CEvent* pEvent); // Render system dispatches this when node is added to scene
void OnMeshLoaded(CEvent* pEvent); // Dispatched by the mesh system when a mesh is loaded and added to a scene node
void OnTransformUpdate(CEvent* pEvent); // Dispatched by my transform system when an entity's position is changed
0

Share this post


Link to post
Share on other sites
As I continue to add subsystems and components to my design, I feel there are problems with my approach that is leading to portions of code that should be simple and short appearing to be more bloated/boilerplate coding than I would have expected or even where I suspect separation of concerns is breached. I've decided to hold off on adding any more subsystems and components until I can address the design issues and I hope others can help.

Entities are first created by the entity manager being given a template definition. The template defines the necessary components to create that entity along with the properties to initialize each component of that entity. The entity system looks up the components from the definition in the component factory, gets the pointer to the create method that the component subsystem registered with the factory and invokes that method. The entity id along with the XML definition for that specific component are passed to the create method function pointer so that the subsystem can instantiate the component, initialize it, and add that component to its internal entity<->component map. Once an entity has been created, none of the components know anything about one another. The only thing that is known are the dependencies that a specific component type has for another component and the functionality/attributes that component provides for that entity's instance. For example, our render and physics components wants to know initial position/orientation along with the physics having interest in the rendered mesh's bounding box size and any scale modifiers while my animation system is interested in mesh information so that animation states can be extracted and used.

Each of my subsystems manage two or more lists of components which are based upon the component's state. When components are created by a subsystem, they are added to the active and update lists. My thought was that rather than having the update() method loop over all components in a particular subsystem, I could reduce that cost by only iterating over components which were modified. First, is this good or bad? Secondly, about the initial "wiring up" among components, I don't like the idea of having checks in my update() method to handle lazy-initialization, but maybe this is the norm ??

My current scenario is:
[list][*]Iterate over the updated transforms and create a transform update event. This event when dispatched invokes methods on the render/physics systems to update their components.[*]Iterate over the updated meshes and create a mesh update event. This event when dispatched invokes methods on the physics/animation systems to update their components.[*]Iterate over the updated physics and create the physics component's rigid bodies and add them to the simulation. Then step the simulation.[*]If a collision was detected, a physics update event is fired and the transform system updates components accordingly, marking components as 'updated'[*]Iterate ALL animations and transition states and/or step animation phases.[*]Iterate over the updated renders and create the scene nodes if one does not exist else update scene node's position.[/list]
The very first thing that bothers me is how I handle this transform component. I opted to have the transform do a broadcast to the entity with the position/orientation to aid in the setup of any component that may require that information. This allowed for when the position/orientation changed from another component, every component of that entity gets updated on the next game loop. When the player has force applied and physics changes the position, the physics subsystem sends an event that the transform subsystem intercepts, modifies the position and then re-broadcasts the updates to everyone. But this seems a bit redundant on the event system to a degree, but it does allow updates to the position to happen in 1 place and then replicated by the component subsystem to those interested in the changes. Is this the typical approach?

Do others have any suggestions of variant ways to approach this? If code snippets would help, I can certainly provide.
0

Share this post


Link to post
Share on other sites
Is it ok not to have my components inheriting from a component base class? All of my systems deal with their own component type so the never use the base class and it's causing me issues like overloading the init function. Not all of the components need a CSpatial but it seems I have to overload it in the base class first then give each component derived off of it the function just to please my compiler.
0

Share this post


Link to post
Share on other sites
[quote name='jaeg' timestamp='1321369247' post='4884179']
Is it ok not to have my components inheriting from a component base class? All of my systems deal with their own component type so the never use the base class and it's causing me issues like overloading the init function. Not all of the components need a CSpatial but it seems I have to overload it in the base class first then give each component derived off of it the function just to please my compiler.
[/quote]

I would suggest they all derive from some base class yes. There are a number of approaches you can take to solve this problem. My suggestion would be to consider having two derived classes from your base component class where one takes the spatial and the other does not. This will give you two types of classes to then base all your components from or you could always base some from the original parent base class if you saw the need. Remember, inheritance isn't bad if used properly :P.

But my approach to initialization was slightly different. My approach is to keep all my behavioral logic in my subsystems and treat my components mainly as data handlers. In my approach, I don't create the components directly but my subsystem does by being provided an entity reference and a list of initialization parameters. The subsystem in turn pulls creates a new component, passing the entity id and component id into the constructor. This will probably turn into a common "init" method soon when I add object pooling to my subsystems. Then the subsystem inspects the initialization parameters and calls the appropriate set methods accordingly. If parameters aren't provided and set during this call, they accept the default values dictated by the subsystem or the component's constructor.

All components typically hold a reference to their entity (whether it be a pointer or the id) and some form of a type identifier (in my case a component id). Rather than duplicate this functionality in all components, place it in a super base class and then reuse it in your hierarchy :P.

EDIT: My rule of thumb is if I have to write something more than once, it gets factored out. If I have conflicts between two objects, common stuff factors out to a base class and I derived two children from that parent :).
0

Share this post


Link to post
Share on other sites
I ended up having to cheat a little when it came to my animation. I ended up tucking my start and end frames into my spatial object and having the render object read it. That way the AI/Behavior components can change them when needed. I'll keep this way until I get my message system capable of sending the data itself. Or is it ok to keep it like it is?
0

Share this post


Link to post
Share on other sites
I would definitely remove it because a lot of things have a position/orientation/scale in 3D space but have nothing to do with animation (based on separation of concerns).

Additionally, I do more than just set an animation into motion based on game actions. For example, when my avatar strafes left or right, I actually work with the mesh's bone structure to rotate the head of the character in the direction i am strafing. If the character is strafing while moving forward, I rotate the bottom of the body to face the angled direction while keeping the head facing forward. When the avatar is idle, it periodically switches between 3 variants of idle animation to give the illusion that the character is "real". Also, the "jump" animation is split out into various animations depending upon whether the character jumps from the ground up and back down or jumps off a ledge and free falls to the ground a far distance. So as you see, animation for me is complex and that doesn't even scratch the surface of animations when it comes to in-combat actions, various other game actions like working with trade skills, etc. I simply have the animation system tied into listening for "movement" events and other game action "events" and it fires the appropriate animations based on those. Once you have your event framework up and running, you'll see how easy it is to move that out into it's own little world and that it just sits there and compliments the other systems without them even knowing what it is doing :P.
0

Share this post


Link to post
Share on other sites
Right now I think I have insufficient communication abilities between my components/systems. I need to rethink my messaging system. Especially when it comes to data sending in events. Void pointers to specific data objects does not cut it. Do you do your animation in an animation component or the render component? Also since as you said animations are more complex for you especially your player entity do you have multiple rendering/animation component types?
0

Share this post


Link to post
Share on other sites
[quote name='jaeg' timestamp='1321501043' post='4884843']
Right now I think I have insufficient communication abilities between my components/systems. I need to rethink my messaging system. Especially when it comes to data sending in events. Void pointers to specific data objects does not cut it. Do you do your animation in an animation component or the render component? Also since as you said animations are more complex for you especially your player entity do you have multiple rendering/animation component types?
[/quote]

I chose to use a very crude approach in the beginning for messaging because I wanted to not worry too much about how they would communicate but be able to bring together a number of core components and work on the inner workings of their component functionality without being bothered. Void pointers to a defined structure would be fine assuming that you are using some form of a callback functor so that when the function call is invoked by the event framework, you know exactly what to recast that void pointer to with a static cast.


When it comes to the animation system, it exposes a great deal of features via events. So when writing the logic for moving forward in the movement component, it applies a force based on the game's movement speed and time and signals physics. Additionally, the component notifies the animation state to begin playing the walk forward animation. In the case of strafing, I have a special event that allows me to rotate the skeletal structures so I can keep my head forward but adjust the body on direction of movement. What I aim for is that the core component/systems such as animation should not be tied at all to my game but provide functionality that I can leverage while making a game. That allows it to be highly reused.

Another way to handle it would be to create a game specific animation system that listens for game-specific events and then internally works with the core engine's animation system. This way the game itself mirrors that of your engine and allows your engine to be reused in multiple games but allowing you to model your game code similarly and abstract the entire engine's systems into your own :). I have found this helpful in a few places where the engine was so modular that rather than remembering when case A needs to trigger 3 events in the engine, I simply send 1 event in my game code and a game code system receives that and dispatches those 3 events. This probably isn't the "fastest" way but keeps me from duplicating lots of code in various places :).
0

Share this post


Link to post
Share on other sites
So you seem to have kind of a game view system going on then don't you?

So if I'm understanding right your animation system isn't in a component then? For my purposes I'm thinking of making it a component that just listens to events from it's ID.

I'm thinking of changing my event system to use more type specific events inheriting from a base event.
Currently my events look like this:
[code] struct Event
{
EventType type;
EventCategory category;
void* data;
};[/code]


type and category are large enum lists. When an event is called the dispatcher sends it to the handlers registered to receive specific categories. I'm thinking of changing it so I can get rid of *data and just make more detailed events. Since the handler will know what it is based on the category and type it'll know what to cast it as to get the data from it.

Also I'm thinking I'm not using it as much as I should. Right now it's just used to give the stateManager feedback on the states it controls like if in the menu a button that should make it switch states is pressed. Or in my CGame class (the engine class that controls if the game is running, sets up application stuff, ect) it uses Irrlicht's eventReciever to get keyboard inputs and broadcasts that. I hadn't thought about have entities use it to send that it moved or not.

Also what is a good way to manage the event objects produced? They aren't pointers I make them like this:
[code]
Event event;
event.type=E_CREDITSSTATE;
event.category=E_GAME;
CEventDispatcher::inst()->sendEvent(event);
[/code]


That sends to the stateManager (who is registered to listen to game events) an event from the menu state to switch to the credit state. Do I need to delete the event after it gets used or will it go out of scope and disappear itself?

The CEventDispatcher calls all of the IEventHandlers->handleEvent(e) functions in the registration list for that particular category. It's up to the handlers to decide if they ignore the event or not.
0

Share this post


Link to post
Share on other sites
[quote name='jaeg' timestamp='1321542306' post='4884979']
So you seem to have kind of a game view system going on then don't you?
So if I'm understanding right your animation system isn't in a component then? For my purposes I'm thinking of making it a component that just listens to events from it's ID.
[/quote]

I can't say whether my design is solid or not yet, but I like the approach at least. I began under the premise that my components are nothing more than data bags, glorified structures called classes that hold state information for a particular component. They hold pointers to allocated resources, etc but there isn't any logic within them at all. All the logic and behavior has been offloaded into a system class that oversees all components of a particular class. In the component's world, all it has is an entity id (a number) but it has no idea what it means, just it needs to hold onto it. The component system doesn't know anything about the outside world except for the event dispatcher. It works under the premise that I send events and either I get an answer or I don't (in the case of callbacks) or I send events and forget it and move to the next task. Beyond that, a component system and its components work in their own little area of space without a care of what else is happening in the system.

In my system, when events are fired, they have an event id and most events typically have an entity id property or a target/source entity id when we talk about cross-entity interaction. The component systems register with the dispatcher upon start-up and specify what event types they are interested in as well as registering their respective callback handler methods for each event type. When an event is dispatched by the dispatcher, that particular function pointer is invoked in the subsystem. That subsystem statically casts the event object to the appropriate type and then performs the necessary logic that method was designed to do; namely look-up an entity by id and change properties, set dirty flag for state changes so it gets picked up on next game loop, then ends. In short, the components are never accessed externally, only via proxy through events and the component system that knows how to handle those events.

[quote name='jaeg' timestamp='1321542306' post='4884979']
Also what is a good way to manage the event objects produced? They aren't pointers I make them like this:
[code]
Event event;
event.type=E_CREDITSSTATE;
event.category=E_GAME;
CEventDispatcher::inst()->sendEvent(event);
[/code]

That sends to the stateManager (who is registered to listen to game events) an event from the menu state to switch to the credit state. Do I need to delete the event after it gets used or will it go out of scope and disappear itself?

The CEventDispatcher calls all of the IEventHandlers->handleEvent(e) functions in the registration list for that particular category. It's up to the handlers to decide if they ignore the event or not.
[/quote]

Before I get to the event deletion question, the common event dispatch handler method approach above, I personally dislike. It is an easy design pattern none the less and will work, but it typically leads to gigantic switch statements based on some data element that determines how to cast the common event object to a particular type. As I said, it works but not an approach I prefer to support because those methods can get lengthy when you have classes that listen to many events. I tend to use function pointer callbacks instead giving me the flexibility to to know when the function pointer is called that I need to take that base class pointer that I got and statically cast it to event type ABC. It avoids the switch statement concept and (although i haven't ran benchmarks personally), I think the virtual callback is a little less performing than a direct function pointer call. I would certainly consider looking into function pointers for a future pass, but YMMV.

Now for the deleting of events, it depends upon your design; whether your event is immediately dispatched or whether it is queued for dispatch at the next game loop or a future game loop. I use two different methods in my engine to distinguish between events that are to be QUEUED vs SENT/NOTIFY.

The notify() method in my case simply takes the event reference, looks up a function pointer and passes the reference to the function. The function can modify the event parameters as it sees fit and return. The next line in the code that called notify() can inspect the event and maybe get some information that was added by the prior callback; think of it as a glorified callback with return data :P.

When I invoke the queue() method, I pass the event information the same way as I do to the notify() method; however, the dispatcher makes a copy of the event and stores the copy. The dispatcher does not care whether what I pass is a heap allocated object or a stack allocated object because internally the queue() method always makes a copy and places it's own allocated object into its internal list for dispatch on the next game loop. This way if I passed a pointer into the dispatcher, that pointer is still my responsibility to delete and manage, not the dispatcher. When the dispatcher finally sends that queued event in the future, that allocated object is what the dispatcher is responsible for deleting when it is no longer needed. There are probably other ways to do this that are better, maybe using some form of smart pointers where once the reference reaches 0; it gets deleted automatically, but I'm not at that optimization stage. The point though is who ever creates a pointer should be the one who deletes the pointer. One of the hardest things to manage is who OWNS a pointer :P.
0

Share this post


Link to post
Share on other sites
So if I'm reading right your actual system is updating the information based on the component data rather than having your component have an update function and it does it's task?

So for example a collision system just pulls the data from the current component it's looking at and updates the data based on that itself? I can see that working for some of the components but what about a more complex component like AI? In my system I have two AI like components. AI and Behavior. Behvavior runs a simple script while AI deals with more complicated inputs and outputs.



EDIT:

I found an article that I think is explaining what you are talking about correct?
[url="http://www.tomseysdavies.com/2011/01/23/entity-systems/"]Entity Systems[/url]

The point your making is about halfway down the page under "Almost"
0

Share this post


Link to post
Share on other sites
[quote name='jaeg' timestamp='1321546042' post='4884998']
So if I'm reading right your actual system is updating the information based on the component data rather than having your component have an update function and it does it's task?

So for example a collision system just pulls the data from the current component it's looking at and updates the data based on that itself? I can see that working for some of the components but what about a more complex component like AI? In my system I have two AI like components. AI and Behavior. Behvavior runs a simple script while AI deals with more complicated inputs and outputs.

[/quote]

That is correct, the update is at the system level, not at the component level. If you think about it at a higher level, when you iterate over your entities and call the component's respective update() method, you're invoking behavior based on that component's existing state. Inevitability, it is no different except we've factored the logic out of the component itself ad into a subsystem that is responsible not only for the logic behind the component it manages, but also the life cycle of that component by creating and destroying it as requested and communicating with the outside world or in my case the event dispatcher.

For things like AI and behavioral things like scripts, there is nothing that says that the component system's update loop can not iterate over the components and call a method such as update on each component too :P. The prime reason for these component systems and isolating logic in the system was to provide uniformity among components, keeping core code in single places and treating the components themselves as data. There will always be exceptions as you point out with behavioral scripts for sure.

When it comes to AI however, I tend to think that AI can be broken out into various components and systems such as:

- Randomly greet a player that walks by
- Pick a random phrase and yell on a specified interval or based upon an event trigger (similar to above)
- Path navigation (pick the next point on a path and walk to that point)
- Threat / Aggressive (if an entity that is an enemy is within X distance of the current entity, latch on to first one and be aggressive)

These are very common AI features that most AI entities will inherit. They may not inherit all of them, but there will be a core set of functionality that will be shared by a vast many and by separating it out like that, I can easily add it or take it away at will and the subsystem that runs an update() simply takes the current component, checks it's state and then applies whatever algorithm the system is designed to execute (navigate to next path after X seconds - pathing). The more complex things like handling what happens in an encounter with attacks, etc could all be driven by a script component that has an internal state machine or behavior tree attached that dictate fight mechanics.

This is my 100000 ft view on where I plan to head, but not sure whether that is right :P. I'm still working on basics :).
0

Share this post


Link to post
Share on other sites
[quote][color=#1C2837][size=2]This is my 100000 ft view on where I plan to head, but not sure whether that is right [/size][/color]:P[color=#1C2837][size=2][left]. I'm still working on basics [/left][/size][/color]:)[color=#1C2837][size=2][left]. [/left][/size][/color][/quote]

Same here. As I work on it I find that certain things don't work (problem I'm having right now) and that certain things do. Also that certain things work better with others. Coding isn't hard it's designing it first. The nice thing though is that I have it set up in a way that I could complete remove the entity system without having to rewrite other parts (stateManager, game) since they are independent of each other. I know that isn't impressive but it's a first for me to design things modularly like this. lol

I need to sit down list what I need in the game how things need to work based on the players view and from there figure out how it needs to work behind the scenes. I also think I'm going to drop CopperCube/irrEdit and make my own editor so that I can decide what components are applied to what and have it generate the .init files for me. But first things first I need to figure out what components I need.

Like for example:
A playable entity needs a component for: Spatial, Render, Animation, Collision, Controllable, Equiping.
A weapon would need: Spatial, Render, Animation, Behavior, and Equipable.
AI NPC (Zombie): Spatial, Render, Animation, Collision, Sight, Hearing, AI Logic.

And if I'm thinking right it should be created and updated in the order I listed the components.

Now for the components Equiping and Equipable:
My thinking is that since every weapon has it's own behavior and other attributes making it able to attach and receive input via a entity with an Equiping component which receives controlling events will let me be able to use it easier.
0

Share this post


Link to post
Share on other sites
[quote name='jaeg' timestamp='1321550897' post='4885021']As I work on it I find that certain things don't work (problem I'm having right now) and that certain things do. Also that certain things work better with others. Coding isn't hard it's designing it first. The nice thing though is that I have it set up in a way that I could complete remove the entity system without having to rewrite other parts (stateManager, game) since they are independent of each other. I know that isn't impressive but it's a first for me to design things modularly like this. lol[/quote]

That's the beauty of using the dispatcher concept right now. If I find I want to try something new, I can easily plug in a new component & system to replace the old one so long as it registers and listens/sends the same events as the other one did then everyone stays in harmony :P.

[quote name='jaeg' timestamp='1321550897' post='4885021']
Like for example:
A playable entity needs a component for: Spatial, Render, Animation, Collision, Controllable, Equiping.
A weapon would need: Spatial, Render, Animation, Behavior, and Equipable.
AI NPC (Zombie): Spatial, Render, Animation, Collision, Sight, Hearing, AI Logic.

And if I'm thinking right it should be created and updated in the order I listed the components.[/quote]

This is one area that I still continue to struggle with because for one I don't want to limit the editor or the designer for that matter to make sure that component A is added before component B. If I need to impose those rules, somehow I have to build a rules system into the plan to control making sure that when components C, A, and B are added to an entity, that before the editor window is updated, the components are re-arranged to A, B, and C in the editor tree so that they are then instantiated in the proper order for rendering. Unfortunately, I don't know if this is how other games are designed so that the game itself does not need to care about the load order as the tools handle that offline. And while a rules system can be imposed, then what happens when your game dynamically adds/removes components from an entity. If the code adds them out of order, then I may get weird results. I'd rather (personally) not have order requirements, but I can see why it helps to have it because now I don't have to necessarily test for that case in the game loop itself. How have others tackled this?

[quote name='jaeg' timestamp='1321550897' post='4885021']
Now for the components Equiping and Equipable:
My thinking is that since every weapon has it's own behavior and other attributes making it able to attach and receive input via a entity with an Equiping component which receives controlling events will let me be able to use it easier.
[/quote]

That sounds about right - at least in my mind too. The way I would see that playing out is that the player selects an ability on their bar. The event is dispatched and the attack subsystem receives the event, determines that the spell used is fire the gun. The attack subsystem dispatches a fire ranged weapon which the weapon subsystem receives. The weapon subsystem inspects what ranged weapon is associated to the entity at that point in time, checks the tag associated with the component as to whether it is a wand, gun, etc. In our case it is a gun, so an event dispatches to play a gun sound and a particle emitter event is dispatched to show bullets leaving the end of the gun.

Thinking about this; it sounds overly complex, so I'm open to input :P.
0

Share this post


Link to post
Share on other sites
I'll probably make two tools. An entity generator and the level editor.In my system the blueprints for entities are stored in .init files that are parsed by the entityFactory creating the components in the correct order. So before actually constructing a level in an editor I would go through and create the entities I.E. enemy types, pick-ups, weapons, and other dynamic stuff. After I have designed them for their purpose the generator goes through and using it's set of rules makes sure the components are listed in the correct order. Note that the generator does not need to use the components so it doesn't have to have them added to it in the correct order either. (I hope that made sense)

The level editor on startup will look through the "scripts/Init" folder find the entities available to it and allow you to place them in the level.

As of right now I don't need to come up with new entity types on the fly I just plan to use the ones I have planned out ahead of time. It keeps things simple for now.


I've been going through and writing notes and drawing diagrams using the systems as the updater and the components as data-bags and I'm seeing why you do it. It's easier to communicate data between components via the systems. Same with system to system.


To me it seems like multiple systems with dependencies on each other should be considered as units especially ones that function together to form AI. So those components need to be made together anyway so the dependency shouldn't really be too worried about. Now using AI as an example again since not all entities need to hear or see rules can be made to exclude those from the system that stores the action queue or makes decisions based on those two's input.
0

Share this post


Link to post
Share on other sites
[quote name='jaeg' timestamp='1321562303' post='4885095']
I'll probably make two tools. An entity generator and the level editor.In my system the blueprints for entities are stored in .init files that are parsed by the entityFactory creating the components in the correct order. So before actually constructing a level in an editor I would go through and create the entities I.E. enemy types, pick-ups, weapons, and other dynamic stuff. After I have designed them for their purpose the generator goes through and using it's set of rules makes sure the components are listed in the correct order. Note that the generator does not need to use the components so it doesn't have to have them added to it in the correct order either. (I hope that made sense)

The level editor on startup will look through the "scripts/Init" folder find the entities available to it and allow you to place them in the level.
As of right now I don't need to come up with new entity types on the fly I just plan to use the ones I have planned out ahead of time. It keeps things simple for now.[/quote]

It does make sense from the perspective of keeping things simple, but I decided to take a different stance when I started. With the editor in mind, I will be able to construct my terrain, shape it as I wish. Additionally, the editor will allow me to place an entity (broad-term) anywhere on the scene. The entity being placed can be selected in two ways 1) pre-fabricated or 2) dynamically. The user will be able to create a monster by simply selecting and dragging components to the entity container, setting values and moving the entity in the scene where they want it to be placed. They'll be able to script in behavior or add AI elements by specifying path points, etc; all because of the components that a selected entity has. The users can create a silly entity and if they like what they have, they can easily with a simple click copy an entity to a pre-fabricated template. Later when they move on to another area, they can grab that entity from the pre-frabricated list instead and simply tweak parameters as they need. It's a big project no doubt, but that's the goal and with that in mind, I am of the opinion that entity components are somewhat dynamic. It certainly adds a bigger element of complexity :(.

[quote name='jaeg' timestamp='1321562303' post='4885095']
I've been going through and writing notes and drawing diagrams using the systems as the updater and the components as data-bags and I'm seeing why you do it. It's easier to communicate data between components via the systems. Same with system to system.[/quote]

One current debate I have with all this is where to draw the line, particularly where it surrounds the render engine's components, such as lights, meshes, planes, and movable text, etc. Most of these objects require access to the scene manager for their respective render engine equivalent to be created. One way I considered is that all these "specialized subsystems" are child component systems of the render system. So when the render engine starts, there are about 10 different subsystems that start up with it. These subsystems handle various render-component types. Another alternative is that I have 1 system that manages all these components in various lists. The downside here though is I end up with a laundry list of logic methods in this one system for various component types; albeit they all depend heavily on the OGRE render engine to work. I just can't seem to put my finger on a good design for these types of components.

[quote name='jaeg' timestamp='1321562303' post='4885095']
To me it seems like multiple systems with dependencies on each other should be considered as units especially ones that function together to form AI. So those components need to be made together anyway so the dependency shouldn't really be too worried about. Now using AI as an example again since not all entities need to hear or see rules can be made to exclude those from the system that stores the action queue or makes decisions based on those two's input.
[/quote]


When you say units, are you implying that you have like a master AI system and then child AI subsystems? Then those child AI systems can request from the parent AI subsystem pointers to the various AI child systems to communicate back and forth and work with other various AI components without using the event dispatcher? As for your comment about see/hear rules, I don't follow.
0

Share this post


Link to post
Share on other sites
[quote][color="#1C2837"][size="2"]When you say units, are you implying that you have like a master AI system and then child AI subsystems? Then those child AI systems can request from the parent AI subsystem pointers to the various AI child systems to communicate back and forth and work with other various AI components without using the event dispatcher? As for your comment about see/hear rules, I don't follow.[/size][/color][color="#1C2837"] [/color][/quote]
I'm thinking my AI system is more complicated than yours. Rather than just one part running scripts there are other systems for things like sensory input. These systems watch for things like sounds to play or check via rays if the entity can see another entity. These will notify the decision making system which looks at the data and decides what to do. Using this I can effectively turn off a monster's ability to hear and it would function as if it never had it. Some with vision. I could turn off it's ability to receive a list of objects it can see making it have to solely by hearing find a target.

The ai has a set of targets kept in a list and when it gets it's vision feedback it'll compare those objects to the target objects and then take the right actions to try to kill the player.

So in short all of these systems make up the AI system as a unit. If one system doesn't exist the unit needs rules to make sure it can still operate.

Best example of what I'm doing:
[url="http://www.valvesoftware.com/publications/2009/ai_systems_of_l4d_mike_booth.pdf"]Left 4 dead AI[/url]


[quote][color="#1C2837"][size="2"]It does make sense from the perspective of keeping things simple, but I decided to take a different stance when I started. With the editor in mind, I will be able to construct my terrain, shape it as I wish. Additionally, the editor will allow me to place an entity (broad-term) anywhere on the scene. The entity being placed can be selected in two ways 1) pre-fabricated or 2) dynamically. The user will be able to create a monster by simply selecting and dragging components to the entity container, setting values and moving the entity in the scene where they want it to be placed. They'll be able to script in behavior or add AI elements by specifying path points, etc; all because of the components that a selected entity has. The users can create a silly entity and if they like what they have, they can easily with a simple click copy an entity to a pre-fabricated template. Later when they move on to another area, they can grab that entity from the pre-frabricated list instead and simply tweak parameters as they need. It's a big project no doubt, but that's the goal and with that in mind, I am of the opinion that entity components are somewhat dynamic. It certainly adds a bigger element of complexity [/size][/color]:([color="#1C2837"][size="2"][left].[/left][/size][/color][/quote]

This is where considering certain parts as units would come in handy. If you give them the option of choosing what input the ai should receive so when the decision making part of the AI unit does it's thing it'll look to see if it has the ability to hear or see.

[quote][color="#1C2837"][size="2"]One current debate I have with all this is where to draw the line, particularly where it surrounds the render engine's components, such as lights, meshes, planes, and movable text, etc. Most of these objects require access to the scene manager for their respective render engine equivalent to be created. One way I considered is that all these "specialized subsystems" are child component systems of the render system. So when the render engine starts, there are about 10 different subsystems that start up with it. These subsystems handle various render-component types. Another alternative is that I have 1 system that manages all these components in various lists. The downside here though is I end up with a laundry list of logic methods in this one system for various component types; albeit they all depend heavily on the OGRE render engine to work. I just can't seem to put my finger on a good design for these types of components.[/size][/color][color="#1C2837"] [/color][/quote]

I'm not sure about OGRE but in Irrlicht things like text is handled by the GUIEnvironment. So maybe have that as either a separate system.

A light that can change it's state should be an entity and in Irrlicht I think is still considered a scene node so the renderComponent which stores said node can still hold a reference to it.
0

Share this post


Link to post
Share on other sites
I have come across a situation where I need to be able to control multiple entities as though they're a single cohesive unit. For example, if entity A moves forward by 5 units, then entity B should do the same despite the fact they're both different entities.

A lot of examples I have encountered tend to have events dispatched to the entity class which in turn iterates it's components and notifies each component of the incoming event. For one case, the programmer implemented a "link component" that allowed them to add the child entity ids for the followers and then added the link to the parent. As events were dispatched to the parent, the entity event handler invoked each component's event handler. The link component changed the destination entity id on the message and then dispatched it again for immediate delivery, effectively relaying the event to another entity with ease.

In my case, I am using the outboard component system approach. For those unfamiliar, there is no concept of an entity class, just the entity manager knows that a particular guid has been allocated but it is oblivious to the components that the guid has too. All component information is held within the particular component systems themselves for the guid. Additionally, each component system registers to have specific events fired to callback methods. So for example, PlaySoundEvent is fired and only the sound system cares about this and the method OnPlaySound(CEventPtr evt) is what gets invoked automatically. The component system extracts the entity guid from the event, looks up the component and performs whatever logic is needed.

Operating under the outboard scenario, there really isn't a way to handle this "link component" behavior, at least not in an obvious fashion as how the above programmer did. How have others handled this situation? I could reintroduce an entity class but I'd rather see if there is an alternative option that I am missing.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0