Concurrent lines allow multiple characters to speak simultaneously, creating overlapping dialogue. This is useful for:
Group conversations
Characters interrupting each other
Background chatter
Simultaneous reactions
The built-in example balloon does not contain an implementation for concurrent lines. You’ll need to implement custom handling in your dialogue balloon.
func _on_dialogue_line(line: DialogueLine) -> void: # Display the main line main_label.text = line.text if line.character: main_character.text = line.character # Check for concurrent lines if line.concurrent_lines.size() > 0: for concurrent in line.concurrent_lines: # Display each concurrent line var bubble = create_dialogue_bubble() bubble.text = concurrent.text bubble.character = concurrent.character show_concurrent_bubble(bubble)
~ startNathan: What a beautiful day!| Coco: I agree!| Lilly: The weather is perfect!Nathan: Should we go on an adventure?| Coco: Yes!| Lilly: Absolutely!Nathan: Then let's go!=> END
This creates three moments where multiple characters speak simultaneously.
~ party_sceneNathan: Welcome everyone!Coco: Thanks for having us!Nathan: Let's have some fun!| Coco: I'm excited!| Lilly: This will be great!| Bob: Can't wait!Nathan: Alright, let's start the party!=> END
Concurrent lines support all regular dialogue features:
~ greetingNathan: [#anim=wave] Hello, {{player_name}}!| Coco: [#anim=wave, #emotion=happy] Welcome!| Lilly: [#anim=smile] Good to see you!Nathan: We've been expecting you.=> END
Nathan: The monster is here!| Coco: [if has_weapon] I'll fight!| Coco: [if not has_weapon] I'm scared!| Lilly: [if is_healer] I'll support you!| Lilly: [if not is_healer] What do we do?!
# Staggered appearancefor i in line.concurrent_lines.size(): var bubble = bubbles[i] bubble.appear() await get_tree().create_timer(0.1).timeout # Small delay between each# Simultaneous appearancefor bubble in bubbles: bubble.appear()# Wave patternfor i in bubbles.size(): var delay = sin(i * 0.5) * 0.2 get_tree().create_timer(delay).timeout.connect(bubbles[i].appear)
Audio
How should voice lines be handled?
# Play all simultaneouslyfor concurrent in line.concurrent_lines: var audio = AudioStreamPlayer.new() audio.stream = get_voice_line(concurrent) audio.play()# Play with slight delays for clarityfor i in line.concurrent_lines.size(): var concurrent = line.concurrent_lines[i] get_tree().create_timer(i * 0.1).timeout.connect( func(): play_voice(concurrent) )
Here’s a complete scene using concurrent dialogue:
~ tavern_sceneNathan: [#anim=enter] Welcome to the Rusty Sword Tavern!Nathan: What brings you all here?- We're looking for adventure Nathan: Excellent! I have just the quest for you. | Coco: [#emotion=excited] What is it? | Lilly: [#emotion=curious] Tell us more! | Bob: [#emotion=eager] We're ready! Nathan: There's a dragon terrorizing the nearby village. | Coco: [#emotion=determined] Let's slay it! | Lilly: [#emotion=worried] A dragon? That sounds dangerous... | Bob: [#emotion=brave] We can handle it! Nathan: Then it's settled. Good luck! | Coco: [#anim=fist_pump] Let's go! | Lilly: [#anim=nod] We'll do our best. | Bob: [#anim=thumbs_up] See you soon! => quest_accepted- Just having drinks Nathan: Well then, enjoy yourselves! | Coco: [#anim=raise_glass] Cheers! | Lilly: [#anim=raise_glass] To friendship! | Bob: [#anim=raise_glass] To adventure! => END~ quest_acceptedNathan: May fortune favor you.=> END