"""Song/Lyrics emotional journey data and sequence generation. This module provides: - EMOTIONAL_STATES: Dictionary of emotional states for song-based narratives - generate_song_sequence: Function to generate emotional journey sequences """ import json import random # Emotional states organized by mood category EMOTIONAL_STATES = { "joy": [ ("Euphoria", "Pure, overwhelming happiness radiates through every moment", ["celebration", "peak"]), ("Contentment", "A gentle satisfaction with the present moment", ["peace", "gratitude"]), ("Excitement", "Anticipation of wonderful things bubbles up inside", ["energy", "possibility"]), ("Love's Bloom", "The warmth of affection fills every corner of being", ["romance", "connection"]), ("Triumph", "Victory brings a surge of proud accomplishment", ["achievement", "power"]), ], "sorrow": [ ("Heartbreak", "The ache of loss echoes through an empty chest", ["pain", "separation"]), ("Melancholy", "A bittersweet sadness colors everything in blue", ["reflection", "beauty"]), ("Grief", "The weight of absence presses down relentlessly", ["mourning", "memory"]), ("Longing", "An unreachable desire stretches toward the horizon", ["yearning", "distance"]), ("Regret", "If only things had been different...", ["hindsight", "weight"]), ], "anger": [ ("Rage", "White-hot fury demands expression and release", ["intensity", "destruction"]), ("Frustration", "Barriers block every attempt at progress", ["struggle", "tension"]), ("Betrayal", "Trust shattered leaves sharp edges everywhere", ["wound", "disbelief"]), ("Defiance", "A refusal to accept what others demand", ["rebellion", "strength"]), ("Righteous Fire", "Injustice ignites a burning need for action", ["purpose", "conviction"]), ], "fear": [ ("Dread", "Something terrible approaches with inevitable footsteps", ["anticipation", "darkness"]), ("Anxiety", "Uncertainty spirals into cascading worries", ["overwhelm", "paralysis"]), ("Vulnerability", "Exposed and unprotected in a hostile world", ["fragility", "need"]), ("Paranoia", "Every shadow hides a threat, every silence a danger", ["suspicion", "isolation"]), ("Terror", "Primal fear strips away everything but survival", ["crisis", "instinct"]), ], "hope": [ ("Dawn Breaking", "After darkness, the first light of possibility appears", ["renewal", "promise"]), ("Second Chance", "An opportunity to make things right emerges", ["redemption", "gratitude"]), ("Dreams Forming", "Visions of what could be take shape in the mind", ["imagination", "aspiration"]), ("Faith Restored", "Belief in something greater returns", ["trust", "meaning"]), ("Courage Rising", "Fear transforms into determination to face what comes", ["strength", "resolve"]), ], "nostalgia": [ ("Golden Memories", "The past glows with a warm, amber light", ["comfort", "loss"]), ("Innocence Lost", "Remembering before the world became complicated", ["youth", "purity"]), ("Phantom Touch", "The sensation of someone no longer present", ["love", "absence"]), ("Places Remembered", "Spaces that hold pieces of who you were", ["identity", "change"]), ("Old Songs", "Melodies that transport you across time", ["emotion", "connection"]), ], "peace": [ ("Stillness", "The noise fades and silence becomes sanctuary", ["calm", "presence"]), ("Acceptance", "What is, simply is - no struggle remains", ["surrender", "wisdom"]), ("Unity", "Separation dissolves into connection with all things", ["transcendence", "belonging"]), ("Forgiveness", "The weight of grudges lifts away", ["release", "healing"]), ("Home", "A sense of belonging settles into the bones", ["safety", "arrival"]), ], } # Song structure elements SONG_STRUCTURES = { "verse": "The story unfolds, details emerge", "chorus": "The central truth repeats, driving home the message", "bridge": "A shift in perspective, a new angle on the theme", "outro": "The emotion settles, leaving its lasting impression", } def generate_song_sequence(verse_count, include_joy, include_sorrow, include_anger, include_fear, include_hope, include_nostalgia, include_peace, emotional_arc="journey"): """Generate an emotional journey sequence based on song structure. Args: verse_count: Number of emotional beats (3-10) include_*: Include specific emotional categories emotional_arc: 'journey' (varied), 'crescendo' (building), 'resolution' (tension to peace) Returns: Tuple of (list_output, json_output, prompts_output) """ available = [] if include_joy: available.extend([(e[0], e[1], "joy", e[2]) for e in EMOTIONAL_STATES["joy"]]) if include_sorrow: available.extend([(e[0], e[1], "sorrow", e[2]) for e in EMOTIONAL_STATES["sorrow"]]) if include_anger: available.extend([(e[0], e[1], "anger", e[2]) for e in EMOTIONAL_STATES["anger"]]) if include_fear: available.extend([(e[0], e[1], "fear", e[2]) for e in EMOTIONAL_STATES["fear"]]) if include_hope: available.extend([(e[0], e[1], "hope", e[2]) for e in EMOTIONAL_STATES["hope"]]) if include_nostalgia: available.extend([(e[0], e[1], "nostalgia", e[2]) for e in EMOTIONAL_STATES["nostalgia"]]) if include_peace: available.extend([(e[0], e[1], "peace", e[2]) for e in EMOTIONAL_STATES["peace"]]) if not available: return "Select at least one emotional category!", "{}", "" sequence = [] random.shuffle(available) # Apply emotional arc logic if emotional_arc == "crescendo": # Build from calm to intense intensity_order = ["peace", "nostalgia", "hope", "joy", "fear", "sorrow", "anger"] available.sort(key=lambda x: intensity_order.index(x[2]) if x[2] in intensity_order else 3) elif emotional_arc == "resolution": # Start intense, end peaceful intense = [e for e in available if e[2] in ["anger", "fear", "sorrow"]] calm = [e for e in available if e[2] in ["peace", "hope", "joy"]] random.shuffle(intense) random.shuffle(calm) available = intense + calm sequence = available[:verse_count] if not sequence: return "No emotional states available!", "{}", "" # Assign song structure elements structure_labels = [] for i in range(len(sequence)): if i == 0: structure_labels.append("INTRO") elif i == len(sequence) - 1: structure_labels.append("OUTRO") elif i == len(sequence) // 2: structure_labels.append("BRIDGE") elif i % 2 == 0: structure_labels.append("CHORUS") else: structure_labels.append("VERSE") # Format as list list_output = f"## Emotional Journey ({emotional_arc.title()} Arc)\n\n" for i, ((name, desc, mood, themes), structure) in enumerate(zip(sequence, structure_labels), 1): themes_str = ", ".join(themes) list_output += f"**{i}. [{structure}] {name}** ({mood})\n{desc}\n*Themes: {themes_str}*\n\n" # Format as config JSON config = {"emotional_journey": {}} for i, ((name, desc, mood, themes), structure) in enumerate(zip(sequence, structure_labels), 1): state_name = name.lower().replace(" ", "_").replace("'", "").replace("-", "_") current_state_id = f"moment_{i}_{state_name}" themes_str = ", ".join(themes) # Determine next state if i < len(sequence): next_name = sequence[i][0] next_state_name = next_name.lower().replace(" ", "_").replace("'", "").replace("-", "_") next_state_id = f"moment_{i+1}_{next_state_name}" else: next_state_id = "journey_end" config["emotional_journey"][current_state_id] = { "description": f"[{structure}] {desc}\n\n*Feeling: {mood} | {themes_str}*", "media_prompt": f"Abstract emotional art: {name} - {mood} mood, {desc}, visual representation of {themes_str}", "choices": ["Feel the Next Wave"], "transitions": { "Feel the Next Wave": next_state_id } } # Add ending state first_moment = sequence[0][0].lower().replace(" ", "_").replace("'", "").replace("-", "_") config["emotional_journey"]["journey_end"] = { "description": "The emotional journey comes full circle. Every feeling has been felt, every moment lived.", "choices": ["Experience Again"], "transitions": { "Experience Again": f"moment_1_{first_moment}" } } json_output = json.dumps(config, indent=2) # Format prompts prompts_output = f"## Emotional Art Prompts ({emotional_arc.title()})\n\n" for i, (name, desc, mood, themes) in enumerate(sequence, 1): themes_str = ", ".join(themes) prompts_output += f"Abstract emotional art: {name} - {mood}, {themes_str}\n" return list_output, json_output, prompts_output if __name__ == "__main__": list_out, json_out, prompts_out = generate_song_sequence( 6, True, True, False, False, True, True, True, "resolution" ) print(list_out)