NarraLeaf

Voice

Pass a URL or a Sound.voice() instance through the line's voice option.

alice.say("Good morning.", {
    voice: "/voice/alice/good-morning.ogg",
});
import { Sound } from "narraleaf-react";

const greeting = Sound.voice({
    src: "/voice/alice/good-morning.ogg",
    volume: 0.9,
});

alice.say("Good morning.", { voice: greeting });

Voice IDs

For larger scripts, define a voice map or resolver on the scene, then reference clips by ID. This keeps file paths out of dialog lines.

const room = new Scene("room", {
    voices: {
        "alice-001": "/voice/alice/001.ogg",
        "alice-002": Sound.voice("/voice/alice/002.ogg"),
    },
});

room.action([
    alice.say("Good morning.", { voiceId: "alice-001" }),
    alice.say("Breakfast is ready.", { voiceId: "alice-002" }),
]);

A resolver is useful when IDs follow a stable file naming rule.

const room = new Scene("room", {
    voices: (id) => `/voice/${id}.ogg`,
});

Per-character volume

voiceVolume governs the whole cast at once. To give the player a control per character, declare a bus for each under voice and put the clip on it:

const game = new Game({
    audioBuses: [
        {id: "alice", parentId: "voice"},
        {id: "bob", parentId: "voice"},
    ],
});

alice.say("Good morning.", {
    voice: Sound.voice({src: "/voice/alice/001.ogg", type: "alice"}),
});

game.audioBuses.setVolume("alice", 0.5) then applies to clips that are already playing. See Audio Buses.

Player-facing voice behavior is controlled by voiceVolume, voiceFadeDuration, and voiceEndMode. See Manage Preferences.

On this page