Sharpee
Chord / Behavior / Topic tables

Topic tables

Conversation is a declared table per person: one define topics for <person> … end topics block serving both ASK and TELL. Entity rows (about the silver locket:) resolve like any noun and are checked first. Quoted rows declare a topic plus comma-separated aliases. Each alias is matched by normalized whole-topic equality, which is a direct lookup and never a fuzzy guess. A row's body is ordinary statements (it binds the owner), so a conversation can change state anywhere in the world. A miss falls to the owner's plain on the player asking catch-all if it has one; on a hit the row fully owns the response. Overlaps are compile errors, never runtime tie-breaks.

define topics for tobias
  about the silver locket: phrase tobias-locket-reply
  about "the folly", "the fire":
    change tobias to shaken
    phrase tobias-folly-reply
end topics

A row can also be gated on how recently a topic came up — see Topic recency, which extends this same define topics block, and Characters & Conversation for the wider dialogue layers built on it.

A readable thing can carry a topic table too, and then consult <thing> about <topic>, look up <topic> in <thing> and read about <topic> in <thing> answer from its rows, matched the same way. With no matching row the player finds "nothing about that" in it, and a thing that is not readable is not something to look things up in. A book has no memory of being asked, so its table is plain about rows: exchanges, threads and knows gating are for people, and an error names the line that uses one.

create the flight manual
  a thing, readable with text "UPPS COURIER FLIGHT MANUAL, REV. 9"
  in the Cockpit
  aka manual

define topics for the flight manual
  about "the fold", "the fold drive", "folding": phrase manual-fold
  about "the airlock", "the outer hatch": phrase manual-airlock
end topics

on the player consulting in the source's block is consulted first, as on the player asking is for a person.