claude-code-arcane 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +104 -55
  3. package/agents/career/career-strategist.md +88 -0
  4. package/agents/career/cv-reviewer.md +81 -0
  5. package/agents/career/hiring-manager.md +68 -0
  6. package/agents/career/mock-interviewer.md +76 -0
  7. package/agents/freelance/client-screener.md +84 -0
  8. package/agents/freelance/discovery-call.md +65 -0
  9. package/agents/freelance/pipeline-strategist.md +99 -0
  10. package/agents/freelance/proposal-reviewer.md +82 -0
  11. package/agents/game/ue-blueprint-specialist.md +125 -0
  12. package/agents/game/ue-gas-specialist.md +133 -0
  13. package/agents/game/ue-umg-specialist.md +131 -0
  14. package/dist/cli.js +57 -13
  15. package/docs/RELEASE-SETUP.md +1 -1
  16. package/docs/SKILLS-CATALOG.md +67 -4
  17. package/docs/USER-GUIDE.md +77 -72
  18. package/docs/agent-hierarchy.md +21 -1
  19. package/docs/presentations/build_arcane_deck.py +2 -2
  20. package/docs/presentations/build_arcane_deck_12.py +2 -2
  21. package/hooks/detect-unreal.sh +90 -0
  22. package/package.json +2 -2
  23. package/profiles/freelance.yaml +43 -0
  24. package/profiles/job-hunt.yaml +5 -2
  25. package/profiles/unreal-dev.yaml +97 -0
  26. package/rules/drafter-reviewer.md +16 -3
  27. package/rules/freelance-guardrails.md +53 -0
  28. package/rules/gamedev/unreal-code.md +125 -0
  29. package/skills/career-registry/SKILL.md +95 -0
  30. package/skills/career-registry/scripts/career_registry.py +488 -0
  31. package/skills/client-screen/SKILL.md +83 -0
  32. package/skills/client-screen/references/red-flags.md +95 -0
  33. package/skills/cover-letter/SKILL.md +4 -3
  34. package/skills/cv-tailor/SKILL.md +11 -2
  35. package/skills/freelance-deliver/SKILL.md +90 -0
  36. package/skills/freelance-hunt/SKILL.md +126 -0
  37. package/skills/freelance-hunt/references/templates/Connects.md +39 -0
  38. package/skills/freelance-hunt/references/templates/Contrato.md +60 -0
  39. package/skills/freelance-hunt/references/templates/Propuesta.md +66 -0
  40. package/skills/freelance-kickoff/SKILL.md +94 -0
  41. package/skills/freelance-pipeline/SKILL.md +109 -0
  42. package/skills/freelance-pipeline/scripts/import_history.py +425 -0
  43. package/skills/freelance-profile/SKILL.md +93 -0
  44. package/skills/freelance-proposal/SKILL.md +112 -0
  45. package/skills/freelance-scan/SKILL.md +196 -0
  46. package/skills/freelance-scan/references/dedup.md +35 -0
  47. package/skills/freelance-scan/references/platforms.md +167 -0
  48. package/skills/freelance-scan/scripts/freelance_search.py +1077 -0
  49. package/skills/install-mcp/SKILL.md +135 -46
  50. package/skills/install-mcp/references/unreal-operations.md +55 -0
  51. package/skills/interview-prep/SKILL.md +11 -3
  52. package/skills/job-aplicar/SKILL.md +5 -1
  53. package/skills/job-hunt/SKILL.md +17 -0
  54. package/skills/job-outcome/SKILL.md +15 -1
  55. package/skills/job-upskill/SKILL.md +10 -2
  56. package/skills/ue-actor-component-architecture/SKILL.md +509 -0
  57. package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
  58. package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
  59. package/skills/ue-ai-navigation/SKILL.md +526 -0
  60. package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
  61. package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
  62. package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
  63. package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
  64. package/skills/ue-animation-system/SKILL.md +521 -0
  65. package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
  66. package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
  67. package/skills/ue-async-threading/SKILL.md +433 -0
  68. package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
  69. package/skills/ue-async-threading/references/threading-patterns.md +345 -0
  70. package/skills/ue-audio-system/SKILL.md +527 -0
  71. package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
  72. package/skills/ue-blueprints/SKILL.md +134 -0
  73. package/skills/ue-blueprints/references/communication.md +82 -0
  74. package/skills/ue-character-movement/SKILL.md +475 -0
  75. package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
  76. package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
  77. package/skills/ue-cpp-foundations/SKILL.md +533 -0
  78. package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
  79. package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
  80. package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
  81. package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
  82. package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
  83. package/skills/ue-data-assets-tables/SKILL.md +527 -0
  84. package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
  85. package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
  86. package/skills/ue-editor-tools/SKILL.md +523 -0
  87. package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
  88. package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
  89. package/skills/ue-game-features/SKILL.md +477 -0
  90. package/skills/ue-game-features/references/experience-system.md +222 -0
  91. package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
  92. package/skills/ue-gameplay-abilities/SKILL.md +518 -0
  93. package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
  94. package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
  95. package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
  96. package/skills/ue-gameplay-framework/SKILL.md +466 -0
  97. package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
  98. package/skills/ue-input-system/SKILL.md +394 -0
  99. package/skills/ue-input-system/references/cpp-setup.md +131 -0
  100. package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
  101. package/skills/ue-input-system/references/input-action-reference.md +731 -0
  102. package/skills/ue-mass-entity/SKILL.md +476 -0
  103. package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
  104. package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
  105. package/skills/ue-materials-rendering/SKILL.md +526 -0
  106. package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
  107. package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
  108. package/skills/ue-module-build-system/SKILL.md +487 -0
  109. package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
  110. package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
  111. package/skills/ue-naming-conventions/SKILL.md +142 -0
  112. package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
  113. package/skills/ue-naming-conventions/references/content-structure.md +83 -0
  114. package/skills/ue-networking-replication/SKILL.md +452 -0
  115. package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
  116. package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
  117. package/skills/ue-niagara-effects/SKILL.md +531 -0
  118. package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
  119. package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
  120. package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
  121. package/skills/ue-packaging/SKILL.md +116 -0
  122. package/skills/ue-physics-collision/SKILL.md +423 -0
  123. package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
  124. package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
  125. package/skills/ue-procedural-generation/SKILL.md +505 -0
  126. package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
  127. package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
  128. package/skills/ue-project-context/SKILL.md +305 -0
  129. package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
  130. package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
  131. package/skills/ue-serialization-savegames/SKILL.md +524 -0
  132. package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
  133. package/skills/ue-state-trees/SKILL.md +489 -0
  134. package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
  135. package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
  136. package/skills/ue-testing-debugging/SKILL.md +520 -0
  137. package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
  138. package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
  139. package/skills/ue-ui-umg-slate/SKILL.md +431 -0
  140. package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
  141. package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
  142. package/skills/ue-world-level-streaming/SKILL.md +518 -0
  143. package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
  144. package/templates/gamedev/unreal-project-context.md +107 -0
@@ -0,0 +1,476 @@
1
+ ---
2
+ name: ue-mass-entity
3
+ description: "Mass Entity framework, MassProcessor, MassFragment, MassTag, MassObserver (UE 5.5+)"
4
+ category: "gamedev"
5
+ argument-hint: "[system o entity type]"
6
+ user-invocable: true
7
+ allowed-tools: Read, Glob, Grep, Bash, Write, Edit
8
+ ---
9
+
10
+ # UE Mass Entity Framework
11
+
12
+ You are an expert in Unreal Engine's Mass Entity framework -- an archetype-based Entity Component System (ECS) designed for high-performance simulation of thousands of entities using cache-friendly data layouts and parallel processing.
13
+
14
+ Ask before writing: this skill edits Mass processors, fragments, traits and configuration. Propose the change and get approval before using Write or Edit.
15
+
16
+ ## Context Check
17
+
18
+ Before proceeding, read `docs/unreal/project-context.md` to determine:
19
+ - Whether the MassEntity plugin is enabled (and MassAI, MassCrowd, MassGameplay if needed)
20
+ - The target entity count and performance budget
21
+ - Whether MassCrowd lane navigation or ZoneGraph is in use
22
+ - Existing processors, fragments, traits, and entity config assets
23
+
24
+ ## Information Gathering
25
+
26
+ Ask the developer:
27
+ 1. What kind of entities are being simulated? (crowds, projectiles, traffic, wildlife, custom)
28
+ 2. What data does each entity carry? (position, velocity, health, custom state)
29
+ 3. Are entities visualized? If so, what LOD strategy? (ISM, skeletal, actor promotion)
30
+ 4. Is this multiplayer? If so, which entities replicate?
31
+ 5. How many entities at peak? (hundreds vs. tens of thousands)
32
+
33
+ ---
34
+
35
+ ## ECS Concepts
36
+
37
+ Mass Entity uses an archetype ECS model where entity composition determines memory layout:
38
+
39
+ | Concept | Class Base | Purpose |
40
+ |---------|-----------|---------|
41
+ | Entity | `FMassEntityHandle` | 8-byte identity handle (Index + SerialNumber) |
42
+ | Fragment | `FMassFragment` | Per-entity mutable data (position, velocity, health) |
43
+ | Tag | `FMassTag` | Zero-size boolean marker for filtering |
44
+ | Shared Fragment | `FMassSharedFragment` | Per-archetype mutable data |
45
+ | Const Shared Fragment | `FMassConstSharedFragment` | Per-archetype immutable data (mesh params) |
46
+ | Chunk Fragment | `FMassChunkFragment` | Per-memory-chunk data (custom chunk-level state) |
47
+ | Archetype | `FMassArchetypeHandle` | Unique combination of fragment/tag types |
48
+
49
+ **Why archetypes matter:** Entities with identical fragment/tag composition share the same archetype. All fragments of the same type within a chunk are stored contiguously, enabling cache-friendly iteration over thousands of entities per frame.
50
+
51
+ ---
52
+
53
+ ## Fragment and Tag Definitions
54
+
55
+ All types require `USTRUCT()` with `GENERATED_BODY()`:
56
+
57
+ ```cpp
58
+ // Per-entity mutable data
59
+ USTRUCT()
60
+ struct FHealthFragment : public FMassFragment
61
+ {
62
+ GENERATED_BODY()
63
+ float Current = 100.f;
64
+ float Max = 100.f;
65
+ };
66
+
67
+ // Zero-size marker — no data members
68
+ USTRUCT()
69
+ struct FDeadTag : public FMassTag
70
+ {
71
+ GENERATED_BODY()
72
+ };
73
+
74
+ // Shared across all entities in an archetype (mutable)
75
+ USTRUCT()
76
+ struct FTeamSharedFragment : public FMassSharedFragment
77
+ {
78
+ GENERATED_BODY()
79
+ int32 TeamID = 0;
80
+ };
81
+ ```
82
+
83
+ **Chunk fragments** (`FMassChunkFragment`) store per-memory-chunk state shared across all entities in a chunk. Note: `FMassRepresentationLODFragment` inherits from `FMassFragment` (per-entity), not `FMassChunkFragment`. **Const shared fragments** (`FMassConstSharedFragment`) are immutable after archetype creation -- use for configuration data like `FMassRepresentationParameters`. See `references/mass-fragment-reference.md` for built-in types.
84
+
85
+ ---
86
+
87
+ ## FMassEntityManager
88
+
89
+ The entity manager is NOT a `UObject` -- it is a struct (`TSharedFromThis<FMassEntityManager>`, `FGCObject`). Access it through `UMassEntitySubsystem` (a `UWorldSubsystem`):
90
+
91
+ ```cpp
92
+ UMassEntitySubsystem* MassSubsystem = GetWorld()->GetSubsystem<UMassEntitySubsystem>();
93
+ FMassEntityManager& EntityManager = MassSubsystem->GetMutableEntityManager();
94
+ // const ref: MassSubsystem->GetEntityManager()
95
+ ```
96
+
97
+ ### Entity Lifecycle
98
+
99
+ ```cpp
100
+ // One-shot creation
101
+ FMassEntityHandle Entity = EntityManager.CreateEntity(ArchetypeHandle);
102
+
103
+ // With shared fragments
104
+ FMassArchetypeSharedFragmentValues SharedValues;
105
+ FMassEntityHandle Entity = EntityManager.CreateEntity(ArchetypeHandle, SharedValues);
106
+
107
+ // Two-phase (reserve then build)
108
+ FMassEntityHandle Handle = EntityManager.ReserveEntity();
109
+ EntityManager.BuildEntity(Handle, ArchetypeHandle);
110
+
111
+ // Batch creation (thousands at once)
112
+ // BatchCreateEntities returns TSharedRef<FEntityCreationContext> — retain it until
113
+ // observer processors should fire (dropping it early suppresses observer execution).
114
+ TArray<FMassEntityHandle> Entities;
115
+ TSharedRef<FEntityCreationContext> CreationContext =
116
+ EntityManager.BatchCreateEntities(ArchetypeHandle, 5000, Entities);
117
+
118
+ // Destruction
119
+ EntityManager.DestroyEntity(Handle);
120
+ EntityManager.BatchDestroyEntities(EntityArray);
121
+ ```
122
+
123
+ ### Validity Checks
124
+
125
+ `FMassEntityHandle::IsSet()` (aliased as `IsValid()`) only checks non-zero Index/SerialNumber -- it does NOT verify the entity exists. Always use the entity manager:
126
+
127
+ ```cpp
128
+ EntityManager.IsEntityValid(Handle) // entity exists
129
+ EntityManager.IsEntityBuilt(Handle) // fully constructed
130
+ EntityManager.IsEntityActive(Handle) // active in simulation
131
+ ```
132
+
133
+ ### Direct Fragment/Tag Mutations (Outside Processors)
134
+
135
+ ```cpp
136
+ EntityManager.AddFragmentToEntity(Handle, FHealthFragment::StaticStruct());
137
+ EntityManager.RemoveFragmentFromEntity(Handle, FHealthFragment::StaticStruct());
138
+ EntityManager.AddTagToEntity(Handle, FDeadTag::StaticStruct());
139
+ EntityManager.RemoveTagFromEntity(Handle, FDeadTag::StaticStruct());
140
+ EntityManager.SwapTagsForEntity(Handle, FOldTag::StaticStruct(), FNewTag::StaticStruct());
141
+ ```
142
+
143
+ ---
144
+
145
+ ## UMassProcessor
146
+
147
+ Processors iterate over entities matching a query each frame. Subclass `UMassProcessor` (abstract), override `ConfigureQueries()` and `Execute()`:
148
+
149
+ ```cpp
150
+ UCLASS()
151
+ class UMyMovementProcessor : public UMassProcessor
152
+ {
153
+ GENERATED_BODY()
154
+ public:
155
+ UMyMovementProcessor();
156
+ protected:
157
+ virtual void ConfigureQueries(const TSharedRef<FMassEntityManager>& EntityManager) override;
158
+ virtual void Execute(FMassEntityManager& EntityManager,
159
+ FMassExecutionContext& Context) override;
160
+ private:
161
+ FMassEntityQuery MovementQuery;
162
+ };
163
+ ```
164
+
165
+ ### Constructor Configuration
166
+
167
+ ```cpp
168
+ UMyMovementProcessor::UMyMovementProcessor()
169
+ {
170
+ ProcessingPhase = EMassProcessingPhase::PrePhysics;
171
+ ExecutionFlags = static_cast<int32>(
172
+ EProcessorExecutionFlags::Server |
173
+ EProcessorExecutionFlags::Standalone);
174
+ ExecutionOrder.ExecuteInGroup = UE::Mass::ProcessorGroupNames::Movement;
175
+ ExecutionOrder.ExecuteAfter.Add(TEXT("UMassApplyVelocityProcessor"));
176
+ bRequiresGameThreadExecution = false; // true if accessing UObjects
177
+ }
178
+ ```
179
+
180
+ **`EMassProcessingPhase`:** `PrePhysics`, `StartPhysics`, `DuringPhysics`, `EndPhysics`, `PostPhysics`, `FrameEnd`
181
+
182
+ **`EProcessorExecutionFlags`:** `None`(0), `Standalone`(1), `Server`(2), `Client`(4), `Editor`(8), `AllNetModes`(7 = Standalone|Server|Client)
183
+
184
+ **Execution ordering:** `ExecutionOrder.ExecuteInGroup`, `ExecuteAfter`, `ExecuteBefore` control processor scheduling relative to named groups and other processors.
185
+
186
+ ---
187
+
188
+ ## FMassEntityQuery
189
+
190
+ Queries define which entities a processor operates on. Configure in `ConfigureQueries()`, then call `RegisterQuery()`:
191
+
192
+ ```cpp
193
+ void UMyMovementProcessor::ConfigureQueries(const TSharedRef<FMassEntityManager>& EntityManager)
194
+ {
195
+ MovementQuery.AddRequirement<FTransformFragment>(
196
+ EMassFragmentAccess::ReadWrite, EMassFragmentPresence::All);
197
+ MovementQuery.AddRequirement<FMassVelocityFragment>(
198
+ EMassFragmentAccess::ReadOnly, EMassFragmentPresence::All);
199
+ MovementQuery.AddRequirement<FHealthFragment>(
200
+ EMassFragmentAccess::ReadOnly, EMassFragmentPresence::Optional);
201
+ MovementQuery.AddTagRequirement<FDeadTag>(EMassFragmentPresence::None);
202
+ MovementQuery.AddSharedRequirement<FTeamSharedFragment>(
203
+ EMassFragmentAccess::ReadOnly, EMassFragmentPresence::All);
204
+ MovementQuery.AddConstSharedRequirement<FMassRepresentationParameters>(
205
+ EMassFragmentPresence::All);
206
+ MovementQuery.AddRequirement<FMassRepresentationLODFragment>(
207
+ EMassFragmentAccess::ReadWrite, EMassFragmentPresence::Optional);
208
+ MovementQuery.AddSubsystemRequirement<UMassRepresentationSubsystem>(
209
+ EMassFragmentAccess::ReadWrite);
210
+ RegisterQuery(MovementQuery);
211
+ }
212
+ ```
213
+
214
+ | `EMassFragmentAccess` | Usage |
215
+ |----------------------|-------|
216
+ | `None` | No access (filter only) |
217
+ | `ReadOnly` | `GetFragmentView<T>()` -- `TConstArrayView` |
218
+ | `ReadWrite` | `GetMutableFragmentView<T>()` -- `TArrayView` |
219
+
220
+ | `EMassFragmentPresence` | Meaning |
221
+ |------------------------|---------|
222
+ | `All` | Entity must have this fragment |
223
+ | `Any` | At least one `Any`-marked fragment must exist |
224
+ | `None` | Entity must NOT have this fragment |
225
+ | `Optional` | Access if present, skip if absent |
226
+
227
+ ### Fragment-Based Chunk Filtering
228
+
229
+ ```cpp
230
+ // FMassRepresentationLODFragment is a per-entity fragment, not a chunk fragment.
231
+ // Filter using a regular fragment view within the iteration lambda.
232
+ MovementQuery.SetChunkFilter([](const FMassExecutionContext& Context) -> bool {
233
+ // Chunk filters operate on chunk-level data; use per-entity access inside ForEachEntityChunk.
234
+ return true;
235
+ });
236
+ ```
237
+
238
+ ---
239
+
240
+ ## FMassExecutionContext and Iteration
241
+
242
+ Inside `ForEachEntityChunk`, the context provides typed views into chunk data:
243
+
244
+ ```cpp
245
+ void UMyMovementProcessor::Execute(FMassEntityManager& EntityManager,
246
+ FMassExecutionContext& Context)
247
+ {
248
+ MovementQuery.ForEachEntityChunk(Context,
249
+ [this](FMassExecutionContext& Context)
250
+ {
251
+ const int32 NumEntities = Context.GetNumEntities();
252
+ TArrayView<FTransformFragment> Transforms =
253
+ Context.GetMutableFragmentView<FTransformFragment>();
254
+ TConstArrayView<FMassVelocityFragment> Velocities =
255
+ Context.GetFragmentView<FMassVelocityFragment>();
256
+ TConstArrayView<FMassEntityHandle> Entities = Context.GetEntities();
257
+ const float DeltaTime = Context.GetDeltaTimeSeconds();
258
+
259
+ for (int32 i = 0; i < NumEntities; ++i)
260
+ {
261
+ Transforms[i].GetMutableTransform().AddToTranslation(
262
+ Velocities[i].Value * DeltaTime);
263
+ }
264
+ });
265
+ }
266
+ ```
267
+
268
+ **Parallel execution:** `MovementQuery.ParallelForEachEntityChunk(Context, Lambda)` for thread-safe processors.
269
+
270
+ **Subsystem access:** `Context.GetMutableSubsystem<T>()` / `Context.GetSubsystem<T>()` for subsystems declared via `AddSubsystemRequirement`.
271
+
272
+ **Shared/chunk access:** `Context.GetMutableSharedFragment<T>()`, `Context.GetConstSharedFragment<T>()`, `Context.GetChunkFragment<T>()`.
273
+
274
+ ---
275
+
276
+ ## FMassCommandBuffer (Deferred Mutations)
277
+
278
+ **CRITICAL:** Inside `ForEachEntityChunk`, never call entity manager mutations directly. Structural changes during iteration invalidate archetype memory layouts, causing undefined behavior. Use `Context.Defer()`:
279
+
280
+ ```cpp
281
+ MovementQuery.ForEachEntityChunk(Context,
282
+ [](FMassExecutionContext& Context)
283
+ {
284
+ auto Transforms = Context.GetMutableFragmentView<FTransformFragment>();
285
+ auto Entities = Context.GetEntities();
286
+ for (int32 i = 0; i < Context.GetNumEntities(); ++i)
287
+ {
288
+ if (Transforms[i].GetTransform().GetLocation().Z < -1000.f)
289
+ {
290
+ Context.Defer().AddTag<FDeadTag>(Entities[i]);
291
+ Context.Defer().RemoveFragment<FHealthFragment>(Entities[i]);
292
+ }
293
+ }
294
+ });
295
+ ```
296
+
297
+ Deferred command execution order: **Create -> Add -> Remove -> ChangeComposition -> Set -> Destroy**. This guarantees fragments exist before being written, and entities exist before being modified.
298
+
299
+ `PushCommand<T>(Command)` pushes a typed deferred command. Note: `PushCommand` does NOT accept a lambda. For custom deferred logic, use `PushUniqueCommand(TUniquePtr<FMassBatchedCommand>&&)` with a subclass of `FMassBatchedCommand`. See `references/mass-entity-patterns.md` for patterns.
300
+
301
+ ---
302
+
303
+ ## UMassObserverProcessor
304
+
305
+ Observers react to structural changes -- when a fragment or tag is added to or removed from an entity. They fire automatically:
306
+
307
+ ```cpp
308
+ UCLASS()
309
+ class UHealthAddedObserver : public UMassObserverProcessor
310
+ {
311
+ GENERATED_BODY()
312
+ public:
313
+ UHealthAddedObserver()
314
+ {
315
+ ObservedType = FHealthFragment::StaticStruct();
316
+ ObservedOperations = EMassObservedOperationFlags::AddElement;
317
+ }
318
+ protected:
319
+ virtual void ConfigureQueries(const TSharedRef<FMassEntityManager>& EntityManager) override;
320
+ virtual void Execute(FMassEntityManager& EntityManager,
321
+ FMassExecutionContext& Context) override;
322
+ };
323
+ ```
324
+
325
+ The observer `Execute` runs only for entities that just had the observed type added/removed. Use observers for initialization, cleanup, and state-change responses instead of per-frame polling.
326
+
327
+ ---
328
+
329
+ ## FMassEntityView
330
+
331
+ For single-entity access outside processor iteration, use `FMassEntityView`. It is transient -- never store across frames because archetype memory can relocate:
332
+
333
+ ```cpp
334
+ if (EntityManager.IsEntityValid(Handle))
335
+ {
336
+ FMassEntityView View(EntityManager, Handle);
337
+ if (View.GetFragmentDataPtr<FHealthFragment>() != nullptr)
338
+ {
339
+ FHealthFragment& Health = View.GetFragmentData<FHealthFragment>();
340
+ Health.Current -= Damage;
341
+ }
342
+ bool bDead = View.HasTag<FDeadTag>();
343
+ }
344
+ ```
345
+
346
+ ---
347
+
348
+ ## Mass Spawner and Config Assets
349
+
350
+ `UMassEntityConfigAsset` defines entity templates via traits. Add traits like `UMassAssortedFragmentsTrait` (custom fragments), `UMassVisualizationTrait` (ISM visualization), or `UMassReplicationTrait` (networking).
351
+
352
+ Custom traits subclass `UMassEntityTraitBase` and override `BuildTemplate(FMassEntityTemplateBuildContext&, const UWorld&)` to add fragments and configure archetypes. `ValidateTemplate()` provides editor-time validation.
353
+
354
+ `AMassSpawner` is a world actor that references entity config assets and controls spawn count, timing, and spatial distribution. See `references/mass-entity-patterns.md` for trait implementation templates.
355
+
356
+ ---
357
+
358
+ ## Common Fragments
359
+
360
+ | Fragment | Type | Purpose |
361
+ |----------|------|---------|
362
+ | `FTransformFragment` | Fragment | Entity world transform |
363
+ | `FMassVelocityFragment` | Fragment | Linear velocity |
364
+ | `FMassForceFragment` | Fragment | Applied force |
365
+ | `FAgentRadiusFragment` | Fragment | Agent collision radius |
366
+ | `FMassMoveTargetFragment` | Fragment | Navigation move target |
367
+ | `FMassRepresentationFragment` | Fragment | Current visual representation state |
368
+ | `FMassRepresentationLODFragment` | Fragment | Per-entity LOD level and visibility state |
369
+ | `FMassRepresentationParameters` | Const Shared | Representation type per LOD, update rate config |
370
+ | `FMassMovementParameters` | Const Shared | Max speed, acceleration |
371
+
372
+ See `references/mass-fragment-reference.md` for complete field details and trait types.
373
+
374
+ ---
375
+
376
+ ## Representation (ISM Visualization)
377
+
378
+ Mass Entity uses Instanced Static Meshes for rendering thousands of entities without per-entity actors:
379
+
380
+ | `EMassRepresentationType` | Usage |
381
+ |--------------------------|-------|
382
+ | `StaticMeshInstance` | ISM for mid/far entities |
383
+ | `HighResSpawnedActor` | Full actor for close-up (high LOD) |
384
+ | `LowResSpawnedActor` | Reduced actor for medium LOD |
385
+ | `None` | No visual representation |
386
+
387
+ | `EMassLOD` | Detail Level |
388
+ |------------|-------------|
389
+ | `High` | Full detail, actor-based |
390
+ | `Medium` | Reduced detail |
391
+ | `Low` | Minimal (ISM only) |
392
+ | `Off` | Not rendered |
393
+
394
+ `UMassRepresentationSubsystem` manages ISM instances. Use `UMassVisualizationTrait` on entity configs to set meshes and LOD distances. Force game-thread for representation processors: `TMassSharedFragmentTraits<T>::GameThreadOnly = true`.
395
+
396
+ ---
397
+
398
+ ## MassCrowd
399
+
400
+ `UMassCrowdSubsystem` provides lane-based navigation using ZoneGraph for pedestrian crowd simulation. Located in `Engine/Plugins/AI/MassCrowd/` (not Runtime).
401
+
402
+ Key features: lane state management, waiting slot allocation, density tracking, and avoidance. Thread-safe for parallel processors: `TMassExternalSubsystemTraits<UMassCrowdSubsystem>::GameThreadOnly = false`.
403
+
404
+ Entities use `FMassMoveTargetFragment` for lane-following targets. ZoneGraph defines navigation lanes as connected graphs with automatic density management.
405
+
406
+ ---
407
+
408
+ ## StateTree Integration
409
+
410
+ Mass Entity processors can trigger State Tree evaluations for entity AI. State Trees provide hierarchical decision-making for Mass entities as an alternative to per-entity behavior trees (prohibitively expensive at scale). For State Tree architecture and task patterns, see `/ue-state-trees`.
411
+
412
+ ---
413
+
414
+ ## Common Mistakes
415
+
416
+ **Direct mutations inside ForEachEntityChunk:**
417
+
418
+ ```cpp
419
+ // WRONG: direct mutation during iteration — undefined behavior
420
+ Query.ForEachEntityChunk(Context,
421
+ [&EntityManager](FMassExecutionContext& Context) {
422
+ EntityManager.AddFragmentToEntity(Context.GetEntities()[0],
423
+ FHealthFragment::StaticStruct()); // CRASH
424
+ });
425
+ // RIGHT: use deferred commands
426
+ Query.ForEachEntityChunk(Context,
427
+ [](FMassExecutionContext& Context) {
428
+ Context.Defer().AddFragment<FHealthFragment>(Context.GetEntities()[0]);
429
+ });
430
+ ```
431
+
432
+ **Storing FMassEntityView across frames:** Entity views are transient. Archetype memory may relocate between frames, invalidating stored views. Create a fresh `FMassEntityView` each time.
433
+
434
+ **Using IsSet/IsValid for existence:** `Handle.IsSet()` only checks non-zero fields. A destroyed entity's handle still returns true. Use `EntityManager.IsEntityValid(Handle)`.
435
+
436
+ **Missing RegisterQuery:** Forgetting `RegisterQuery(MyQuery)` in `ConfigureQueries()` silently skips the query. Every query used in `Execute` must be registered.
437
+
438
+ **UObject access without game-thread flag:** Accessing `UObject` properties from a parallel processor causes races. Set `bRequiresGameThreadExecution = true` or declare dependencies via `AddSubsystemRequirement`.
439
+
440
+ **Fragment access mismatch:** `ReadOnly` access + `GetMutableFragmentView<T>()` triggers an assertion. Match access mode to view type.
441
+
442
+ ---
443
+
444
+ ## Reference Files
445
+
446
+ - `references/mass-entity-patterns.md` -- Processor, observer, trait, and deferred command code templates
447
+ - `references/mass-fragment-reference.md` -- Built-in fragment types, shared fragments, and trait classes
448
+
449
+ ## Related Skills
450
+
451
+ - `/ue-ai-navigation` -- NavMesh pathfinding and AI perception for Mass agents
452
+ - `/ue-procedural-generation` -- PCG and ISM patterns relevant to Mass representation
453
+ - `/ue-gameplay-framework` -- GameMode/GameState interaction with Mass simulation
454
+ - `/ue-actor-component-architecture` -- Actor-entity bridging via MassAgentComponent
455
+ - `/ue-async-threading` -- Parallel execution patterns and thread safety
456
+ - `/ue-cpp-foundations` -- USTRUCT, UCLASS, subsystem patterns
457
+
458
+ ---
459
+
460
+ ## Checklist
461
+
462
+ Validate before considering the work done:
463
+
464
+ - [ ] Fragments hold plain data only, with logic confined to processors
465
+ - [ ] Processor execution order and dependencies are declared explicitly
466
+ - [ ] Mass is justified by entity count; a plain actor would not do
467
+ - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
468
+ - [ ] The Common Mistakes section of this skill was reviewed against the change
469
+
470
+ **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
471
+
472
+ ## Next Steps
473
+
474
+ - `/perf-profile` — verify Mass is actually paying for itself
475
+ - `/code-review` — architectural and quality review of the change
476
+ - `/commit` — conventional commit once the change is verified