Studio

FolioTier 1

say

Attribute a dialogue line to a named character.

say puts a line of dialogue on screen and attributes it to a named speaker. You reach for it whenever a character in your scene speaks - it is the primary tool for carrying conversation forward and the construct your script will use most.

The choice between a cast handle and a quoted name is a maintenance decision, not a style one. Use a cast handle for any recurring character so that a rename in your cast sheet propagates automatically everywhere that character speaks. Reserve the quoted form for incidental voices that genuinely do not belong in your cast, such as an unnamed bystander or a background announcement.

Each say is one beat of dialogue. You cannot split a single character's speech across continuation lines - start a fresh say for each new line of text instead, as shown in the canonical example above.

If you want words on screen with no speaker at all, that is the job of narrate, not say with an empty string. Mixing them up leaves an empty namebox visible rather than hiding it entirely.

The optional color on a quoted speaker applies only to the namebox for that individual line. It does not carry forward to other say statements using the same quoted name elsewhere in the script, so if you find yourself repeating the same name and color, that character probably belongs in the cast.

Parameters

ParameterKindRequiredDefaultNotes
characterstringyes-The speaker. A bare cast handle (`say vee:`) references a cast member by a stable id and is rename-safe - renaming the character never touches the line. A quoted name (`say "Guard":`) is a one-off custom speaker that is not in the cast, optionally followed by a `#rrggbb` namebox color (`say "Guard" #8899ff:`). The colon separator is required. For a line with no speaker, use `narrate` instead.
textstringyes-The dialogue line. Supports text-tag grammar (see Effects → text-tags). Each `say` is one logical line - implicit string continuation across indentation changes inside a label body is not supported.

Canonical example

Folio
say "Emma": "I missed you."
say "Emma": "How long has it been?"
Ren'Py
e "I missed you."
e "How long has it been?"

The Folio shape mirrors Ren'Py's character-attributed dialogue line verbatim: a Character reference followed by a quoted string. The importer's deterministic pass handles every variation of the Ren'Py shape - short-form character aliases (e "..."), interpolation ("Hello, [player_name]"), and the inline what-extension (e "Hello," (what="…")) - so creators rarely need to think about the lowering.

Notes

say is the most-used construct across the Ren'Py corpus by an order of magnitude - it appears thousands of times in a typical full-size game. It carries the burden of getting style right - text-tag grammar ({b}, {i}, {color}, {wave}, {vibrate}), voice-line auto-attachment, and per-character text styling all hang off this verb.

The speaker is either a bare cast handle (say vee:), which points at a cast member by a stable id and survives a rename, or a quoted one-off name (say "Guard":) with an optional #rrggbb namebox color. The importer translates Ren'Py character aliases into display names by reading the Character() definition.

A line without a leading character identifier is not a say - it's a narrate. The two are deliberately separate so the importer, the runtime, and the node editor can render narrator lines with their own visual treatment (no namebox, full-width text). When in doubt, write narrate "…" rather than say "…".

See also

  • narrate - narrator lines without a character attribution
  • characters - defining the characters this verb references
  • text-tags - inline formatting grammar