Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.



This feature is still in beta and subject to constant change.  We encourage you to use it in test projects and provide your feedback to us.

However, DO NOT use it in production where it creates dependencies!  Always back up your projects to make sure that you can go back to a previous version. 


The Universal Query System (UQS) is a system for undertaking spatial queries in a 3D world.


Table of Contents


In the TPS, queries are geared around so-called 'tactical points' which are basically positions in the world that are specific to the CryAISystem's object model.


  • Support for feeding in parameter values into queries at run-time, rather than being restricted to hard-coded values at design-time only.

  • Allows for custom names for query parameters so that you can better describe the context that the query is intend to resolve, for example:
    • Currently 'puppet' is hardcoded to mean 'the thing that requested the query'.
    • Better/more suggestive names might be: 'querier', 'attacker', 'hostiles', 'observers', etc.

  • Improved debugging (and logging), for example:
    • Which conditions were true/false.
    • How total scoring values were constructed.
    • Which sorting rules were applied.

  • Visual history of queries:
    • Items can be visualized using built-in debug rendering facilities.
    • Individual items can be inspected to better understand how their score was constructed.
    • The whole history can be persisted and restored for inspection outside of the running game.

  • Custom 'post-validation' for when a query has been completed, for example:
    • The NavMesh might have changed while the query took a couple of frames to complete, so now you want to make sure that the query result is still 'valid'.

  • Fallback queries:
    • Allows to create alternative queries with perhaps less restrictions, should the 'primary' query not find any items.

  • Query chaining:
    • Use the outcome of one query as parameters for another query.

  • Fully extendable on the game side:
    • Custom item types
    • Custom generators
    • Custom functions
    • Custom evaluators

Core Parts of a Query

There are 4 main parts that comprise a query:


DeferredEvaluators are free to run over time and return their outcome once they have finished processing the item. Whether they do time-sliced work or offload the actual work to a different system is up to them. From the query's point of view, it's only relevant that they are periodically updated until they come up with a result. A typical use case would be to start an asynchronous physics raycast between 2 points and wait until the raycast request has been fulfilled.

Scoring of Items

As mentioned above, evaluators are responsible for scoring an item. Generally speaking, each evaluator in a query will be asked to evaluate each generated item. Their scores will then be added together to form the overall score of that item. To allow a little more control over the individual scoring by a single evaluator, each evaluator comes with a weight that the score will be multiplied by before its added to the overall score.

The overall score of an item will be used to work out what the best 'N' items are to return in the final result set of a query.

Technical Information

For more technical information on how to work with these features, then see the following pages:

Children Display

New Features in CRYENGINE 5.4

  • Added concept of GUIDs to all UQS elements to prevent relying on their names.
  • Added concept of Parameter IDs to Generator's parameters, Functions and Evaluators to no longer rely on their names.
  • Added support for providing descriptions to all UQS elements from within the code to reflect in the UI.
  • Added helper classes that makes running a query easier from within the code: UQS::Client::CQueryHostUQS::Client::CQueryHostT<>.
  • Added concept of Evaluation result transforms to manipulate the outcome of a single item. This can be achieved via a score function and discard negation.
  • Added a helper class for easier setup of the UQS when using the XML data source: UQS::DataSource_XML::CXMLDataSource.
  • Added preliminary Schematyc support to allow running queries from within Schematyc.
  • Query Editor: added tool tips for most elements that originate from the descriptions provided by the programmer.
  • Query History Inspector: double-clicking on a historic query now "teleports" the Editor camera to a close-by position.

Breaking Changes in 5.4

Namespaces and Variable Names in C++ Code Have Been Adjusted to Better Match the Coding Conventions

Old namespaces:

  • uqs
    • client
      • internal
    • core
    • datasource
    • datasource_xml
    • editor
    • shared
    • stdlib
    • uqseditor


  • UQS
    • Client
      • Internal
    • Core
    • DataSource
    • DataSource_XML
    • Editor
    • Shared
    • StdLib
    • UQSEditor

GUIDs and Coder-defined Comments

Due to the introduction of GUIDs and coder-defined comments in all of the UQS elements, then the way how factories for generators, functions, evaluators, etc. get registered has changed. Before, it was mainly about creating a global instance of that factory with a list of parameters as constructor arguments. Now all the parameters get bundled in a struct.


Code Block
static const UQS::Client::CGeneratorFactory<CGenerator_PointsOnPureGrid> generatorFactory_PointsOnPureGrid(
        UQS::Client::CGeneratorFactory<CGenerator_PointsOnPureGrid>::SCtorParams ctorParams;

        ctorParams.szName = "std::PointsOnPureGrid";
        ctorParams.guid = "498bce51-a2b9-4e77-b0f9-e127e8a5cc72"_uqs_guid;
        ctorParams.szDescription =
            "Generates points on a grid.\n"
            "The grid is specified by a center, size (of one edge) and a spacing between the points.\n"
            "Notice: this generator is very limited and doesn't work well if you intend to use it for things like uneven terrain.";

        return ctorParams;

UQS Standard Library

  • The data type Vec3 has been replaced by Pos3Ofs3 and Dir3. Functions, generators and evaluators using the old data type have been adjusted accordingly.
  • The function std::Vec3 Vec3Add ( std::Vec3 v1, std::Vec3 v2 ) has been superseded by std::Pos3 Pos3AddOfs3 ( std::Pos3 pos, std::Ofs3 ofs ).