DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

How to Generate Voice Samples for Game Characters

Introduction

If you’ve ever played a game where the NPCs sound like they were recorded in a basement, you know how much a polished voice can elevate immersion. Modern text‑to‑speech (TTS) and voice‑cloning tools make it possible to generate high‑quality, expressive voice lines on the fly—no need for a full voice‑over studio. In this post I’ll walk you through a practical workflow for creating voice samples for game characters, using Python (or a quick curl call) and ElevenLabs as the core TTS engine.

TL;DR: Grab the ElevenLabs API, feed it your character’s script, tweak the voice settings, and you’ve got ready‑to‑use .wav files for Unity, Unreal, or any engine you like.


Why TTS is a Game‑Changer for Developers

Traditional VO Production TTS‑Based Production
Hours of recording, editing, and cleanup Instant generation from text
Voice actors need to be booked and directed Any script can be rendered on demand
High cost per minute of audio Pay‑as‑you‑go pricing (often pennies per second)
Limited ability to iterate quickly Rapid A/B testing of lines, emotions, and accents

With voice cloning, you can even give a single actor a “family” of voices—perfect for a squad of soldiers, a group of robots, or a cast of fantasy creatures that share a linguistic DNA.


Getting Started with ElevenLabs

ElevenLabs offers a robust REST API that supports:

  • High‑fidelity neural synthesis (over 30 kHz sampling)
  • Voice cloning from as little as a 30‑second sample
  • Emotion & style controls (e.g., “excited”, “sad”, “angry”)

Sign up through the affiliate link below to get a free trial credit and your API key:

👉 Try ElevenLabs now → https://try.elevenlabs.io/kr07zfuqn1bp 👈

Once you have an API key, you’re ready to script the generation.


Step‑By‑Step: Generating a Voice Line in Python

Below is a minimal but functional Python script that:

  1. Creates a new voice (or re‑uses an existing one)
  2. Sends a line of dialogue to the API
  3. Saves the returned audio as a .wav file
import requests
import json
import os

# -------------------------------------------------
# Config – replace with your own values
# -------------------------------------------------
API_KEY = "YOUR_ELEVENLABS_API_KEY"
VOICE_ID = "YOUR_VOICE_ID"   # optional – you can create a new one first
OUTPUT_DIR = "voice_samples"
os.makedirs(OUTPUT_DIR, exist_ok=True)

# -------------------------------------------------
# Helper: call ElevenLabs TTS endpoint
# -------------------------------------------------
def synthesize(text: str, voice_id: str = VOICE_ID, stability: float = 0.75, similarity: float = 0.85):
    url = f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}"
    headers = {
        "xi-api-key": API_KEY,
        "Content-Type": "application/json"
    }
    payload = {
        "text": text,
        "model_id": "eleven_monolingual_v1",   # high‑quality English model
        "voice_settings": {
            "stability": stability,          # 0‑1, higher = smoother
            "similarity_boost": similarity   # 0‑1, higher = more like the cloned voice
        }
    }

    response = requests.post(url, headers=headers, data=json.dumps(payload))
    response.raise_for_status()
    return response.content   # binary WAV data

# -------------------------------------------------
# Example usage
# -------------------------------------------------
if __name__ == "__main__":
    # Example line for a grizzled mercenary
    line = "We've got company. Keep your eyes peeled and your trigger ready."
    wav_data = synthesize(line)

    out_path = os.path.join(OUTPUT_DIR, "mercenary_01.wav")
    with open(out_path, "wb") as f:
        f.write(wav_data)

    print(f"✅ Saved: {out_path}")
Enter fullscreen mode Exit fullscreen mode

What’s happening?

  • stability smooths out the voice—use lower values for a more “human” jitter.
  • similarity_boost controls how closely the output matches a cloned voice; crank it up for consistency across a character’s lines.

You can loop over a CSV of lines, generate dozens of files in seconds, and then import them straight into your game engine’s audio assets folder.


Quick curl Alternative

If you’re not a Python fan, the same request can be made with curl. This is handy for CI pipelines or quick tests.

curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/YOUR_VOICE_ID" \
  -H "xi-api-key: YOUR_ELEVENLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "text": "The ancient ruins whisper your name.",
        "model_id": "eleven_monolingual_v1",
        "voice_settings": {
          "stability": 0.7,
          "similarity_boost": 0.9
        }
      }' \
  --output ancient_ruins.wav
Enter fullscreen mode Exit fullscreen mode

Replace YOUR_VOICE_ID and YOUR_ELEVENLABS_API_KEY with your real values, and you’ll have a WAV file ready to drop into Unity’s Resources folder.


Cloning a Custom Voice

Sometimes you want a unique, brand‑specific voice—think a futuristic AI companion. ElevenLabs lets you upload a short reference audio file (30 s–2 min) and creates a new voice ID you can reuse.

def create_clone(name: str, audio_path: str):
    url = "https://api.elevenlabs.io/v1/voice-clone"
    headers = {
        "xi-api-key": API_KEY
    }
    files = {
        "name": (None, name),
        "audio_file": open(audio_path, "rb")
    }
    resp = requests.post(url, headers=headers, files=files)
    resp.raise_for_status()
    return resp.json()["voice_id"]
Enter fullscreen mode Exit fullscreen mode
  1. Record a short script in a quiet room.
  2. Run create_clone("Mara the Guide", "mara_sample.wav").
  3. Store the returned voice_id and use it for all subsequent lines.

Now every line you generate will sound like exactly the same character, no matter how many variations you need.


Integrating with Game Engines

Unity (C#)

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class ElevenLabsTTS : MonoBehaviour
{
    [SerializeField] private string apiKey = "YOUR_ELEVENLABS_API_KEY";
    [SerializeField] private string voiceId = "YOUR_VOICE_ID";

    public IEnumerator GetSpeech(string text, string filename)
    {
        string url = $"https://api.elevenlabs.io/v1/text-to-speech/{voiceId}";
        var payload = new
        {
            text = text,
            model_id = "eleven_monolingual_v1",
            voice_settings = new { stability = 0.75f, similarity_boost = 0.85f }
        };
        string json = JsonUtility.ToJson(payload);

        UnityWebRequest request = UnityWebRequest.Put(url, json);
        request.method = UnityWebRequest.kHttpVerbPOST;
        request.SetRequestHeader("xi-api-key", apiKey);
        request.SetRequestHeader("Content-Type", "application/json");

        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.Success)
        {
            System.IO.File.WriteAllBytes($"{Application.persistentDataPath}/{filename}.wav", request.downloadHandler.data);
            Debug.Log($"Saved {filename}.wav");
        }
        else
        {
            Debug.LogError($"TTS error: {request.error}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Call StartCoroutine(GetSpeech("Welcome to the citadel, traveler.", "intro_line")); and the WAV will appear in your persistent data folder, ready for an AudioSource.

Unreal (Blueprints)

  1. Use the HTTP Request node to POST to the same endpoint.
  2. Set the “xi-api-key” header.
  3. Store the binary response into a Sound Wave asset via the Create Sound Wave from Bytes node (available in the Runtime Audio Importer plugin).

Both engines treat the result like any other audio asset, so you can apply 3D spatialization, reverb zones, or dynamic mixing just as you would with hand‑recorded files.


Tips for Production‑Ready Voice Lines

Tip Why it matters
Batch generate Reduces API overhead and keeps your cost predictable.
Consistent voice settings Small changes in stability or similarity_boost can make a character feel “off”. Store the parameters in a config file.
Post‑process with a limiter Even high‑quality TTS can produce occasional peaks; a quick limiter in Audacity or a Unity audio mixer ensures uniform loudness.
Cache results Store generated WAVs locally (or in a CDN) so you don’t hit the API on every game launch.
Test with in‑game context Play the line while the character is moving, in a crowded scene, etc., to catch any clipping or latency issues.

Cost Considerations

ElevenLabs’ pricing is usage‑based. A typical 5‑second line costs around $0.005 (subject to change). For a mid‑size RPG with 300 unique lines, you’re looking at roughly $1.50—a fraction of a traditional voice‑over budget. Keep an eye on the “characters generated” metric in your dashboard to avoid surprise bills.


Wrapping Up

Generating voice samples for game characters no longer requires a studio, a talent scout, or weeks of post‑production. With a few lines of code, you can:

  • Clone a custom voice or pick from ElevenLabs’ library
  • Produce expressive, high‑fidelity audio on demand
  • Integrate the results directly into Unity, Unreal, or any engine of your choice

Give it a spin, iterate on your characters’ personalities, and let the AI do the heavy lifting while you focus on gameplay.

Ready to bring your NPCs to life?

👉 Try ElevenLabs today → https://try.elevenlabs.io/kr07zfuqn1bp and start generating voice lines that sound as unique as your game world. Happy coding!

Top comments (0)