EQS query basics after the first Behavior Tree¶
At a glance
Type: AI concept - System: Environment Query System (EQS) - Use when: an AI needs to choose the best actor/location from the environment using tests and scores - Does not: replace Behavior Trees, Blackboard keys, NavMesh, or server authority - Official docs: Environment Query System, Environment Query Testing Pawn, and Behavior Tree User Guide
The one-minute version¶
- EQS asks the environment a question like "where is the best cover point?" or "which reachable point keeps line of sight?"
- A generator creates candidate items: points, actors, grid cells, or other options.
- A context tells the query what to compare against, such as the querier, player, target actor, or last known location.
- Tests filter or score candidates: distance, trace, pathing, dot, overlap, gameplay tags, and similar checks.
- Behavior Trees often run EQS and store the result in a Blackboard key.
- Do not add EQS to a first enemy until patrol/chase/attack already works and your problem is choosing a better location or target.
What it actually does¶
EQS is a candidate-and-score pipeline:
flowchart LR
Gen[Generator creates candidates] --> Tests[Tests filter and score]
Ctx[Contexts provide reference points/actors] --> Tests
Tests --> Result[Best item / result set]
Result --> BB[Blackboard key]
BB --> BT[Behavior Tree branch]
A simplified cover query:
pseudocode of EQS behavior - not engine source
Candidates = generate points in a grid around the AI
for each Candidate:
if Candidate is not reachable:
discard it
if trace from player to Candidate is clear:
score lower or discard it
score by distance to player
score by distance to AI
return highest-scored Candidate
The query does not move the pawn. It returns data. A Behavior Tree task or Blueprint then uses that result, often by setting a Blackboard vector/actor and running a Move To task.
When it fails (and what failure looks like)¶
Common causes:
- No candidates were generated. Generator radius, context, or item type is wrong.
- All candidates were filtered out. Tests are too strict or the NavMesh does not support the query.
- The context points at the wrong actor. A player context that returns
Nonemakes distance/trace tests meaningless. - The query is too dense or frequent. Large grids and expensive traces can become a performance problem if run often.
- The result type does not match the Blackboard key. A vector result will not correctly fill an actor key.
- The Behavior Tree ignores the result. EQS succeeded, but no Move To, decorator, or task uses the Blackboard key.
- Debugging is invisible. Without the EQS Testing Pawn or debugger view, you are guessing at which item won.
Failure can look like no result, a failed task, a stale Blackboard value, or an AI moving to a technically valid but bad-looking point. Visualize the query before changing tests blindly.
The pattern everyone actually uses¶
After a first chase works:
AI sees player
-> Blackboard TargetActor = player
-> Behavior Tree enters ranged-combat branch
-> Run EQS Query: FindFiringPosition
-> store result in Blackboard FiringLocation
-> Move To FiringLocation
-> attack when in range/line of sight
For simple patrol, stay simpler:
Patrol
-> authored patrol points or Get Random Reachable Point in Radius
-> Move To
Use EQS when the choice needs multiple tests:
Find cover
-> candidates around AI
-> must be reachable
-> should block line of sight from target
-> should not be too close to target
-> prefer closer-to-AI options
Debug it with the testing pawn¶
The EQS Testing Pawn lets you place a query in the editor and see colored candidate points. It answers questions prints cannot:
- were any candidates generated,
- which candidates failed a Boolean/filter test,
- which item scored highest,
- whether the context actor is where you think it is,
- whether path/trace tests are rejecting everything.
If a Behavior Tree EQS task fails, test the query asset by itself before rewriting the tree.
Lookalikes - which one do I want?¶
| Tool | Returns / changes | Use when |
|---|---|---|
| Get Random Reachable Point in Radius | One random reachable point + success bool | Wander/patrol only needs a usable random destination. |
| Target Points | Authored locations | Patrol should follow designed points. |
| EQS Query | Filtered/scored location or actor | AI needs to choose a good point/target from many candidates. |
| Behavior Tree | Executes decision branches over time | AI needs ongoing behavior structure. |
| Blackboard | Shared AI facts | Tasks/services/decorators need to read/write target data. |
| AI Perception / Pawn Sensing | Sensed actors/events | AI needs to detect the player before choosing what to do. |
| Gameplay Debugger / EQS Debugger | Live/query debug evidence | You need to see why the query or tree chose something. |
Rule of thumb: Behavior Tree decides when to ask; EQS answers where/which; Blackboard stores the answer; Move To uses the answer.
Going deeper¶
- Behavior Trees and Blackboards for Blueprint Beginners
- the decision structure EQS usually plugs into.
- Move To Task, Decorators, Services, and Observer Aborts
- using Blackboard results in movement branches.
- Get Random Reachable Point in Radius
- the simpler random-patrol alternative.
- Gameplay Debugger and AI Debugger for Blueprint Beginners
- reading live AI/EQS state.
- Visual Logger, EQS Debugger, and ShowDebug Boundaries
- when live debugger evidence is not enough.
- Official docs: Environment Query System, Environment Query System Quick Start, Environment Query Testing Pawn, and Behavior Trees.
- Engine source (requires engine access - we do not reproduce it here):
EQS query/runtime classes under
Engine/Source/Runtime/AIModule/Private/EnvironmentQuery/; Behavior Tree EQS task behavior inEngine/Source/Runtime/AIModule/Private/BehaviorTree/Tasks/BTTask_RunEQSQuery.cpp.