Mass Entity - Post spawn manipulation of entities

Hello,

What would be the proper way to pass information from a world subsystem or a level actor to a Mass processor in C++ to make the entities behave in a different way through input?

For example, I have an actor that starts a timer and increments a counter after some time passed up to a limit. I would like to have the active entities do something once the counter is incremented by the actor.

I have a Mass world subsystem that can spawn any number of entities at a given location and a processor that makes them change location over time.

Ultimately, I need to know how many active entities each group have in order to assign a random entity as a target for each entity in a processor.

I’ve personally been relying a lot on TQueue<FMyEvent, EQueueMode::SPSC> to safely pass events/data between game-side systems and Mass processors. A processor can declare the subsystem dependency with AddSubsystemRequirement<>() and access it through Context.GetSubsystem<>(). The queue then provides the thread-safe handoff between producers and the processor.

For the team/targeting case, one possible approach would be:

  • Give each entity a TeamId fragment.
  • Push team membership changes into a TQueue:
struct FTeamEvent
{
    FMassEntityHandle Entity;
    int32 TeamId;
};

Have one processor consume those events and maintain in a Mass-accessible subsystem. something like:

TMap<int32, TArray<FMassEntityHandle>> EntitiesByTeam;

Then the targeting processor can read that registry to get the number of active entities per team and select a random target from the opposing team.

I would also explicitly order the processors so the registry update processor and targeting processor don’t access the map concurrently. For example: Events → TeamRegistryProcessor → TargetingProcessor. That way the registry processor is the writer and the targeting processor only needs read access.


I’m failry new to Mass so please feel free to correct me if there is a better more correct way.

Hope it helps.

Adding a subsystem as a requirement and then be able to access it in a processor seemed to be what I needed to know and do.

However having a list of items that is larger than the amount of items per chunk seems to be a problem I need to understand now but Ill ask about it in a new question.

Thank you for the response.

Another way to do this is to create a new entity that serves as an event entity. You can then add fragments to that event entity that needs to be used to update your other entities. Jared Schibel talks about this in his talk on Unlearning OOP for Mass. The explosions in his demo are themselves a new entity that represents the damage and knockback event.

You can also add a tag/fragment to the relevant entity using deferred commands and have an observer that watches for the tag application that can then update the data on the relevant fragments of the entity to alter processing. If you are needing to swap behavior of the entity, I would recommend using composition to dictate the behavior meaning adding/removing fragments so the correct processor runs rather than using branches inside a processor on an enum, bool, etc. There are cases where a branch can be faster especially if you are swapping archetypes frequently, but I would look at composition first.

Also, try to avoid a monolithic entity in your project. The visual representation in the game can be multiple entities in Mass. It does not need to be a 1:1 for viz to entity. Smaller entities should help to cut down on archetype changes.

-James