Sign in to follow this  
Alex Melbourne

Component programming. I think?

Recommended Posts

EWClay    659
I would like to understand this too. A complete novice could come in and explain how to solve a problem with messages, but we have not yet had a coherent example using flags. So far it sounds like you somehow cache the content of the messages in one of the components, and have every system come along and look at the list later. Not seeing how that's better.

Share this post


Link to post
Share on other sites
Zipster    2359

Sorry for pushing this, but to make my point, we need to go into depth. Suppose the solution with a VisualEffectComponent is used. I suppose this would be a temporary component? That is, it is added for this purpose, and removed when "used"?

It could be a temporary component, yes. The alternative would be to make it permanent and have it store an empty list most of the time, but then the interested systems would waste time iterating over it to only find an empty list. If it's temporary, systems can create and destroy it as they deem it necessary. However either approach technically works.

How would you implement the sound effect? Would you create a "SoundEffectComponent" for that? How would you create the log message in the chat window, would you create a "LogMessage" component for that?

The effect component would contain an abstract description of the sound effect, and the sound effect system would just play it using whatever sound library the engine provides. There is no sound effect component to be created. Likewise there is no need for a log message component, whenever a system needs to log a message it just does so using the logging API, or sending an event that the UI can listen for to display a visual message.

Now back to the other proposal, using a "DamageComponent". I suppose this solution would also be a temporary component, which is removed when used? If so, who would have  the responsibility to remove the component again? How long will the component stay attached on the entity (monster)?

This would be a permanent component, the existence of which also acts as a 'tag' (or 'aspect' if you will) to indicate that its parent entity can take damage, and thus any systems that deal damage for whatever reason should be on the look out for these entities. Removing the component would mean the entity can no longer take damage, which could be a very helpful feature during development.

Please enlighten me, what kind of data will you store in the achievement component to solve the specific achievement problem i listed above? The example I had was an achievement where the player had to hit a number of monsters with arrows in a limited time period. How would you solve this with an achievement component?

Whenever damage is done to an entity (which would mean it has a DamageComponent), the system applying the damage would also log an event, some packet of data, to the AchievementComponent of the attacker, if they have one. In this case only the player entity would have this component. If you log information pertaining to which entity was damaged, at what time, and with what weapon, the achievement system then has all the information it needs to determine whether the player hit a certain number a monsters in some time period. At that point it's just a data-mining problem: query all the damage events that have occurred in the past 10 seconds, with an arrow weapon, and count the number of unique monsters. If it's greater than or equal to 5, award the respective achievement.

Share this post


Link to post
Share on other sites
Zipster    2359

I would like to understand this too. A complete novice could come in and explain how to solve a problem with messages, but we have not yet had a coherent example using flags. So far it sounds like you somehow cache the content of the messages in one of the components, and have every system come along and look at the list later. Not seeing how that's better.

I think I've provided a few coherent examples, but that's just my opinion smile.png You might be missing the forest for the trees and focusing too much on the message-passing aspect of the design (or lack thereof), which is really just a side effect of removing all logic from components so that they no longer can communicate directly. Instead of components responding to messages from other components, systems respond to all changes in component data and make further updates to components as necessary. It's an inversion of responsibility, where instead of individual components trying to wrangle what happens to other entities and components in addition to themselves, entire systems become responsible for these tasks. As long as you adhere to that guiding principle, everything else is pretty much an implementation detail - which components are permanent vs transient, how systems can communicate with each other, how systems know when they need to run, and how often, etc.

Share this post


Link to post
Share on other sites
EWClay    659

Whenever damage is done to an entity (which would mean it has a DamageComponent), the system applying the damage would also log an event, some packet of data, to the AchievementComponent of the attacker, if they have one. In this case only the player entity would have this component. If you log information pertaining to which entity was damaged, at what time, and with what weapon, the achievement system then has all the information it needs to determine whether the player hit a certain number a monsters in some time period. At that point it's just a data-mining problem: query all the damage events that have occurred in the past 10 seconds, with an arrow weapon, and count the number of unique monsters. If it's greater than or equal to 5, award the respective achievement.


If I read that right, every system has to be aware of the achievement component, and has to log everything that ever happens because achievements can be triggered by any weird combination of factors over any time period. And the achievement system has to mine a huge amount of data on a constant basis. Whereas using messages and an observer nothing else needs to know that achievements even exist, and the overhead is minimal.

Share this post


Link to post
Share on other sites
Zipster    2359

Whenever damage is done to an entity (which would mean it has a DamageComponent), the system applying the damage would also log an event, some packet of data, to the AchievementComponent of the attacker, if they have one. In this case only the player entity would have this component. If you log information pertaining to which entity was damaged, at what time, and with what weapon, the achievement system then has all the information it needs to determine whether the player hit a certain number a monsters in some time period. At that point it's just a data-mining problem: query all the damage events that have occurred in the past 10 seconds, with an arrow weapon, and count the number of unique monsters. If it's greater than or equal to 5, award the respective achievement.


If I read that right, every system has to be aware of the achievement component, and has to log everything that ever happens because achievements can be triggered by any weird combination of factors over any time period. And the achievement system has to mine a huge amount of data on a constant basis. Whereas using messages and an observer nothing else needs to know that achievements even exist, and the overhead is minimal.

 

Achievements are always going to be a data mining problem regardless of where that data is stored or how it gets there. You simply replaced logging events to a component with sending a message. In either case, the code needs to know that some event X is "significant" enough to be stored to a component, or in your case warrants a message to be sent. The fact that it's called the "achievement" component is irrelevant; you could instead call it the "stats" components to make its purpose less specific and more reusable (and this is probably what I would call it in a real design), but it would still need to store data required to evaluate achievements. And if a history is required to evaluate a particular achievement, then that cached data isn't suddenly going to go away when the data transfer mechanism changes.

 

Achievement systems always tend to require very specific data to be collected across multiple gameplay systems, and often times that data isn't relevant to anything but achievements. So we can tell ourselves that we're collecting monster damage data for some unknown yet hopefully non-specific, reusable purpose, but in many cases the developer just had to add that data logging to be able to award some achievement somewhere down the road, and otherwise that data is useless smile.png

Share this post


Link to post
Share on other sites
Zipster    2359

Also, just to be clear, I'm not advocating the complete removal of events or messages from the design. All I'm saying is that the components themselves should neither send nor receive these messages. The systems, however, are free to communicate among themselves. As a matter of a fact, signaling would probably be the most efficient way to handle the achievement system, since it only needs to run occasionally. Whenever another system modifies component state that could affect achievement status, it sends a signal to the achievement system to wake it up. The achievement system runs once, awarding any achievements it detects, then goes back to sleep until it receives another "reevaluate" signal.

Share this post


Link to post
Share on other sites
larspensjo    1561

All I'm saying is that the components themselves should neither send nor receive these messages. The systems, however, are free to communicate among themselves.

 

Ah, then I agree completely. It may be we argued around a misunderstanding.

Share this post


Link to post
Share on other sites
EWClay    659

As a matter of a fact, signaling would probably be the most efficient way to handle the achievement system, since it only needs to run occasionally.


Well, that was my point. Agreed then.

Where the logic lives isn't a great concern to me; as long as the most suitable algorithms can be allowed to work.

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