Files
novafarma/scripts/generate_quest_voiceovers.py
David Kotnik d5c7c3ee67 CHAR ANIMATIONS COMPLETE - 52 frames generated
Session: 11hr marathon (Jan 8, 2026)
Assets: 52 animation frames total
Progress: 36% to 54%

Kai: 20 frames (idle 4, walk 6, dig 5, swing 5)
Ana: 10 frames (idle 4, walk 6)
Gronk: 10 frames (idle 4, walk 6)
Susi: 12 frames (idle 4, run 6, bark 2)

Demo Status: 157/292 assets (54%)
Remaining: 135 assets

Files updated:
- TASK_TRACKER.md
- PRODUCTION_CHECKLIST.md
- 64 new PNG assets
- Susi reference updated
2026-01-08 04:03:10 +01:00

144 lines
4.5 KiB
Python

#!/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()