Copyright © 2025-2026 Candy ArtsVoice
Spoken Lines can be voiced, in every Dialogue Mode: a Line plays a pre-recorded voice file, or the output of Text-To-Speech (see TTS).
Everything on this page applies to all Dialogue Modes. Voice mode is the one mode that plays the voice alone, without displaying any text.
Who Speaks the Line
Voices are played by Voice Players (see Voice Players). Which one plays a Line's voice depends on where the Line is displayed:
- Dialogue Box, Subtitles and Chat: the Voice Player of that UI Element (its voice_node).
- Speech and bark bubbles: the bubble's own Voice Player, an AudioStreamPlayer2D or AudioStreamPlayer3D, so the voice is heard from the bubble's position.
- Voice mode: the standalone Voice Player, at voice_player_path in the Engine's ui_elements_paths.
- A file name (e.g. hello or hello.ogg): the Engine searches the voice folders for the file, as explained below.
- A full res:// or user:// path: the file is loaded from that path, and the voice folders are ignored.
- A CandyRef expression (
¢...) that evaluates to either of the above.
| Setting | Purpose |
| voice_folder | The root folder of every voice file. By default: res://Candy_DE/Media/Actors/Voices/ |
| voice_logic | The method that locates the file. Currently, the only method is "Folder". |
| voice_path | The folders between voice_folder and the file. By default: "{actor}/{dialogue}/{conversation}/{block}" |
| Tag | Replaced by |
{actor} | The speaker's Actor Reference. |
{dialogue} | The name of the dialogue file, as passed to load_scripted_dialogue(). |
{conversation} | The name of the Conversation the Line is in. |
{block} | The name of the Block the Line is in. |
{line} | The number of the Line in its Block, counting from 0. A Line nested inside another Line, such as the Lines of a choice, receives the number of the Line that contains it. |
"{actor}/{conversation}_{block}"). A tag with no value leaves out its folder. An unknown tag, or an unknown voice_logic, is reported once in the Output when the game starts.
For example, with the default voice_path, a Line spoken by Alice, in the Meeting Conversation and Start Block of the Intro dialogue file, with the Voice field hello, plays:
res://Candy_DE/Media/Actors/Voices/Alice/Intro/Meeting/Start/hello.ogg
Edit voice_path to fit the way your own voice files are organized: "{actor}", for example, places every file of an Actor in a single folder.
{dialogue} is the file name passed to load_scripted_dialogue(). To run a Dialogue another way (see Exporting Dialogues), set the Engine's running_dialogue_file yourself, or leave {dialogue} out of voice_path.
Languages and Variations
A Line with several Variations (translations included) requires a voice file for each one. The voice file of every Variation other than "Default" is in a folder of its own, named exactly like the Variation, inside the Line's voice folder, under the same file name.
Using the example above, the French translation of the Line plays:
res://Candy_DE/Media/Actors/Voices/Alice/Intro/Meeting/Start/French/hello.ogg
This also applies to full paths: for the Voice field res://My_Voices/hello.ogg, the French Variation plays res://My_Voices/French/hello.ogg.
When a Variation's voice file doesn't exist, the Line is displayed without voice. To play another language's file instead, set voice_fallback_language in Candy_Properties.gd to that language, or to Default for the original language. In the example above, with Default, the French Line plays res://Candy_DE/Media/Actors/Voices/Alice/Intro/Meeting/Start/hello.ogg until French/hello.ogg is added.
A tagged Variation falls back to the Variation of the fallback language with the same tags, when its file exists, and to the untagged one otherwise: French_S=F falls back to Default_S=F, then to Default. If the fallback language's file doesn't exist either, the Line is displayed without voice.
Voice Language
Voice files follow the language of the text by default. In a game where players choose the voice language separately, such as Japanese voices with French text, set voice_language in Candy_Properties.gd to the language of the voice files, or to Default for the original language. An empty value follows the text.
The Variation chosen for the text keeps its tags, and its voice file is looked up in the voice language: with French text and Japanese voices, the Variation French_S=F plays the file of the Japanese_S=F folder. Each Engine's voice_language overrides the project's, and the Engine_Language command can change it during a Dialogue.
Once voice_language is set, the voice no longer follows changes to the text's language: changing language changes the text only. To make the voice follow the text again, such as when players choose "same as text" in an options menu, set voice_language back to an empty value.
File Extensions
A voice file named without an extension receives the default voice extension: default_voice_extension (.ogg by default).
It's set in Candy_Properties.gd, and can be overridden by the Engine, by the Voice Player speaking the Line, and by a config.txt in the voice file's folder (see Media Files). A file named with its own extension is loaded with that extension.
Voice Files and Text-To-Speech
When Text-To-Speech is enabled for a Line (text_to_speech), it takes precedence: the Line's text is passed to the tts() hook function (Tts.gd), and the audio it returns is played.
If Text-To-Speech returns nothing usable, the Line's voice file is played instead. Both can therefore be mixed: recorded voices for the main characters, for example, and Text-To-Speech for everyone else.
See TTS for details.
Playback
The voice starts with the Line, and stops when the Line ends, once the Dialogue advances. A voice still playing when the player advances is cut off.
Waiting for the voice
The Engine's await_voice_playback setting, under the Writing category, prevents the Dialogue from advancing until the voice has finished playing. See Dialogue Advance.
Synchronizing the text
The Engine's sync_write_speed_voice setting, under the Writing category, adjusts the writing speed so that the text finishes writing at the same time as the voice. See Typewriter Effect.
Both settings can be overridden by the UI Elements that display speech, by Actor properties (AwaitVoicePlayback, SyncWriteSpeedVoice) and Spoken Line data (Await_Voice_Playback, Sync_Write_Speed_Voice).
Suspending Dialogues
When a Dialogue is suspended, its voice is paused, and resumes with the Dialogue.
To leave the voice playing, disable the Engine's suspend_voice setting, under the Suspend Dialogue category, or add "Voice" to its media_suspend_immune array. See Suspending Dialogues.
Audio Bus
Assign every Voice Player the audio bus of your voices (a Voice bus, for example), through the node's bus property, so that players can adjust the voice volume separately from the music and the sound effects.
Hook Functions
Each Voice Player calls x_playback_starting() immediately before a voice starts, and x_playback_started() immediately after, whether it plays a voice file or Text-To-Speech. See Voice Players.