reckfellENGINE

Text-to-speech: voices and queue

Select a voice safely with empty lists and manage speech requests.

On this page

Text-to-speech uses available system voices. The list can be empty and a saved voice ID can disappear after system changes. Never access voices[0] without checking length.

Preparation

Enable project setting audio/general/text_to_speech for startup initialization. Keep a separate user narration preference: the project flag does not replace deliberate control over what is spoken and when. DisplayServer.HasFeature(DisplayServer.Feature.TextToSpeech) checks backend capability, not language availability.

Complete handler with a no-voice fallback

Attach this script to an Entity and enable SpeechEnabled according to user preference. Call TryAnnounce() for meaningful UI changes rather than every frame.

C#
using System;
using Reckfell;

public partial class SpeechNarrator : Entity
{
    [Export] public bool SpeechEnabled { get; set; }
    [Export] public string Language { get; set; } = "en";
    public string PreferredVoice { get; set; } = "";

    public static string? ChooseVoice(string[] voices, string preferred)
    {
        if (Array.IndexOf(voices, preferred) >= 0) return preferred;
        return voices.Length > 0 ? voices[0] : null;
    }
    public bool TryAnnounce(string text)
    {
        if (!SpeechEnabled || string.IsNullOrWhiteSpace(text) ||
            !DisplayServer.HasFeature(DisplayServer.Feature.TextToSpeech)) return false;
        string? voice = ChooseVoice(DisplayServer.TtsGetVoicesForLanguage(Language), PreferredVoice);
        if (voice is null) return false;
        DisplayServer.TtsSpeak(text, voice, volume: 50, pitch: 1, rate: 1, utteranceId: 0L, interrupt: false);
        return true; // Queued request, not speech-completion acknowledgement.
    }
}

ChooseVoice() prefers the saved ID, then the first available voice for the chosen language; an empty list returns null. Show the actual selected voice in UI and allow changes. Refresh the list after system-service or voice changes.

Language goes to TtsGetVoicesForLanguage(). Native filtering tests the beginning of the language string, so a site locale code is not automatically a valid voice selector. Store text locale, selected voice, and user speech settings separately.

Queue and completion

TtsSpeak() submits a request and returns immediately. The example's true means submission, not playback completion or correct pronunciation. Do not infer duration from string length.

By default the example queues without interruption. interrupt=true interrupts current speech for the new message; TtsStop() stops the shared queue. Coordinate multiple speaking screens through one service. Do not issue a global stop whenever an arbitrary object closes.

Track start/end using TtsSetUtteranceCallback() with utteranceId, not a fixed timer. Cancellation and failure are separate outcomes. This example did not test those callbacks or audible playback.

Useful UI behavior

Speak meaningful text without markup or technical IDs. Do not repeat an entire description on every pointer movement. Offer voice, rate, volume, and narration-disable settings. Retain visible text when speech is enabled.

TtsSpeak() alone does not add labels, focus order, or UI semantics for accessibility tools. Configure those separately; TTS support does not prove the entire application's accessibility.

Diagnose silence

Check user preference, nonblank text, backend support, language voice list, and the actual selected ID. If none are available, retain a working text UI and offer voice setup. Do not publish one package-installation command for every system: availability depends on target OS configuration.

Checks cover opt-out, blank text, empty lists, preferred/stale IDs, headless fallback, and Windows voice enumeration without speaking. Loudness, pronunciation, phrase completion/cancellation, OS accessibility integration, and exports were not tested.

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.