Workflow: Creating and Using Queries
A Query in FactsDB is a powerful concept that allows you to define reusable, data-driven logical checks. Instead of building complex branches of AND
s and OR
s in your Blueprints, you define the logic once in a Query Definition Asset and can then evaluate it anywhere using a single, clean node.
Let's create a query to determine if our player can perform a "special attack". The conditions will be:
- The player's health must be above 25.
- The player must be holding the key.
Step 1: Create a Query Definition Asset
Queries are stored in a dedicated Data Asset. You can have multiple query assets in your project, but it's often convenient to group related queries together.
- In the Content Browser, right-click and go to
Miscellaneous
>Data Asset
. - In the "Pick Data Asset Class" dialog, search for and select
FactsDBQueryDefinition
. - Name the new asset
DA_PlayerQueries
.
Step 2: Define the Query Logic
Open the DA_PlayerQueries
asset. The main editor is a map where each entry represents one query.
-
Click the
+
icon next to Query Definitions to add a new query. -
Key (Query Tag): First, we need a
Gameplay Tag
to identify this query. Create and/or select a tag, for example,Query.Player.CanUseSpecialAttack
. -
Value (Query Logic): This is where we build the logic. By default, it's
None
. We need anAND
block to check both our conditions.- Click the dropdown that says
None
. - Select
AND
.
- Click the dropdown that says
Now we can add our two conditions to the Sub Queries
array inside the AND
block.
Condition 1: Health > 25
-
Click the
+
next toSub Queries
to add the first condition. In the dropdown, selectCondition Evaluator
. -
You will see a single, intuitive row appear, representing the entire condition:
[Left Hand Side] [Operator] [Right Hand Side]
. -
Left Hand Side (LHS): This is the fact you want to check.
- Schema: Select the Schema containing the player's stats, e.g.,
Schema.Player
. - Fact: A dropdown will appear, filtered to facts within that schema. Select
Fact.Player.Stat.Health
. - The
Context Source
should remainTarget
, meaning the query will check the health of whatever object it's being evaluated against.
- Schema: Select the Schema containing the player's stats, e.g.,
-
Operator:
- Because
Health
is a numeric fact (a float), the operator dropdown is automatically populated with relevant comparisons. - Select
> (Greater)
.
- Because
-
Right Hand Side (RHS): This is the value you're comparing against.
- You'll see a choice between Fixed (a literal value) and Runtime (another fact). Select Fixed.
- A numeric input box will appear. Enter
25.0
.
Condition 2: HasKey == true
- Click the
+
next toSub Queries
again and add anotherCondition Evaluator
. - Left Hand Side (LHS):
- Schema:
Schema.Player
- Fact:
Fact.Player.State.HasKey
- Schema:
- Operator:
- Notice that because
HasKey
is a boolean fact, the operator list is now automatically filtered to only== (Equal)
and!= (Not Equal)
. - Leave it as
== (Equal)
.
- Notice that because
- Right Hand Side (RHS):
- Select Fixed.
- Because the LHS is a boolean, a checkbox will appear instead of a number box. Check the box to represent
true
.
Your final query definition should now look clean and readable:
Save the DA_PlayerQueries
asset.
Step 3: Register the Query Asset
Just like with Schemas, the system needs to know where to find your queries.
- Go to
Edit
>Project Settings
>Game
>FactsDB Runtime Settings
. - Find the Query Definition Assets array.
- Click
+
and add ourDA_PlayerQueries
asset to the list.
Step 4: Use the Query in Blueprints
Now, using this complex logic in any Blueprint is incredibly simple.
-
In your player Blueprint (or any other graph), add an Evaluate Query node.
-
Select the node. In the Details panel, under "Query Configuration", set the Query To Evaluate to
Query.Player.CanUseSpecialAttack
. -
Connect the
Context ID
of the object you want to test (in this case, our player character's Context ID). -
The node outputs a single boolean. Connect this to a
Branch
node.
That's it! You have successfully decoupled your gameplay logic from its implementation. If a designer now decides that the "special attack" also requires the player to have full health, they can simply add another condition to the AND
block in DA_PlayerQueries
. No Blueprints need to be changed or recompiled. This is the core power of a data-driven approach.
You can nest queries inside other queries. Instead of adding a Condition
, you can add a Query by Reference. This allows you to build complex logical trees out of smaller, reusable pieces. For example, a Query.Player.CanDoAnything
might be an AND
block that references Query.Player.IsAlive
, Query.Player.IsNotStunned
, etc.
Next Up: Blueprintable Queries