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.
- package/CHANGELOG.md +37 -0
- package/README.md +104 -55
- package/agents/career/career-strategist.md +88 -0
- package/agents/career/cv-reviewer.md +81 -0
- package/agents/career/hiring-manager.md +68 -0
- package/agents/career/mock-interviewer.md +76 -0
- package/agents/freelance/client-screener.md +84 -0
- package/agents/freelance/discovery-call.md +65 -0
- package/agents/freelance/pipeline-strategist.md +99 -0
- package/agents/freelance/proposal-reviewer.md +82 -0
- package/agents/game/ue-blueprint-specialist.md +125 -0
- package/agents/game/ue-gas-specialist.md +133 -0
- package/agents/game/ue-umg-specialist.md +131 -0
- package/dist/cli.js +57 -13
- package/docs/RELEASE-SETUP.md +1 -1
- package/docs/SKILLS-CATALOG.md +67 -4
- package/docs/USER-GUIDE.md +77 -72
- package/docs/agent-hierarchy.md +21 -1
- package/docs/presentations/build_arcane_deck.py +2 -2
- package/docs/presentations/build_arcane_deck_12.py +2 -2
- package/hooks/detect-unreal.sh +90 -0
- package/package.json +2 -2
- package/profiles/freelance.yaml +43 -0
- package/profiles/job-hunt.yaml +5 -2
- package/profiles/unreal-dev.yaml +97 -0
- package/rules/drafter-reviewer.md +16 -3
- package/rules/freelance-guardrails.md +53 -0
- package/rules/gamedev/unreal-code.md +125 -0
- package/skills/career-registry/SKILL.md +95 -0
- package/skills/career-registry/scripts/career_registry.py +488 -0
- package/skills/client-screen/SKILL.md +83 -0
- package/skills/client-screen/references/red-flags.md +95 -0
- package/skills/cover-letter/SKILL.md +4 -3
- package/skills/cv-tailor/SKILL.md +11 -2
- package/skills/freelance-deliver/SKILL.md +90 -0
- package/skills/freelance-hunt/SKILL.md +126 -0
- package/skills/freelance-hunt/references/templates/Connects.md +39 -0
- package/skills/freelance-hunt/references/templates/Contrato.md +60 -0
- package/skills/freelance-hunt/references/templates/Propuesta.md +66 -0
- package/skills/freelance-kickoff/SKILL.md +94 -0
- package/skills/freelance-pipeline/SKILL.md +109 -0
- package/skills/freelance-pipeline/scripts/import_history.py +425 -0
- package/skills/freelance-profile/SKILL.md +93 -0
- package/skills/freelance-proposal/SKILL.md +112 -0
- package/skills/freelance-scan/SKILL.md +196 -0
- package/skills/freelance-scan/references/dedup.md +35 -0
- package/skills/freelance-scan/references/platforms.md +167 -0
- package/skills/freelance-scan/scripts/freelance_search.py +1077 -0
- package/skills/install-mcp/SKILL.md +135 -46
- package/skills/install-mcp/references/unreal-operations.md +55 -0
- package/skills/interview-prep/SKILL.md +11 -3
- package/skills/job-aplicar/SKILL.md +5 -1
- package/skills/job-hunt/SKILL.md +17 -0
- package/skills/job-outcome/SKILL.md +15 -1
- package/skills/job-upskill/SKILL.md +10 -2
- package/skills/ue-actor-component-architecture/SKILL.md +509 -0
- package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
- package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
- package/skills/ue-ai-navigation/SKILL.md +526 -0
- package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
- package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
- package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
- package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
- package/skills/ue-animation-system/SKILL.md +521 -0
- package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
- package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
- package/skills/ue-async-threading/SKILL.md +433 -0
- package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
- package/skills/ue-async-threading/references/threading-patterns.md +345 -0
- package/skills/ue-audio-system/SKILL.md +527 -0
- package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
- package/skills/ue-blueprints/SKILL.md +134 -0
- package/skills/ue-blueprints/references/communication.md +82 -0
- package/skills/ue-character-movement/SKILL.md +475 -0
- package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
- package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
- package/skills/ue-cpp-foundations/SKILL.md +533 -0
- package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
- package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
- package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
- package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
- package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
- package/skills/ue-data-assets-tables/SKILL.md +527 -0
- package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
- package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
- package/skills/ue-editor-tools/SKILL.md +523 -0
- package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
- package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
- package/skills/ue-game-features/SKILL.md +477 -0
- package/skills/ue-game-features/references/experience-system.md +222 -0
- package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
- package/skills/ue-gameplay-abilities/SKILL.md +518 -0
- package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
- package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
- package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
- package/skills/ue-gameplay-framework/SKILL.md +466 -0
- package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
- package/skills/ue-input-system/SKILL.md +394 -0
- package/skills/ue-input-system/references/cpp-setup.md +131 -0
- package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
- package/skills/ue-input-system/references/input-action-reference.md +731 -0
- package/skills/ue-mass-entity/SKILL.md +476 -0
- package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
- package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
- package/skills/ue-materials-rendering/SKILL.md +526 -0
- package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
- package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
- package/skills/ue-module-build-system/SKILL.md +487 -0
- package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
- package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
- package/skills/ue-naming-conventions/SKILL.md +142 -0
- package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
- package/skills/ue-naming-conventions/references/content-structure.md +83 -0
- package/skills/ue-networking-replication/SKILL.md +452 -0
- package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
- package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
- package/skills/ue-niagara-effects/SKILL.md +531 -0
- package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
- package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
- package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
- package/skills/ue-packaging/SKILL.md +116 -0
- package/skills/ue-physics-collision/SKILL.md +423 -0
- package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
- package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
- package/skills/ue-procedural-generation/SKILL.md +505 -0
- package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
- package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
- package/skills/ue-project-context/SKILL.md +305 -0
- package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
- package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
- package/skills/ue-serialization-savegames/SKILL.md +524 -0
- package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
- package/skills/ue-state-trees/SKILL.md +489 -0
- package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
- package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
- package/skills/ue-testing-debugging/SKILL.md +520 -0
- package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
- package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
- package/skills/ue-ui-umg-slate/SKILL.md +431 -0
- package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
- package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
- package/skills/ue-world-level-streaming/SKILL.md +518 -0
- package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
- 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. |
|