Files
novafarma/scripts/generate_intro_cutscene.py
David Kotnik 4a5b788ad4 🎬🎵 Jan 8 COMPLETE AUDIO PRODUCTION - Intro + Music + SFX
 FULL AUDIO SYSTEM READY (104 FILES):

**🎙️ INTRO CUTSCENE VOICES (4 NEW MP3):**
Generated via Edge TTS:
1. 01_narrator_flyover.mp3 (73KB) - 'They say the world didn't die...'
2. 02_kai_awakening.mp3 (28KB) - 'My head... it hurts. Where am I?'
3. 03_kai_truth_part1.mp3 (67KB) - 'Kai Marković. 14 years old...'
4. 04_kai_truth_part2.mp3 (51KB) - 'I'm coming to find you... Ana.'

**Story Structure:**
- Part 1: The Flyover (0:00-0:45) - Narrator
- Part 2: The Awakening (0:45-1:10) - Kai confused
- Part 3: The Truth (1:10-2:00) - Kai determined

**🎵 MUSIC PLACEHOLDERS (7 WAV - 60MB):**
Simple ambient loops for testing:
1. main_theme.wav (90s) - Menu music
2. farm_ambient.wav (120s) - Farming
3. town_theme.wav (90s) - Town restoration
4. combat_theme.wav (60s) - Battle
5. night_theme.wav (180s) - Nighttime
6. victory_theme.wav (30s) - Quest complete
7. ana_theme.wav (120s) - Emotional/flashback

**🔊 SFX PLACEHOLDERS (23 WAV - 1.5MB):**
Farming (8): plant_seed, water_crop, harvest, dig, scythe, mine, chop, cow
Combat (8): sword, bow, zombie_hit, zombie_death, hurt, shield, explosion, raider
Building (5): chest, door_open, door_close, hammer, repair
Misc (2): coin_collect, level_up

**📊 TOTAL AUDIO INVENTORY:**
- Voice Files: 28 MP3 (24 existing + 4 new intro)
- Voiceover: 43 WAV (prologue cutscenes)
- Sound Effects: 25 WAV (2 existing + 23 new placeholders)
- Music: 8 tracks (1 existing + 7 new placeholders)
- **TOTAL: 104 audio files!**

**🎮 INTEGRATION:**
- Updated PreloadScene with intro voice loading
- All audio keys ready for use in intro cutscene
- BiomeMusicSystem ready for 7-track cross-fade
- AudioTriggerSystem ready for all 23 SFX

**📝 SCRIPTS CREATED:**
1. scripts/generate_intro_cutscene.py - Intro dialogue generation
2. scripts/generate_audio_placeholders.py - Music + SFX placeholders

**🎯 USAGE:**
Intro voices: 'intro_flyover', 'intro_awakening', 'intro_truth_1', 'intro_truth_2'
Music: Load from assets/audio/music/*.wav
SFX: Load from assets/audio/sfx/[category]/*.wav

**⚠️  NOTE:** Music/SFX are PLACEHOLDERS (simple tones)
Replace with real audio from Freesound.org or AI generators later!

🎉 AUDIO SYSTEM 100% FUNCTIONAL FOR TESTING!
2026-01-08 17:05:57 +01:00

124 lines
3.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Complete Intro Cutscene Voice Generation
Generates all dialogue for the intro sequence
"""
import asyncio
import edge_tts
from pathlib import Path
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/audio/voiceover/intro")
# Voice configurations
NARRATOR_VOICE = "en-US-GuyNeural" # Deep, mysterious
KAI_VOICE = "en-US-AvaNeural" # Young female
async def generate_intro_voices():
"""Generate all intro cutscene dialogue"""
# Create output directory
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
print("🎬 GENERATING INTRO CUTSCENE VOICES...")
print("="*60)
# ========================================
# PART 1: THE FLYOVER (Narrator)
# ========================================
print("\n📍 Part 1: The Flyover (Narrator)")
narrator_flyover = (
"They say the world didn't die with a bang... "
"but with a quiet whisper. "
"The Valley of Death is not just a place. "
"It's a memory that no one wants to have anymore."
)
await generate_voice(
text=narrator_flyover,
voice=NARRATOR_VOICE,
output_path=OUTPUT_DIR / "01_narrator_flyover.mp3",
rate="-10%", # Slower, dramatic
pitch="-5Hz" # Deeper
)
# ========================================
# PART 2: THE AWAKENING (Kai)
# ========================================
print("\n📍 Part 2: The Awakening (Kai)")
kai_awakening = (
"My head... it hurts. Where am I? Who am I...?"
)
await generate_voice(
text=kai_awakening,
voice=KAI_VOICE,
output_path=OUTPUT_DIR / "02_kai_awakening.mp3",
rate="-15%", # Slower, confused
pitch="-3Hz" # Slightly lower
)
# ========================================
# PART 3: THE TRUTH (Kai - multiple lines)
# ========================================
print("\n📍 Part 3: The Truth (Kai)")
# Line 1: Reading ID card
kai_truth_1 = (
"Kai Marković. 14 years old. That's me. "
"But this other girl... why do I feel so... empty when I see her? "
"Like I'm missing half of my heart."
)
await generate_voice(
text=kai_truth_1,
voice=KAI_VOICE,
output_path=OUTPUT_DIR / "03_kai_truth_part1.mp3",
rate="-5%", # Normal pace, emotional
pitch="+0Hz"
)
# Line 2: Final determination
kai_truth_2 = (
"Someone is waiting for me out there. "
"I can't remember the face, but I feel the promise. "
"I'm coming to find you... Ana."
)
await generate_voice(
text=kai_truth_2,
voice=KAI_VOICE,
output_path=OUTPUT_DIR / "04_kai_truth_part2.mp3",
rate="+0%", # Normal pace, determined
pitch="+2Hz" # Slightly higher, hopeful
)
print("\n" + "="*60)
print("✅ ALL INTRO VOICES GENERATED!")
print("="*60)
print(f"\nOutput directory: {OUTPUT_DIR}")
print("\nGenerated files:")
print(" 1. 01_narrator_flyover.mp3 (Narrator - The Flyover)")
print(" 2. 02_kai_awakening.mp3 (Kai - Awakening)")
print(" 3. 03_kai_truth_part1.mp3 (Kai - Reading ID)")
print(" 4. 04_kai_truth_part2.mp3 (Kai - Determination)")
async def generate_voice(text, voice, output_path, rate="+0%", pitch="+0Hz"):
"""Generate single voice line"""
print(f"\n🎙️ Generating: {output_path.name}")
print(f" Voice: {voice}")
print(f" Text: {text[:60]}...")
communicate = edge_tts.Communicate(text, voice, rate=rate, pitch=pitch)
await communicate.save(str(output_path))
size = output_path.stat().st_size
print(f" ✅ Saved: {size:,} bytes")
if __name__ == "__main__":
asyncio.run(generate_intro_voices())