ue-mass-entity

Use this skill when working with Mass Entity, MassEntity, Mass AI, MassProcessor, MassFragment, MassTag, MassObserver, MassSpawner, MassCrowd, Mass ECS, entity archetype, ForEachEntityChunk, FMassEntityQuery, FMassEntityManager, ISM crowd, or large-scale entity simulation in Unreal Engine. See refer

By quodsoler · 774 installs

npx skills add quodsoler/unreal-engine-skills --skill ue-mass-entity

Source repository · Upstream listing

UE Mass Entity Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use". Mass is an archetype Entity Component System for simulating thousands of agents with cache friendly data layouts and multi threaded processors. The core lives in the always available runtime modules MassEntity and MassCore (plus MassSignals , MassEngine ); gameplay facing pieces (spawning, representation, movement, LOD, replication, actor bridging) come from the MassGameplay (Experimental in 5.8) plugin, and navigation/behavior from MassAI (Experimental in 5.8) and MassCrowd (Experimental in 5.8) . Context Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing. Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code. Request is about… Go to Build.cs, includes, "enable the plugin" [Modules and Build.cs]( modules and buildcs) Declaring fragments, tags, shared/chunk data [Fragments, Tags and Archetypes]( fragments tags and archetypes) Creating/destroying entities, direct mutation [FMassEntityManager]( fmassentitymanager) Writing a processor, scheduling, phases [UMassProcessor]( umassprocessor) Selecting entities, requirements, filtering [FMassEntityQuery]( fmassentityquery) Reading/writing fragment data in a loop [Iteration and FMassExecutionContext]( iteration and fmassexecutioncontext) Adding/removing fragments during iteration [Deferred Commands]( deferred commands) Reacting to fragment/tag add or remove [UMassObserverProcessor]( umassobserverprocessor) One entity outside a processor, fluent build [Single Entity Access and FEntityBuilder]( single entity access and fentitybuilder) Parent/child links, archetype grouping [Relations and Archetype Groups]( relations and archetype groups) Traits, config assets, AMassSpawner [Traits, Config Assets and Spawning]( traits config assets and spawning) ISM rendering, LOD, actor promotion [Representation and LOD]( representation and lod) Crowds, lanes, entity AI [Crowd, Navigation and Behavior]( crowd navigation and behavior) Longer templates live in [mass entity patterns.md](references/mass entity patterns.md); built in types and fields in [mass fragment reference.md](references/mass fragment reference.md). Modules and Build.cs There is no MassEntity plugin to enable. MassEntity and MassCore are runtime modules that ship with the engine — add them to Build.cs and they link. Only the gameplay layers are plugins, and those must be enabled in the .uproject . Include paths that moved into MassCore are namespaced under Mass/ : Mass/EntityElementTypes.h , Mass/EntityFragments.h , Mass/EntityHandle.h , Mass/ExternalSubsystemTraits.h , Mass/ArchetypeGroup.h . MassEntityTypes.h still pulls the element bases in transitively; prefer the explicit Mass/ path. Fragments, Tags and Archetypes Concept Base / type Purpose Entity FMassEntityHandle Index + SerialNumber identity handle Fragment FMassFragment Per entity mutable data Sparse fragment FMassSparseFragment Per entity data stored outside the archetype (no entity move on add) Tag FMassTag Zero size marker used for filtering Sparse tag FMassSparseTag Marker added/removed without an archetype change Chunk fragment FMassChunkFragment One instance per memory chunk Shared fragment FMassSharedFragment Mutable value shared by entities that reference it Const shared fragment FMassConstSharedFragment Immutable shared configuration Archetype FMassArchetypeHandle A unique fragment/tag composition All of these derive from FMassElement and are declared in Mass/EntityElementTypes.h . Entities with the same composition share an archetype, and each fragment type is stored contiguously per chunk. Adding or removing a fragment or tag moves the entity to another archetype — that is why structural change is deferred during iteration. Sparse fragments and sparse tags exist precisely to avoid that move. FMassEntityManager FMassEntityManager is not a UObject ; it is a struct deriving from TSharedFromThis<FMassEntityManager and FGCObject . Reach it through UMassEntitySubsystem (a UMassSubsystemBase , itself a UWorldSubsystem ) or through UE::Mass::Utils . FMassEntityHandle::IsSet() (and its alias IsValid() ) only reports that Index and SerialNumber are non zero. To ask whether an entity really exists, use the manager: Outside processor iteration, direct structural mutation is legal. The add/tag/swap calls take TNotNull<const UScriptStruct ( RemoveFragmentFromEntity still takes a plain const UScriptStruct , MassEntityManager.h:430 ), so pass T::StaticStruct() and never a possibly null pointer. Entity storage is concurrent: FMassEntityManager::Initialize(const FMassEntityManagerStorageInitParams&) takes FMassEntityManager InitParams Concurrent ( MaxEntityCount , MaxEntitiesPerPage ) and builds a FConcurrentEntityStorage . The subsystem does this for you; only standalone managers need the call. UMassProcessor Subclass UMassProcessor , construct the query with this so it registers itself, and override the two virtuals exactly as declared. EMassProcessingPhase : PrePhysics , StartPhysics , DuringPhysics , EndPhysics , PostPhysics , FrameEnd , MAX . EProcessorExecutionFlags : None , Standalone , Server , Client , Editor , EditorWorld , AllNetModes (Standalone Server Client), AllWorldModes (AllNetModes EditorWorld), All . FMassProcessorExecutionOrder carries ExecuteInGroup (an FName ) plus ExecuteBefore and ExecuteAfter arrays of processor or group names. A processor's name is its class FName without the U prefix ( MassProcessorDependencySolver.cpp:560 ) — prefer UOther::StaticClass() GetFName() ; a mistyped name just becomes a dummy node with a Log verbosity message ( :705 ), so the ordering is silently lost. Named groups come from UE::Mass::ProcessorGroupNames : UpdateWorldFromMass , SyncWorldToMass , Behavior , Tasks , Avoidance , ApplyForces , Movement . FMassEntityQuery Declare requirements in ConfigureQueries — never in the constructor, because the query is bound to the entity manager just before ConfigureQueries runs. Queries built with FMassEntityQuery(UMassProcessor& Owner) are already registered; a default constructed member still needs RegisterQuery(Query) . EMassFragmentAccess Meaning None Filter only, no data binding ReadOnly Read through GetFragmentView<T () ( TConstArrayView ) ReadWrite Read/write through GetMutableFragmentView<T () ( TArrayView ) EMassFragmentPresence Meaning All Every listed element must be present Any At least one Any marked element must be present None The element must be absent Optional Bound when present, skipped when absent AddChunkRequirement<T (Access, Presence) binds a FMassChunkFragment . SetChunkFilter(const FMassChunkConditionFunction&) takes a TFunction<bool(const FMassExecutionContext&) evaluated once per chunk, so the predicate may read chunk fragments, shared fragments and constant data — never per entity fragments. Iteration and FMassExecutionContext The lambda takes only FMassExecutionContext& ; there is no entity manager parameter. Other accessors: GetEntities() ( TConstArrayView<FMassEntityHandle ), GetFragmentView<T () , GetMutableFragmentView<T () , GetChunkFragment<T () , GetConstSharedFragment<T () , GetMutableSharedFragment<T () , GetSubsystem<T () , GetMutableSubsystem<T () and Defer() . Parallel: ParallelForEachEntityChunk(Context, Lambda, FMassEntityQuery::EParallelExecutionFlags::Default) ; the nested enum's flags are Default , Force and AutoBalance ( MassEntityQuery.h:67 ). Time slicing: ForEachEntityChunk(Context, Limiter, Lambda) takes a UE::Mass::FExecutionLimiter& built from an entity count, stops once that many entities have been visited (always finishing the current chunk) and resumes from the stored position on the next call. Keep the limiter alive across frames as a processor member — a fresh one restarts from the beginning, and the limiter does not notice entities created or destroyed between calls. Deferred Commands Inside ForEachEntityChunk never mutate composition through the entity manager: the entity moves archetype and the views you are holding dangle. Queue the change on Context.Defer() . Convenience calls on FMassCommandBuffer : AddFragment<T , RemoveFragment<T , AddTag<T , RemoveTag<T , SwapTags<TOld, TNew , AddElements<T... , RemoveElements<T... , DestroyEntity , DestroyEntities . The add/remove helpers forward to FMassCommandAddElements<T... / FMassCommandRemoveElements<T... , which handle any mix of fragments and tags in a single entity move ( SwapTags uses FMassCommandSwapTagsInternal , MassCommandBuffer.h:264 ). To add a fragment and its value, push the command type directly: For arbitrary deferred work push a lambda through FMassDeferredCommand<OpType : Context.Defer().PushCommand<FMassDeferredSetCommand ([Entity](FMassEntityManager& Manager) { ... }); (aliases FMassDeferredCreate/Add/Remove/ChangeComposition/Set/DestroyCommand , MassCommands.h:1686 1744 ). For a reusable typed command, subclass FMassBatchedCommand , override Run(FMassEntityManager&) (the const Execute is UE DEPRECATED(5.7) , MassCommands.h:202 ) and call PushUniqueCommand(TUniquePtr<FMassBatchedCommand &&) . Commands flush by EMassCommandOperationType bucket, not enum order: Create → Add → ChangeComposition → Set → Remove and Destroy (one shared bucket, push order) → the unclassified None last ( MassCommandBuffer.cpp:110 119 ). That ordering guarantees entities exist before they are modified and fragments exist before values are written. UMassObserverProcessor Observers run when an observed fragment or tag is added or removed. Fill ObservedTypes (an array — one observer can watch several types) and ObservedOperations . EMassObservedOperationFlags : None , AddElement , RemoveElement , CreateEntity , DestroyEntity , plus the composites Add (= AddElement CreateEntity ), Remove (= RemoveElement DestroyEntity ) and All . Use Add / Remove unless you deliberately want to ignore entity creation — AddElement alone does not fire for entities that are born with the fragment. Override Register() to customise which types get registered, and read them back with GetObservedTypes() or GetSingleObservedTypeChecked() . Full observer template in [mass entity patterns.md](references/mass entity patterns.md). Single Entity Access and FEntityBuilder FMassEntityView gives typed access to one entity. It is transient — archetype memory relocates, so build a fresh view every time and never cache one. UE::Mass::FEntityBuilder ( MassEntityBuilder.h ) composes an entity fluently and commits once, which beats repeated AddFragmentToEntity calls. SetForceDeferredCommit(true) routes the commit through the command buffer; CommitAndReprepare() reuses the builder for the next entity. Relations and Archetype Groups Relations model typed links between entities. A relation type derives from FMassRelation (itself an FMassTag ); the engine ships FMassChildOfRelation with FMassChildOfFragment in Relations/MassChildOf.h . Instances are created and queried through UE::Mass::FRelationManager , reached with EntityManager.GetRelationManager() .