claude-code-arcane 2.3.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 (103) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +54 -6
  3. package/agents/game/ue-blueprint-specialist.md +125 -0
  4. package/agents/game/ue-gas-specialist.md +133 -0
  5. package/agents/game/ue-umg-specialist.md +131 -0
  6. package/dist/cli.js +5 -0
  7. package/docs/SKILLS-CATALOG.md +42 -3
  8. package/docs/USER-GUIDE.md +2 -2
  9. package/hooks/detect-unreal.sh +90 -0
  10. package/package.json +1 -1
  11. package/profiles/unreal-dev.yaml +97 -0
  12. package/rules/gamedev/unreal-code.md +125 -0
  13. package/skills/install-mcp/SKILL.md +135 -46
  14. package/skills/install-mcp/references/unreal-operations.md +55 -0
  15. package/skills/ue-actor-component-architecture/SKILL.md +509 -0
  16. package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
  17. package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
  18. package/skills/ue-ai-navigation/SKILL.md +526 -0
  19. package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
  20. package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
  21. package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
  22. package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
  23. package/skills/ue-animation-system/SKILL.md +521 -0
  24. package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
  25. package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
  26. package/skills/ue-async-threading/SKILL.md +433 -0
  27. package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
  28. package/skills/ue-async-threading/references/threading-patterns.md +345 -0
  29. package/skills/ue-audio-system/SKILL.md +527 -0
  30. package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
  31. package/skills/ue-blueprints/SKILL.md +134 -0
  32. package/skills/ue-blueprints/references/communication.md +82 -0
  33. package/skills/ue-character-movement/SKILL.md +475 -0
  34. package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
  35. package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
  36. package/skills/ue-cpp-foundations/SKILL.md +533 -0
  37. package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
  38. package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
  39. package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
  40. package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
  41. package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
  42. package/skills/ue-data-assets-tables/SKILL.md +527 -0
  43. package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
  44. package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
  45. package/skills/ue-editor-tools/SKILL.md +523 -0
  46. package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
  47. package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
  48. package/skills/ue-game-features/SKILL.md +477 -0
  49. package/skills/ue-game-features/references/experience-system.md +222 -0
  50. package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
  51. package/skills/ue-gameplay-abilities/SKILL.md +518 -0
  52. package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
  53. package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
  54. package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
  55. package/skills/ue-gameplay-framework/SKILL.md +466 -0
  56. package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
  57. package/skills/ue-input-system/SKILL.md +394 -0
  58. package/skills/ue-input-system/references/cpp-setup.md +131 -0
  59. package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
  60. package/skills/ue-input-system/references/input-action-reference.md +731 -0
  61. package/skills/ue-mass-entity/SKILL.md +476 -0
  62. package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
  63. package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
  64. package/skills/ue-materials-rendering/SKILL.md +526 -0
  65. package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
  66. package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
  67. package/skills/ue-module-build-system/SKILL.md +487 -0
  68. package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
  69. package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
  70. package/skills/ue-naming-conventions/SKILL.md +142 -0
  71. package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
  72. package/skills/ue-naming-conventions/references/content-structure.md +83 -0
  73. package/skills/ue-networking-replication/SKILL.md +452 -0
  74. package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
  75. package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
  76. package/skills/ue-niagara-effects/SKILL.md +531 -0
  77. package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
  78. package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
  79. package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
  80. package/skills/ue-packaging/SKILL.md +116 -0
  81. package/skills/ue-physics-collision/SKILL.md +423 -0
  82. package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
  83. package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
  84. package/skills/ue-procedural-generation/SKILL.md +505 -0
  85. package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
  86. package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
  87. package/skills/ue-project-context/SKILL.md +305 -0
  88. package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
  89. package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
  90. package/skills/ue-serialization-savegames/SKILL.md +524 -0
  91. package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
  92. package/skills/ue-state-trees/SKILL.md +489 -0
  93. package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
  94. package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
  95. package/skills/ue-testing-debugging/SKILL.md +520 -0
  96. package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
  97. package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
  98. package/skills/ue-ui-umg-slate/SKILL.md +431 -0
  99. package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
  100. package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
  101. package/skills/ue-world-level-streaming/SKILL.md +518 -0
  102. package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
  103. package/templates/gamedev/unreal-project-context.md +107 -0
@@ -0,0 +1,423 @@
1
+ # EQS Reference
2
+
3
+ Environment Query System (EQS) generator and test configurations for common AI spatial reasoning tasks.
4
+
5
+ ---
6
+
7
+ ## Architecture Overview
8
+
9
+ ```
10
+ UEnvQuery (Data Asset)
11
+ └── Options (array of UEnvQueryOption)
12
+ ├── Generator — produces candidate items (locations or actors)
13
+ └── Tests (array) — filter and score items
14
+ ├── Filter: Discard items that fail the condition
15
+ └── Score: Weight items by test result
16
+ ```
17
+
18
+ Key classes:
19
+ - `UEnvQuery` — the query asset (inherits `UDataAsset`)
20
+ - `UEnvQueryManager` — subsystem that executes queries
21
+ - `FEnvQueryResult` — results: `GetItemAsLocation(0)`, `GetItemAsActor(0)`, `GetRawStatusDesc()`
22
+ - `UEnvQueryContext_Querier` — built-in context: the AI pawn running the query
23
+ - `UEnvQueryContext_Item` — built-in context: each candidate item (used in item-relative tests)
24
+
25
+ ---
26
+
27
+ ## Generators
28
+
29
+ ### SimpleGrid (Point Grid)
30
+
31
+ Generates a uniform grid of points on the NavMesh around a center context.
32
+
33
+ | Property | Type | Description |
34
+ |----------|------|-------------|
35
+ | `GridHalfSize` | Float | Half extent of the grid (cm). 500 = 10x10 at 100cm spacing |
36
+ | `SpaceBetween` | Float | Spacing between points (cm) |
37
+ | `GenerateAroundActor` | Context | Usually `EnvQueryContext_Querier` |
38
+ | `ProjectDown` | Float | How far down to project onto NavMesh |
39
+
40
+ Practical settings for cover search (nearby): `GridHalfSize=800, SpaceBetween=150`
41
+ Practical settings for patrol (wide area): `GridHalfSize=2000, SpaceBetween=300`
42
+
43
+ ### Ring (DonutAroundActor)
44
+
45
+ Generates points on a ring/annulus around a context at a specified radius range.
46
+
47
+ | Property | Type | Description |
48
+ |----------|------|-------------|
49
+ | `Center` | Context | Center of ring (e.g., `EnvQueryContext_Querier`) |
50
+ | `Radius` | Float | Ring radius (cm) |
51
+ | `ItemSpacing` | Float | Angular spacing between ring points |
52
+ | `ArcDirection` | Direction | Optional: restrict to a forward arc |
53
+
54
+ Use for: **flanking positions** (ring around enemy), **retreat points** (ring around self, facing away from enemy).
55
+
56
+ ### PathingGrid (Points on NavMesh reachable from context)
57
+
58
+ Extends SimpleGrid by only keeping points reachable via NavMesh from the querier. More expensive but guarantees navigability.
59
+
60
+ | Property | Type | Description |
61
+ |----------|------|-------------|
62
+ | `GenerateAroundActor` | Context | Usually `EnvQueryContext_Querier` |
63
+ | `MaxDistance` | Float | NavMesh distance budget |
64
+ | `SpaceBetween` | Float | Grid spacing |
65
+ | `ScanRangeMultiplier` | Float | Multiplies scan range for path exploration |
66
+
67
+ ### ActorsOfClass
68
+
69
+ Generates candidate actors of a given class (e.g., `APatrolPoint`, `APickup`).
70
+
71
+ | Property | Type | Description |
72
+ |----------|------|-------------|
73
+ | `SearchedActorClass` | Class | Actor class to find |
74
+ | `SearchCenter` | Context | Center of search radius |
75
+ | `SearchRadius` | Float | Radius to find actors in |
76
+
77
+ Use for: **patrol waypoints**, **interact targets**, **pickup locations**.
78
+
79
+ ### Composite Generator
80
+
81
+ Combines results from multiple generators into one candidate set. Each sub-generator runs independently; results are merged.
82
+
83
+ ---
84
+
85
+ ## Tests
86
+
87
+ Each test has a **Test Purpose**: `Filter` (discard), `Score` (weight), or `FilterAndScore`.
88
+
89
+ ### Distance Test
90
+
91
+ Scores/filters by distance between item and a context.
92
+
93
+ | Property | Type | Use |
94
+ |----------|------|-----|
95
+ | `DistanceTo` | Context | Usually `EnvQueryContext_Querier` or enemy context |
96
+ | `TestMode` | Enum | PathLength (NavMesh), Straight3D, Straight2D, Z |
97
+ | `ScoringEquation` | Enum | Constant, Linear, Square, InverseLinear |
98
+ | `ScoringFactor` | Float | Multiplier on the score |
99
+
100
+ **Find nearest actor**: Score=InverseLinear, ScoringFactor=1.0
101
+ **Find farthest (flee)**: Score=Linear, ScoringFactor=1.0
102
+ **Filter within range**: Purpose=Filter, FloatValueMin=100, FloatValueMax=2000
103
+
104
+ ### Trace Test
105
+
106
+ Checks line-of-sight between item and a context. Can be used to find covered positions (no LoS to enemy) or exposed positions (has LoS to enemy).
107
+
108
+ | Property | Type | Use |
109
+ |----------|------|-----|
110
+ | `TraceFrom` | Context | Usually enemy actor context |
111
+ | `TraceChannel` | Enum | Visibility, Camera, or custom |
112
+ | `BoolMatch` | Bool | `true` = requires LoS; `false` = requires NO LoS (cover) |
113
+ | `TraceMode` | Enum | Navigation, Geometry, ByChannel |
114
+
115
+ **Cover query**: `BoolMatch=false` (item must NOT be visible from enemy)
116
+ **Sniper position query**: `BoolMatch=true` (item must have LoS to enemy)
117
+
118
+ ### Dot Product Test
119
+
120
+ Scores items by the dot product of two directions. Useful for angular relationship checks.
121
+
122
+ | Property | Type | Use |
123
+ |----------|------|-----|
124
+ | `LineFrom` | Context | Origin of direction line |
125
+ | `LineTo` | Context | End of direction line |
126
+ | `TestAgainst` | Direction | Direction to test against |
127
+ | `bAbsoluteValue` | Bool | Use absolute dot product |
128
+
129
+ **Prefer items behind the querier**: `LineFrom=Enemy, LineTo=Querier, TestAgainst=ItemToLine`
130
+ **Flanking (perpendicular)**: Set scoring to penalize high dot products
131
+
132
+ ### Overlap Test
133
+
134
+ Filters items that have overlapping geometry of a given class or channel.
135
+
136
+ | Property | Type | Use |
137
+ |----------|------|-----|
138
+ | `OverlapData` | Shape | Box, Sphere, or Capsule |
139
+ | `OverlapChannel` | Channel | Collision channel to check |
140
+ | `bOnlyBlockingHits` | Bool | Filter based on blocking overlaps |
141
+
142
+ Use for: checking clearance at candidate positions (e.g., "is there room to stand here?").
143
+
144
+ ### Pathfinding Length Test
145
+
146
+ Scores items by how long the NavMesh path from the querier is. Different from straight-line distance.
147
+
148
+ | Property | Type | Use |
149
+ |----------|------|-----|
150
+ | `Context` | Context | Path destination context |
151
+ | `ScoringEquation` | Enum | Linear (prefer shorter paths) or InverseLinear |
152
+ | `PathFromContext` | Bool | If true, path goes from context to item |
153
+
154
+ Use for: **patrol point selection** (prefer reachable points without huge path detours), **cover with fast exit route**.
155
+
156
+ ### GameplayTagsTest
157
+
158
+ Filters/scores items based on GameplayTags on the item actor.
159
+
160
+ | Property | Type | Use |
161
+ |----------|------|-----|
162
+ | `TagsToMatch` | FGameplayTagContainer | Required tags |
163
+ | `TagMatchType` | Enum | HasAll, HasAny |
164
+ | `bMustPass` | Bool | True = filter out non-matching |
165
+
166
+ ---
167
+
168
+ ## Common Query Configurations
169
+
170
+ ### 1. Find Nearest Cover
171
+
172
+ Goal: AI hides from enemy, selecting the closest covered position.
173
+
174
+ ```
175
+ Generator: SimpleGrid
176
+ GridHalfSize = 800
177
+ SpaceBetween = 150
178
+ GenerateAround = EnvQueryContext_Querier
179
+
180
+ Test 1: Trace (Filter)
181
+ TraceFrom = EnemyContext
182
+ BoolMatch = false ← item must NOT be visible from enemy
183
+ TraceChannel = Visibility
184
+
185
+ Test 2: Distance (Score)
186
+ DistanceTo = EnvQueryContext_Querier
187
+ TestMode = Straight2D
188
+ ScoringEquation = InverseLinear ← prefer closer cover
189
+ ScoringFactor = 1.0
190
+
191
+ Test 3: Pathfinding Length (Filter + Score)
192
+ Purpose = FilterAndScore
193
+ FloatValueMax = 3000 ← discard unreachable points
194
+ ScoringEquation = InverseLinear
195
+ ```
196
+
197
+ ### 2. Find Flee Point (Retreat from Enemy)
198
+
199
+ Goal: AI moves far from enemy while staying navigable.
200
+
201
+ ```
202
+ Generator: PathingGrid
203
+ MaxDistance = 2000
204
+ SpaceBetween = 300
205
+ GenerateAround = EnvQueryContext_Querier
206
+
207
+ Test 1: Distance from Enemy (Score)
208
+ DistanceTo = EnemyContext
209
+ ScoringEquation = Linear ← higher score = farther from enemy
210
+ ScoringFactor = 1.0
211
+
212
+ Test 2: Trace from Enemy (Score — optional soft preference)
213
+ TraceFrom = EnemyContext
214
+ BoolMatch = false
215
+ Purpose = Score ← bonus score for hidden positions
216
+ ScoringFactor = 0.5
217
+
218
+ Test 3: Distance from Self (Filter)
219
+ DistanceTo = EnvQueryContext_Querier
220
+ Purpose = Filter
221
+ FloatValueMin = 400 ← don't pick a spot right next to self
222
+ ```
223
+
224
+ ### 3. Find Flanking Position
225
+
226
+ Goal: AI reaches a position perpendicular to the enemy, neither directly behind nor in front.
227
+
228
+ ```
229
+ Generator: Ring
230
+ Center = EnemyContext
231
+ Radius = 600
232
+ ItemSpacing = 45 ← 8 points around enemy
233
+
234
+ Test 1: Dot Product (Score — penalize direct front/back)
235
+ LineFrom = EnemyContext (enemy forward)
236
+ LineTo = Item position
237
+ bAbsoluteValue = true
238
+ ScoringEquation = InverseLinear ← low dot = perpendicular = high score
239
+
240
+ Test 2: Trace to Enemy from Item (Filter)
241
+ TraceFrom = EnemyContext
242
+ BoolMatch = true ← flanking position must have LoS to attack from
243
+ TraceChannel = Visibility
244
+
245
+ Test 3: Pathfinding Length (Filter)
246
+ FloatValueMax = 2500 ← must be reachable
247
+ ```
248
+
249
+ ### 4. Find Patrol Waypoint
250
+
251
+ Goal: Select a patrol destination that is not the current location, ideally exploring unvisited areas.
252
+
253
+ ```
254
+ Generator: ActorsOfClass
255
+ SearchedActorClass = APatrolPoint
256
+ SearchCenter = EnvQueryContext_Querier
257
+ SearchRadius = 5000
258
+
259
+ Test 1: Distance (Filter + Score)
260
+ DistanceTo = EnvQueryContext_Querier
261
+ Purpose = FilterAndScore
262
+ FloatValueMin = 100 ← not current location
263
+ FloatValueMax = 4000
264
+ ScoringEquation = Linear ← prefer farther points for exploration
265
+
266
+ Test 2: GameplayTags (Filter — optional)
267
+ TagsToMatch = PatrolPoint.Active
268
+ bMustPass = true
269
+ ```
270
+
271
+ ### 5. Find Attack Position (Ranged AI)
272
+
273
+ Goal: AI positions itself at ideal attack range, with LoS, not too close.
274
+
275
+ ```
276
+ Generator: Ring
277
+ Center = EnvQueryContext_Querier
278
+ Radius = [AttackRangeMin..AttackRangeMax] ← can use two rings merged with Composite
279
+ ItemSpacing = 30
280
+
281
+ Test 1: Distance from Enemy (Filter)
282
+ DistanceTo = EnemyContext
283
+ Purpose = Filter
284
+ FloatValueMin = AttackRangeMin
285
+ FloatValueMax = AttackRangeMax
286
+
287
+ Test 2: Trace to Enemy (Filter — must have LoS)
288
+ TraceFrom = EnemyContext
289
+ BoolMatch = true
290
+ TraceChannel = Visibility
291
+
292
+ Test 3: Distance from Self (Score — minimize movement)
293
+ DistanceTo = EnvQueryContext_Querier
294
+ ScoringEquation = InverseLinear
295
+ ScoringFactor = 0.3 ← lower weight: prefer standing still if already in range
296
+ ```
297
+
298
+ ---
299
+
300
+ ## Custom EQS Context (C++)
301
+
302
+ A custom context resolves to a specific actor or location, used in tests:
303
+
304
+ ```cpp
305
+ #include "EnvironmentQuery/EnvQueryContext.h"
306
+ #include "EnvironmentQuery/Items/EnvQueryItemType_Actor.h"
307
+
308
+ UCLASS()
309
+ class UEnvQueryContext_Enemy : public UEnvQueryContext
310
+ {
311
+ GENERATED_BODY()
312
+ public:
313
+ virtual void ProvideContext(
314
+ FEnvQueryInstance& QueryInstance,
315
+ FEnvQueryContextData& ContextData) const override
316
+ {
317
+ AAIController* Controller = Cast<AAIController>(
318
+ Cast<APawn>(QueryInstance.Owner.Get())->GetController());
319
+ if (!Controller) { return; }
320
+
321
+ UBlackboardComponent* BB = Controller->GetBlackboardComponent();
322
+ if (!BB) { return; }
323
+
324
+ AActor* Enemy = Cast<AActor>(BB->GetValueAsObject(TEXT("TargetActor")));
325
+ if (IsValid(Enemy))
326
+ {
327
+ UEnvQueryItemType_Actor::SetContextHelper(ContextData, Enemy);
328
+ }
329
+ }
330
+ };
331
+ ```
332
+
333
+ Blueprint context (simpler): Subclass `UEnvQueryContext_BlueprintBase` and implement `ProvideActorsSet` or `ProvideSingleLocation`.
334
+
335
+ ---
336
+
337
+ ## Running EQS Queries from C++
338
+
339
+ ### Direct call (one-shot)
340
+
341
+ ```cpp
342
+ #include "EnvironmentQuery/EnvQueryManager.h"
343
+
344
+ UPROPERTY(EditDefaultsOnly)
345
+ TObjectPtr<UEnvQuery> CoverQuery;
346
+
347
+ void AMyAIController::FindCover()
348
+ {
349
+ FEnvQueryRequest Request(CoverQuery, this);
350
+ // Optional named float params (set via DataProvider in the asset):
351
+ // Request.SetFloatParam(TEXT("SearchRadius"), 1200.f);
352
+
353
+ Request.Execute(EEnvQueryRunMode::SingleResult,
354
+ FQueryFinishedSignature::CreateUObject(
355
+ this, &AMyAIController::OnCoverQueryDone));
356
+ }
357
+
358
+ void AMyAIController::OnCoverQueryDone(TSharedPtr<FEnvQueryResult> Result)
359
+ {
360
+ if (!Result.IsValid() || !Result->IsSuccessful()) { return; }
361
+
362
+ // Location result
363
+ FVector Location = Result->GetItemAsLocation(0);
364
+ GetBlackboardComponent()->SetValueAsVector(TEXT("CoverLocation"), Location);
365
+
366
+ // Actor result (if generator produces actors)
367
+ // AActor* Actor = Result->GetItemAsActor(0);
368
+
369
+ // Multiple results (when RunMode = AllMatching)
370
+ // for (int32 i = 0; i < Result->Items.Num(); ++i)
371
+ // {
372
+ // FVector Loc = Result->GetItemAsLocation(i);
373
+ // float Score = Result->Items[i].Score;
374
+ // }
375
+ }
376
+ ```
377
+
378
+ ### Via BT Task (BTTask_RunEQSQuery)
379
+
380
+ Configure in-editor:
381
+ 1. Add `BTTask_RunEQSQuery` node to Behavior Tree
382
+ 2. Set `EQSRequest.QueryTemplate` = your `UEnvQuery` asset
383
+ 3. Set `BlackboardKey` = target BB key (Vector for locations, Object for actors)
384
+ 4. `EQSRequest.RunMode` = `SingleResult` for most cases
385
+ 5. `bUpdateBBOnFail = false` to avoid clearing BB on failure
386
+
387
+ The task stores `FBTEnvQueryTaskMemory` (containing `RequestID`) in NodeMemory to manage the async query lifecycle and abort correctly.
388
+
389
+ ### Via BT Service (periodic queries)
390
+
391
+ ```cpp
392
+ // BTService_RunEQS — built-in service that runs an EQS query on interval
393
+ // Found in: BehaviorTree/Services/BTService_RunEQS.h
394
+ // Configure: QueryTemplate, BlackboardKey, RunMode, Interval
395
+ // This is equivalent to using a service that calls Request.Execute() in TickNode
396
+ ```
397
+
398
+ ---
399
+
400
+ ## EQS Debugging
401
+
402
+ Enable EQS debug visualization:
403
+
404
+ ```
405
+ Console: ai.debug.eqs 1
406
+ Console: DisplayAll EQS
407
+ Gameplay Debugger: ' key → select AI → press 4 (EQS panel)
408
+ ```
409
+
410
+ In C++, `UEQSTestingPawn` (`EnvironmentQuery/EQSTestingPawn.h`) can be placed in the level to preview query results in-editor without running the game.
411
+
412
+ ---
413
+
414
+ ## Performance Notes
415
+
416
+ | Concern | Mitigation |
417
+ |---------|-----------|
418
+ | Large grid (many candidates) | Reduce `GridHalfSize` or increase `SpaceBetween`. Use `SingleResult` mode. |
419
+ | Frequent queries | Use BT Service with `Interval >= 0.5s`. Cache result in BB rather than re-running each tick. |
420
+ | Expensive Trace tests | Limit trace count via early filter tests before trace (e.g., distance filter first). |
421
+ | PathfindingLength test | Avoid on every frame; path queries are CPU-intensive. Run at 1-2s intervals max. |
422
+ | Many concurrent AI | Use `UEnvQueryManager`'s built-in query throttling (max parallel queries per frame set in Project Settings > AI > EQS). |
423
+ | AllMatching mode | Only use when you need a ranked list; `SingleResult` is significantly cheaper. |