Course contentsShow
← Unreal Engine Game Development
Lesson 471 of 8806. AI, Navigation, and Decision MakingFree lesson

Managing Large Agent Populations with Mass Entity Framework

You will leverage the Mass Entity system to offload AI calculations to data-oriented structures, enabling the simulation of hundreds of agents simultaneously.

In this lesson, you will learn how to leverage the Data-Oriented Technology Stack (DOTS) within the Mass Entity framework to offload AI logic from heavy AActor classes into highly performant, memory-efficient data structures.

Moving Beyond the Actor Bottleneck

Traditionally, Unreal AI relies on AActor and AController instances. Each of these carries significant memory overhead—rendering overhead, component ticking, and object management—which causes performance to plummet when simulating hundreds or thousands of agents.

The Mass Entity framework shifts this paradigm by decoupling state from logic. Instead of an object-oriented approach, Mass treats agents as "Entities" (a simple ID) associated with "Components" (plain data structs). By using Mass Processors, we iterate over arrays of these components in contiguous memory, allowing the CPU to cache data more efficiently and process thousands of agents in the same time it would take to update a handful of standard Actors.

Practical Implementation

To scale your AI, you define your agent's state using FMassEntityHandle and FMassComponent. Logic is then performed by UMassProcessor classes. Instead of every AI having a tick function, the Processor runs once per frame for all entities that possess the relevant component data.

For example, a steering processor might look like this:

void UMassMovementProcessor::Execute(FMassEntityManager& EntityManager, FMassExecutionContext& Context)
{
    Context.ForEachEntityChunk(MovementQuery, [&](FMassExecutionContext& ChunkContext)
    {
        auto& Positions = ChunkContext.GetMutableFragmentView<FMassPositionFragment>();
        auto& Velocities = ChunkContext.GetMutableFragmentView<FMassVelocityFragment>();

        for (int32 i = 0; i < ChunkContext.GetNumEntities(); ++i)
        {
            // Logic operates on contiguous data, not high-level object calls
            Positions[i].Position += Velocities[i].Velocity * ChunkContext.GetDeltaTime();
        }
    });
}

By keeping the data flat and the logic localized within these Processors, you avoid the overhead of virtual function calls and pointer indirection that typically plague large-scale crowd simulations. This architecture allows you to maintain complex behaviors—like navigation and flocking—by processing them in batches rather than individually.

Key Takeaway: By offloading agent data into memory-efficient structs processed in batches via Mass Processors, you replace expensive per-actor logic with high-performance, data-oriented iterations that scale to thousands of agents.