FolioTier 1

characters

How named speakers, narrators, and Ren'Py character aliases lower into Folio.

Reference page — characters aren't a verb. This page collects the rules that govern how say references a speaker and how the importer flattens Ren'Py's character indirection.

Display name is the identifier

Folio has no define e = Character("Emma") step. The character's display name is the only handle — say "Emma": "..." references the character by what the player sees. No short-form alias, no intermediate object, no Python class.

say "Emma": "I missed you."
say "Storyteller": "And so the day began."

Two reasons for the flattening: (a) the node editor and migration report read cleaner when the speaker is the literal name a creator would say out loud, and (b) Folio's import target is the result of a project's character system, not its source — Vizno owns the future, not the round-trip back to Ren'Py.

Narrator

A line without a speaker is narrate, not a say with an empty character. The split keeps the runtime, node editor, and importer honest about whether a line is character speech (namebox, character-coloured text, voice-line auto-attachment in Phase 6) or narration (no namebox, full-width prose).

narrate "The lights faded."

If a creator wants a named narrator — "the storyteller", "the dungeon master" — they write it as a regular character: say "Storyteller": "...". The runtime treats them as a character; the render style distinction stays clean.

Per-character styling

Per-character text styling (colours, fonts, side-of-screen positioning) is theme work, not character-definition work. The theme JSON5 declares named styles; a character picks a style by display name. The styling layer lands in Phase 2; until then, the runtime renders every character with the default theme.

Importer translation

Ren'Py Character() definitions are flattened at import time:

| Ren'Py | Folio | |---|---| | define e = Character("Emma")
e "Hello!" | say "Emma": "Hello!" | | define e = Character("Emma", color="#ff8")
e "Hello!" | say "Emma": "Hello!" (colour migrates to theme JSON5 in Phase 2) | | e "Hello," (what="...") | say "Emma": "Hello," (inline what= extensions normalize to plain text) | | bare "Hello!" | narrate "Hello!" |

If two Ren'Py characters share a display name, the importer flags it in the migration report — Folio's flat-namespace model can't carry the collision automatically, and the author resolves it (typically by renaming one).

See also

  • say — character-attributed dialogue
  • narrate — narrator lines