Entity hierarchies with embedded Events : init and design problems

After several tests, it seems that it’s impossible to get back the hierarchy of parent/children in script canvas with the available Nodes like Get Descendants, Get Children … is it a bug or maybe must be sure to have initialize in a good way before to get all children “présents à l’appel” :checkered_flag:?

For info, it is by asking the question that we sometimes find an answer :wink: … if can that help you, in this case here if instead of starting the script by On Graph or other … it’s with an On Tick that it works well.

I don’t have any problem with getting children. You have to use a “for each” to loop through all the children if you want to do anything with each one. By the way, the ordering of the entities is not maintained. That’s because it would cost too much for too little gain to doing sorting all the time, if I recall correctly.

@wcb this problem occurs when you have several existing hierarchies of parent/child … in most case effectively it will not appear. I suppose too that if we are able to verify that all the hierarchy is well loaded in all the case at the time you want to read it it’s ok, but it could be preferable that the Node verifies that by itself :wink: or return a kind of “must wait” output …

I haven’t worked with entity hierarchies that deep so I’m not sure about that. I am not sure if get children nodes actually do a recursive walk of the hierarchy or not. If not then you’ll have to implement it yourself in a for each loop.

For info I get the total hierarchy as expected, but as discussed under some init conditions that must be followed before we can expect to get the whole hierearchy in a reliable way.

If it works on tick but not on graph it’s because the entities probably haven’t been activated yet in the tree if you do it “on graph.” You should get children on an entity when that entity is activated I would think.

On Graph Start, Game Entity was tested without the success … Tick was perfect but then must be desactivated which is not very top. If you have another idea to do it ?

A way is to call the hierarchy after a call to “Game Entity” with as source the deepest child of the tree so we are sure that the init is well done before we make a call to “get children” or “get descendants” …

But the simplest and reliable way for me seems like thereafter

What about “on game entity activated”?

yes with a call to “Game Entity- on game entity activated” it’s ok if you choose a deep leaf of your tree as the Source … but it stills problems with the others branch … so a little bit boring if we need to do it for all branch to be sure …

Another improved proposal :wink:

But in fact the problem is elsewhere as well as its solution :face_with_monocle:

I made an init in the script of the Parent entity and every time one of his children is activated, it also activates again the script of the parent entity.

Thus as it’s the case now for me, it’s good to remember that now ! :wink:

The use of image is recomended too here as the On Graph Start and the On Entity Activated events are subject to activation order issues and it’s sometimes the case here too.

Hello @Didier!

The solutions you offered are often used when these situations happen, the event driven nature of Lumberyard sometimes introduces some patterns that don’t feel intuitive. This is because entities rely on their components to provide their functionality and the way entities communicate with each other is through event messages (through the EBus system).

This means that in order for an Entity to be able to handle function calls on its components it needs to be activated. During the activation step entities connect internally to the different component event buses, these are the functions called by scripts.

I recommend that you add a variable for the target entity you wish to get descendants from, then add an On Entity Activated handler for which you specify your new variable as the Source. When you handle the On Entity Activated event you should be able to call Get Descendants and receive them as the entity will be guaranteed to be active and able to respond to your requests.

Thank you,

LS

4 Likes

Hello @LS1 thanks for the help and I’d like to take this opportunity to tell you :+1: about your great LY dev.! The more I discover it, the more I find it very well thought out and user friendly.

I’m just now going to find out more about performance and as the design choice with Events is likely to be a determining factor in these performance evaluations, I’ll have a question that follows with Events and script design.

In the same problem area, when you have a large number of Entities sending Events that are themselves red by the same large number of Entities … a kind of “for each Entity a one-to-many dependency between Entities so that when one Entity changes state, all its dependents are notified and updated automatically”… what could be your recommendation for designing it as it may concern the initialisation with parenting of Entities as discussed before, Events,… and pitfalls to avoid in order to get performances, stability and reliability during play?

Maybe as you evoked too with update/init Entities/Component, recommendations could arise to avoid browsing components if not necessary (performance?), to use different time base according to the systems …

Hi @Didier,

Performance is a great thing to keep in mind when you’re designing systems, I’m glad you’re thinking about it, thanks for the question!

While our event system is designed to be very efficient, it is true that at some point too many events in a given frame could result in a slow down. My recommendation would be to try and reduce the number of events you send out on a frame by frame basis.

For example, if you have an array of 10000 entities, you may not necessarily need for all of them to receive an event on the same frame, you could throttle the messaging over N frames, this would limit the number of events you’re sending out per-frame. In other words, distribute your event sending over a number of frames rather than in a single frame (tick).

Another strategy is for entities to only connect to events they want to handle only for as long as they need to handle it. What I mean by this is, if after handling an event you will no longer need to handle it anymore, it’s a good idea to disconnect from it. This is not always possible, the benefit is that disconnecting from an event will remove it from the list of recipients of the event.

As much as possible, avoid entities connected to On Tick, but if you do need them to do per-frame operations, try to manage how long they remain connected to On Tick.

These are a few things that come to mind, I hope they help!

LS

Interesting, thanks @LS1 for those recommendations. It reminds me of the organization put in place in case of radar systems.

You define a recurrence period, a pulse width, … and everything is organized around a listening every nth recurrence and according to the pulse width …

Thus it seems for me comparable to what you propose

= pulse impulse width and only each sending/listening at nth recurrence

and then

= listening only during a time period of the nth recurrence.

Would this mean that we would need a class of Events with these kinds of parametrisation or is it already easy to define this kind of behavior without loosing too much in lisibility/simplicity of our scripts ? Could you give us a kind of design template for this ? (an idea : a kind of Gantt tool for Events to get a better visibility on design with those Events)

It’s remind me too that implementing the Get/Send of global variables with Events is overloading maybe unecessary the system and increase complexity. On the other hand using the coordinates of an Empty is not viable for a global Array variable too as discussed here How can I create a global variable in Script Canvas? [Lumberyard 1.14]… or maybe some other solution that escapes me, thus what could be the best way or some missing component or speciallized Event ?

And what is the risk of putting several script components on the same Entity while using Events?

@LS1 I hope that I followed your proposal with those nodes thereafter

but the Get Children is empty.

Thus currently, I’m using On Child Added Node.

image

With this Node I can step by step follow the construction of the parent-child tree and store it in a matrix which is this time perfectly complete.

1 Like

@LS1 For info, it seems impossible to do it for the moment