#!/usr/bin/env python3 """ Generate Quest Voiceover Audio Generates TTS audio files for all quest dialogue using Edge TTS. Supports Slovenian language with natural female voice (Petra). Usage: python generate_quest_voiceovers.py Output: assets/audio/quests/[quest_id]_start.mp3 assets/audio/quests/[quest_id]_progress.mp3 assets/audio/quests/[quest_id]_complete.mp3 """ import os import sys import asyncio import edge_tts # Quest dialogue from QuestDataLoader QUEST_DIALOGUES = { # Main Story Quests "q001_kje_sem": { "start": "...au glava... kje sm? Čak... kdo SM jaz sploh?!", "complete": "Včeri sm bla tam, zdej pa tuki... MORŠ NEC NAJT!" }, "q002_prvi_koraki": { "start": "Hm... mam tools pa zemljo... Probam narit farmo?", "progress": "Nice! Raste!", "complete": "DAAAAJ! Prva plants! Kul!" }, "q003_glas_v_glavi": { "start": "...Kaj je to? Neki slišim... Dekle? Govori slovensko.. mam občutek da jo POZNAM?!", "onVoice": "Kai, a me slišiš? Ne skrbi zame... najd se...", "complete": "TA FOTKA! To je... ANA?! SESTRA! Moja SESTRA! ...pomnim se! ANA JE ŽIVA!" }, # Collection Quests "q010_80_crops": { "start": "80 različnih crops? Challenge accepted!", "progress": "Še {remaining} da konč!", "complete": "DAAAAAJ 80/80! MASTER FARMER STATUS UNLOCKED!" }, "q011_tree_planter": { "start": "11 vrst dreves... začenjam z oak!", "complete": "DONE! Ves forest je moj!" }, "q020_creature_catalog": { "start": "HOLY SHIT 99 creatures?! OK gremo!", "progress": "{current}/99... keep going!", "complete": "COMPLETE CREATURE CATALOG! SICK!" }, # Social Quests "q080_166_friends": { "start": "166 ljudi? Noben me ne pozna... but I'll try!", "progress": "{current} friends... getting there!", "complete": "166/166! EVERYONE KNOWS ME NOW!" }, # Building Quests "q040_gothic_empire": { "start": "6 buildings... let's gooo!", "complete": "FARM EMPIRE COMPLETE!" }, # Biome Quests "q050_underwater_secrets": { "start": "Voda! Water physics so sick! Dreads plavajo! 😂", "complete": "Podvodni treasures found! DOPE!" }, "q060_baba_yaga": { "start": "Witch Forest... creepy af", "onBoss": "BABA YAGA?! OH SHIT!", "complete": "DEFEATED! Broomstick je moj! LETIM!" }, "q070_jurassic_farm": { "start": "DINOZAVRI?! WHAT?!", "complete": "TAMED T-REX! BEST DAY EVER!" } } # Voice settings VOICE_SLOVENIAN_FEMALE = "sl-SI-PetraNeural" # Petra - Slovenian female voice OUTPUT_DIR = "assets/audio/quests" async def generate_voiceover(text, output_path, voice=VOICE_SLOVENIAN_FEMALE): """Generate single voiceover file""" # Remove emojis and special characters for TTS clean_text = text.replace('😂', '').replace('...', ' ').strip() print(f"Generating: {output_path}") print(f" Text: {clean_text[:50]}...") communicate = edge_tts.Communicate(clean_text, voice) await communicate.save(output_path) print(f" ✅ Saved!") async def generate_all_quest_voiceovers(): """Generate all quest voiceovers""" # Create output directory os.makedirs(OUTPUT_DIR, exist_ok=True) total_files = 0 for quest_id, dialogues in QUEST_DIALOGUES.items(): print(f"\n🎙️ Quest: {quest_id}") for event_type, text in dialogues.items(): # Skip progress dialogue with placeholders if '{remaining}' in text or '{current}' in text: print(f" ⏭️ Skipping {event_type} (has placeholder)") continue # Generate filename filename = f"{quest_id}_{event_type}.mp3" output_path = os.path.join(OUTPUT_DIR, filename) # Generate voiceover await generate_voiceover(text, output_path) total_files += 1 print(f"\n✅ COMPLETE! Generated {total_files} voiceover files!") print(f"📁 Location: {OUTPUT_DIR}/") def main(): """Main entry point""" print("=" * 60) print("QUEST VOICEOVER GENERATOR") print("=" * 60) print(f"Voice: {VOICE_SLOVENIAN_FEMALE}") print(f"Output: {OUTPUT_DIR}/") print("=" * 60) # Run async generation asyncio.run(generate_all_quest_voiceovers()) if __name__ == "__main__": main()