Hello,
in our current game, we use structures derived from FMassBatchedCommand to execute different Mass-related operations on entities and have a way to provide arbitrary payloads to the command itself (without forcing archetype changes).
In simple cases we just use it to modify some of the entity fragments, in more complex ones, we actually construct&run a FMassEntityQuery to do more complex processing (ie. signal some entities, etc.).
Either way, we run our logic inside the derived struct’s ::Execute(FMassEntityManager& EntityManager) method.
Is this a viable pattern, or would you prefer us to execute the queries beforehand, outside of the command?
To give you a concrete example, we do something along the lines of the snipped linked in “Steps to Reproduce”.
Thanks in advance!
Steps to Reproduce
UMassEntitySubsystem* EntitySubsystem = GetWorld()->GetSubsystem<UMassEntitySubsystem>();
EntitySubsystem->GetMutableEntityManager().Defer().PushCommand<FBuildExcluderVolumeActivatedCommand>(
ExcluderEntry->Handle
);
Hello,
I’m bumping up this question, can you provide us some hint about it?
Thanks
Emanuele
Hi,
I’m bumping this as well: it’d be great if you could provide us with an answer, it’d be super useful to validate our direction on Mass Commands…
Thanks
Timothy
Hello,
My apologies for the delay in getting a response on this question. One potential problem that immediately caught my attention is the possibility of threading or owner ID issues of running the entity query from your command. I do not believe the query would be picked up by our dependency solver to ensure that the entities being iterated over would not change while your logic executes. It could also work the other way where you change an entity that another processor has work on and the other processors is the one that throws an error due to changes to the entity.
Can you share a bit more of what you are trying to accomplish by using the data payload instead of having different commands to do things? It certainly helps us to have use cases as we work on Mass, and it helps us in coming up with how this could fit in the current system or how we would try to do it.
-James
Hi James,
first of all, thanks a lot for your reply!
I was under the impression that FMassBatchedCommand(s) scheduled with EntityManager.Defer().PushCommand<…> run after MassProcessor and thus it should be safe to execute queries or change entity data inside their ::Execute().
Can I ask you a bit more about their execution and scheduling, related to MassProcessor?
Should you want to point us to some specific sections in engine code it’d be great!
In general, our processors are all on the game thread and we do not intend to parallelize them.
I’ve picked one command we’re using in our game, you can find it right below.
Thanks a lot for your time!
Timothy van der Gen
So Defer does run the commands on the game thread. It is supposed to happen between processing phases, but we have recently discovered that there is inconsistencies in how IsProcessing is run where things can be not processing when it is evaluated but begin before processing is locked. I do not recall if the fix for that was included for 5.7. It is not something we often see for running commands, but has caused some baffling issues both internally and for other licensees when it is checked prior to logic and then an assert is triggered. It is also possible to flush commands outside of the game thread, and I was a bit worried you may have been doing that while creating entity queries.
BatchedMassCommands were intended for specific, single, batched action on a set of entities. It may currently support larger operations such as queries, but it is not something we will support and any issues found would not be considered bugs by us. There is talk and plans of making the MassEntityManager API more limited and only accessible easily through the execution context. I don’t have a full ETA on when that may be done, but it is something currently seeing attention and development effort. When I had mentioned your question with the team, the overwhelming opinion was not to use commands in this way.
We would like to add the ability to have payloads to MassSignals using something akin to FInstancedStructs. This is a desire, but unfortunately is not currently planned to be able to give even a rough ETA.
-James