Skip to main content
Version: Next (dev)

AI EQS Query

An Environment Query System (EQS) query generates candidate positions, filters unsuitable ones, scores the survivors, and returns one or more results. Use it to find cover, a flanking position, a spawn point, or a smart-object slot.

Author a query

Create an AI EQS Query asset from the Asset Browser and open it.

  1. Choose NavmeshConfig and PathSearchConfig.
  2. Select a Generator and configure its center context and radius.
  3. Add named Contexts for information such as the threat position.
  4. Use + Add Test to add filters and scoring rules. Put cheap filters before expensive line-of-sight or path-length tests.
  5. Choose a run mode and limits, then inspect the Query Preview.
  6. Validate in a simulating scene with AI EQS Query Test.

Generators

GeneratorCandidates
RingDistributed ring samples projected onto the navmesh.
GridA grid projected onto the navmesh; spacing can increase to fit the candidate budget.
NavmeshRandomRandom navmesh positions around the center.
CoverPointsGenerated or authored cover points in range.
SmartObjectsAvailable interaction slots, optionally filtered by Type.

The base generator settings include CenterContext, RadiusMin, RadiusMax, and VerticalRange. Keep the vertical range narrow enough to avoid selecting a different floor unintentionally.

Contexts

A context answers “relative to which object or position?” The implicit Querier context is always available. Additional named slots can use:

  • Querier: another name for the asking object.
  • Perceived Target: the AI agent's last-known target position; unavailable without target confidence.
  • Blackboard Vec3 or Blackboard Object: an entry on the querying object's board.
  • Explicit Position: a position provided by the query submitter.

Names must match exactly. A test referring to Threat needs a slot with that name or a submission override. The test component's ThreatSlot and ThreatObjectKey let you supply that position without a perceiving agent.

Tests and scoring

TestPurpose
DistancePrefer a distance band relative to a context.
DirectionPrefer an angle around a context, such as a flank.
CoverQualityRequire or favor a protection level.
CoverFacingCheck whether the wall faces the threat.
UnclaimedReject cover or slots claimed by another object.
LineOfSightPrefer visibility or occlusion, with configurable eye heights.
ReachableApproxApproximate reachability with a navmesh raycast; an indirect route receives a lower score.
PathLengthEvaluate actual path length and reject unreachable candidates.

Each test has a Purpose: Filter Only, Score Only, or Filter And Score. A filtering test discards a candidate at raw score zero, before the response curve is applied. Scoring tests contribute weighted, curved scores to a normalized weighted average.

This differs from behavior considerations, which multiply together. A zero Score Only result lowers an EQS candidate's score without discarding it.

For line of sight against multiple context positions, Min, Max, and Average combine results. With a test that prefers occlusion, Min expresses “hidden from all positions”; Max expresses “hidden from at least one.”

Result settings

  • RunMode = SingleBest: choose the highest-scoring survivor.
  • RandomOfTopPercent: choose randomly from the top percentage, controlled by TopPercent.
  • AllMatching: return survivors ordered by score, up to MaxResults.
  • Candidates: candidate-generation budget.
  • MaxResults: result-count limit.

Query Preview

The editor preview uses a local synthetic layout. Inspect candidate colors, the winner, discarded crosses, and the selected candidate's per-test breakdown. Move the threat or occluder to see how distance, direction, and visibility affect the result.

EQS editor with Cover Facing and Path Length tests, candidate positions, and the winning score breakdown

The star marks the winner; crosses mark filtered candidates. The breakdown shows how the two weighted tests contribute to the displayed 0.38 score. Navmesh tests in this panel are approximations.

The preview approximates navmesh tests and does not validate your level's collision geometry. The current use scene simulation option is disabled. Use the scene component below to test real runtime results.

Test in a scene

  1. Start from a working navmesh path test.
  2. Add AI EQS Query Test (plAiEqsQueryTestComponent) and assign the query asset.
  3. For threat-relative queries, give another object a global key, enter it in ThreatObjectKey, and match ThreatSlot to the query's context name (default Threat).
  4. Simulate. QueryInterval controls repeated runs (default 0.5 s).
  5. Move the test object or threat and watch the returned points. The winner is white; other returned points are colored by score. The winner's per-test breakdown is drawn above it.

The component draws returned results without requiring a CVar. Enable AI.EQS.VisualizeQueries = 1 to inspect the broader candidate/filter visualization, and AI.EQS.VisualizeScores for score debugging.

ClaimBest claims a winning cover point, allowing two test objects to demonstrate claim exclusion. It does not automatically move either test object to the result.

Runtime result states

StateMeaning
PendingStill queued or executing; continue polling.
ReadyAt least one surviving result.
NoResultQuery ran, but no candidate survived.
AreaNotReadyRequired navigation data was requested but is not ready; retry later.
InvalidNo valid query result for that ID.

Query budgets can spread execution over frames. A delayed result is not necessarily a failed query.

Use the result in a behavior

The Ai Run Eqs Query state assigns its best position to TargetEntry (default Ai_TacticalTarget) and status to ResultEntry (default Ai_TacticalResult): 0 = querying, 1 = success, 2 = failure.

Transition on 1 to Ai Navigate To, setting that state's TargetPositionEntry to the same vector entry. Add a retry or fallback branch for 2. Do not start navigation while the query is still pending.

ClaimCover and ClaimSmartObject reserve appropriate result payloads. ClaimTimeout limits the reservation, and ReleaseClaimOnExit controls whether it is released when leaving the query state. Keep a claim while walking toward the position, then release it when the interaction or cover use ends.

Use a query without an AI Agent

AI EQS Query (plAiEqsQueryComponent) runs an asset from its owner's position. AutoRunInterval = 0 runs once at simulation start; a positive interval repeats it. RunQuery() requests another run when one is not already in flight.

Completion sends plMsgAiEqsQueryFinished with Success, BestPosition, BestScore, and BestObject. Use the event's success flag before consuming its position. HasResult() and GetLastResultPosition() retain the last successful result, even if a later run fails.

The component retries AreaNotReady internally instead of reporting that transient state as a completed failure.

See also