Studio

FolioTier 1

characters

How speakers lower into Folio. A cast member is a stable handle (`say emma:`), like a Ren'Py `Character()` variable - rename-safe. A bare quoted name (`say "Storyteller":`, optionally `#color`) is a one-off custom speaker, like a Ren'Py string-speaker line. A bare string with no speaker is `narrate`.

Folio gives you three ways to attach a voice to a line of dialogue. A cast member is a name you define once in your project's cast - when you write say emma:, Folio resolves the display name, color, and portrait from that single definition, so renaming a character later touches one place rather than every line she speaks. A bare quoted name lets you put a speaker on screen without a cast entry, useful for one-off voices, environmental speakers, or anything whose identity matters for only a handful of lines.

Narrate drops the nameplate entirely. It is not a shorthand for a character named Narrator - it signals the structural absence of any speaker, and the engine presents it differently as a result.

The choice between a cast member and a quoted name is a question of reuse and ownership. If a speaker appears more than a handful of times, or if other parts of your script need to reference or react to their identity, define them as a cast member. A quoted name with a color is convenient for a background voice that surfaces once, but that color lives only inside that say line - there is no shared definition to update if your palette changes. Avoid using quoted names as a workaround for cast members you intend to reuse; the short-term convenience becomes maintenance debt once the character recurs.

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.

Cast handle or quoted name

A cast member is referenced by a stable handle - say emma: "..." - which is rename-safe: renaming the character never touches the line. A quoted name (say "Storyteller": "...") is a one-off custom speaker that is not in the cast.

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 once the voice verb ships) 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 presentation work, not character-definition work. The presentation layer exposes one per-character hook today - the namebox can follow the speaker's own colour; a richer styling system may return later, but it isn't part of the v1 surface.

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!" (per-character colour is dropped; the presentation layer renders every character with the default style) | | 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 read-only migration report flags it inline on the affected scene - Folio's flat-namespace model can't carry the collision automatically, so the creator resolves it in the editor (typically by renaming one).

See also

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