Skip to content

15. Queries

EBNF
query = query_header ":" query_body .
query_header = "query" identifier .
query_body = (* unordered, each field optional *)
[ query_roles ] [ query_conditions ]
[ query_action_name ] [ query_ancestors ] [ query_descendants ]
[ query_importance ] [ query_tags ] [ query_salience ]
[ query_associations ] [ query_location ] [ query_time ]
[ query_initiator ] [ query_partners ] [ query_recipients ]
[ query_bystanders ] [ query_active ] [ query_present ] .

A query definition, or just query, specifies a pattern for searching over recorded action instances—either in a character’s memories or in the global chronicle. Queries are named with an identifier, and each query in a content bundle must have a unique name.

Queries are invoked at runtime via action search expressions.

EBNF
query_header = "query" identifier .

The query header is introduced by the query keyword, followed by the query’s name:

query recent-betrayals:
...
EBNF
query_roles = "roles" ":" role+ .

The optional roles field specifies one or more role definitions that parameterize the query. A query may have zero roles, in which case the field is omitted:

query acts-against:
roles:
@perpetrator:
as: character
@victim:
as: character
...
EBNF
query_conditions = "conditions" ":" statements .

The optional conditions field specifies a block of statements that must evaluate to truthy values for a match:

query acts-against:
conditions:
@perpetrator.opinion[@victim] < -30
...
EBNF
query_action_name = "action" ":" set_predicate_tags+ .

The action-name field constrains matches by the name of the recorded action, using one or more set predicates over tags:

query violent-acts:
action:
any: attack, murder, assault
...
EBNF
query_ancestors = "ancestors" ":" set_predicate+ .

The ancestors field constrains matches by their causal ancestors—the prior action instances that caused them, directly or transitively—using one or more set predicates:

query revenge-acts:
ancestors:
any: @original_offense
...
EBNF
query_descendants = "descendants" ":" set_predicate+ .

The descendants field constrains matches by their causal descendants—the subsequent action instances they caused, directly or transitively—using one or more set predicates.

EBNF
query_importance = "importance" ":" query_numeric_criteria .
query_numeric_criteria = query_numeric_criterion+ .
query_numeric_criterion = query_numeric_criterion_operator ":" ( enum | number ) .
query_numeric_criterion_operator = "==" | "<=" | ">=" | "<" | ">" .

The importance field constrains matches by their importance value using one or more numeric criteria:

query major-events:
importance:
>=: #HIGH
...
EBNF
query_tags = "tags" ":" set_predicate_tags+ .

The tags field constrains matches by their tags, using one or more set predicates over tags:

query social-acts:
tags:
any: social, romantic
...
EBNF
query_salience = "salience" ":" query_numeric_criteria .

The salience field constrains matches by their salience value as held by the searching character, using one or more numeric criteria. This field is only valid when searching over a character’s memories; if the query is executed with the chronicle as the search domain, an error will be thrown.

EBNF
query_associations = "associations" ":" set_predicate_tags+ .

The associations field constrains matches by their associations as held by the searching character, using one or more set predicates over tags. Like salience, this field is only valid when searching over character memories.

EBNF
query_location = "location" ":" set_predicate+ .

The location field constrains matches by the location at which the action was performed, using one or more set predicates.

EBNF
query_time = "time" ":" temporal_constraint+ .

The time field constrains matches by the time at which the action was performed, using one or more temporal constraints. A query may have at most one time-frame constraint and at most one time-of-day constraint.

A query may constrain matches by the entities that were cast in particular roles. Each role-based filter uses one or more set predicates.

EBNF
query_initiator = "initiator" ":" set_predicate+ .
query_partners = "partners" ":" set_predicate+ .
query_recipients = "recipients" ":" set_predicate+ .
query_bystanders = "bystanders" ":" set_predicate+ .
query_active = "active" ":" set_predicate+ .
query_present = "present" ":" set_predicate+ .
FieldConstrains by
initiatorThe entity that initiated the action
partnersThe entities that partnered in the action
recipientsThe entities that received the action
bystandersThe entities that witnessed the action
activeThe entities that were actively involved (initiator, partners, recipients)
presentAll entities that were present (active participants and bystanders)
query acts-by-person:
roles:
@person:
as: character
initiator:
any: @person
time:
after: 1 week ago
EBNF
set_predicate = set_predicate_operator ":" expression { "," expression } .
set_predicate_operator = "none" | "any" | "all" | "exactly" .

A set predicate tests a relationship between a set of actual values and a set of specified values. There are four operators:

OperatorMeaning
noneNone of the specified values appear in the actual set.
anyAt least one of the specified values appears in the actual set.
allAll of the specified values appear in the actual set.
exactlyThe actual set contains exactly the specified values, and no others.

Each operator is followed by a colon and one or more comma-separated expressions:

location:
any: @tavern, @marketplace
none: @dungeon

When multiple set predicates appear in a single field, all must be satisfied.

For singular-value fields (location and initiator), the all operator is not permitted—use exactly instead. Additionally, if exactly is used in a field, it MUST be the only set predicate in that field.

EBNF
set_predicate_tags = set_predicate_operator ":" tag { "," tag } .

Some fields (action name, tags, associations) use a variant of set predicates that operates over tag identifiers rather than general expressions:

tags:
all: social, public
none: violent
EBNF
query_numeric_criteria = query_numeric_criterion+ .
query_numeric_criterion = query_numeric_criterion_operator ":" ( enum | number ) .
query_numeric_criterion_operator = "==" | "<=" | ">=" | "<" | ">" .

A numeric criterion tests a numeric value against a threshold. The operator is one of ==, <=, >=, <, >, and the value is a number or enum:

importance:
>=: 5
<: 10

When multiple numeric criteria appear in a single field, all must be satisfied.