Chapter 3

Tags & the ontology

Tags are how a node says what it's like. Last chapter used them freely; this one is about what they are. A tag has a name and a leading sigil, and the sigil marks which facet of a thing the tag describes — for the reader and the engine alike. Five come up constantly.

+propertywhat a thing is — a role, a kind, an attribute. [+Grifter], [+Cursed]
#statehow it is right now — a mutable condition. [#Grieving], [#Wounded]
&verbwhat happens, usually on an evt. [&Betrays(agent=…)]
@relationa bond between nodes. [@Rival_Of(other=…)]
%registeran engine-/world-level modifier. [%Status_Berserk]
char vale [+Grifter] [#Suspicious]
evt the_switch [&Deceives(agent=vale, target=renn)]
char renn [@Rival_Of(other=vale)]

Tags can carry parameters in parentheses — [&Deceives(agent=vale, target=renn)] — which bind roles so recognition can match "who did what to whom." A handful of parameter keys are reserved and meaningful: hidden=true keeps a tag active in the engine but out of what's surfaced to a player (that's how information asymmetry is built), and source, target, and others anchor provenance and intent.

The leading character also carries a dynamic: + plays the trope straight (the default), while - subverts, ? averts, and ! invokes it. These can wait — the grammar reference has the full set; the five facets above are the part to learn first.

imply: one tag, many

Vocabulary in TropeLang is layered. Tags form an ontology, and the connective is imply: declaring that one tag pulls in others. When vale is tagged [+Grifter] and the ontology says a grifter is deceptive and cunning, those component tags come along automatically.

imply Grifter -> [Deceptive, Cunning]
char vale [+Grifter]

This matters more than it looks. Implication is transitive (if grifter implies deceiver, and deceiver implies something else, you get all of it) and it's reference-counted, so removing [+Grifter] only removes the components nothing else still requires. The point is that a story can use rich, specific words — grifter, con artist, sharper — while the engine sees the common structural facts underneath. That shared substrate is exactly what lets a trope match across stories that use completely different surface vocabulary (Chapter 4).

exclusive: mutually exclusive tags

Where imply says tags travel together, exclusive says they can't co-occur. It declares a partition — a named set of tags of which an entity may carry at most one:

exclusive Allegiance -> [Loyalist, Traitor, Neutral]
char mole [+Traitor]

A character has one allegiance, not several. Declaring the partition tells the engine so, and a trailing ! on the name (exclusive Allegiance! -> […]) tightens "at most one" to exactly one. Like imply, it's a vocabulary-level statement, not a fact about any particular entity — the partition name is a label, never asserted on a character.

The point is what it does for recognition. A partition is a constraint: when a trope needs a character to be [+Loyalist] and the story marks that character [+Traitor], that partition sibling doesn't just leave the anchor unmet — it actively refutes it. The engine can then tell "this trope is ruled out" apart from "we haven't seen evidence yet," which is the difference between absence of evidence and evidence of absence (recognition makes that distinction; the planning tools build on it).

A partition earns two more moves. In an exactly-one partition (Allegiance!), eliminating members determines the rest: mark a character [-Loyalist] where only Traitor remains and the engine derives [+Traitor] — the last candidate standing. And a rule can demand resolution by anchoring the partition label itself (when: char $p [+Allegiance!]), matching only once the character is settled on some member — the difference between "we haven't placed them" and "they're placed, whichever way." Both need engine ≥ 0.33.

Taxonomy: specific and general

Where imply pulls in companion tags, taxonomy says one tag is a kind of another. A braced axis after a tag name — [+Warrior{Archetype}] — declares a subsumption edge: a swordsman is a warrior. Recognition then reads the specific tag as the general one, so a story that only ever says [+Swordsman] still satisfies a trope gated on [+Warrior].

concept Archetype
prop Warrior
prop Swordsman [+Warrior{Archetype}]
char kael [+Swordsman]

The direction is is-a, one way: a swordsman counts as a warrior, never the reverse. The axis (Archetype) groups related edges, and a tag can sit under several parents at once — the graph is a DAG, not a tree. The brace is what makes it structural: a plain [+Warrior] stays ordinary annotation, so no vocabulary written before taxonomy landed changes meaning. It is recognition's alone — expanding what a trope will match while staying out of eval and the drams coverage count, where folding in vocabulary structure would only inflate the numbers. Needs engine ≥ 0.32.0.

The prelude

All of this rests on the prelude: the base vocabulary and its implications, computed once and always in scope. It's why [+Protagonist] means something without you defining it, and why two authors who never coordinated still write tags that the same engine understands. The full, living list of what the prelude and corpus define is the vocabulary glossary — generated straight from the core, so it never drifts from the language.