Skip to content

14. Tropes

EBNF
trope = trope_header ":" trope_body .
trope_header = "trope" identifier .
trope_body = (* unordered; roles required, conditions optional *)
trope_roles
[ trope_conditions ] .
trope_roles = "roles" ":" role+ .
trope_conditions = "conditions" ":" statements .

A trope definition, or just trope, describes a relational pattern among entities and symbols that can be tested at runtime. Tropes are named with an identifier, and each trope in a content bundle must have a unique name.

EBNF
trope_header = "trope" identifier .

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

trope rivalry:
...
EBNF
trope_roles = "roles" ":" role+ .

The roles field specifies one or more role definitions that parameterize the trope. This field is required.

trope rivalry:
roles:
@hero:
as: character
@villain:
as: character
...
EBNF
trope_conditions = "conditions" ":" statements .

The optional conditions field specifies a block of statements that must all evaluate to truthy values for the trope to be considered a match (a fit):

trope rivalry:
roles:
@hero:
as: character
@villain:
as: character
conditions:
@hero.opinion[@villain] < -50
@villain.opinion[@hero] < -50

A trope can be tested at runtime using a trope fit expression (see Expressions). The expression evaluates to a boolean indicating whether the trope’s conditions hold for a given set of bindings:

// Standard form
fit trope rivalry:
with:
@hero: @person1
@villain: @person2
// Sugared form
<@person1, @person2> fits trope rivalry

For full details on trope fit syntax, see Expressions.