PointClickEngine::UI::Dialog
Inherits PointClickEngine::Core::Drawable < YAML::Serializable < Reference < Object
Displays conversation text and player choices.
The Dialog class provides the primary interface for character
conversations, narrative text, and player decision-making. It supports
both simple click-to-continue text and multiple-choice selections.
## Features
- Auto-sizing based on text content
- Multiple choice support with callbacks
- Character name display
- Customizable appearance
- Input handling with click/space to continue
- Resolution-independent positioning
## Basic Text Dialog
```crystal
# Simple narrative text
dialog = Dialog.new(
"You enter a dark room. The air is thick with dust.",
Vector2.new(400, 500), # Bottom center
Vector2.new(600, 120) # Width x Height
)
dialog.show
# With character name
dialog.character_name = "Guard"
dialog.text = "Halt! Who goes there?"
dialog.show
```
## Choice Dialog
```crystal
dialog = Dialog.new("How do you respond?", pos, size)
dialog.add_choice("Tell the truth") do
player.add_variable("told_truth", true)
show_next_dialog("truth_response")
end
dialog.add_choice("Lie") do
player.add_variable("told_truth", false)
show_next_dialog("lie_response")
end
dialog.add_choice("Say nothing") do
guard.mood = CharacterMood::Suspicious
dialog.hide
end
dialog.show
```
## Chaining Dialogs
```crystal
dialog1 = Dialog.new("First message", pos, size)
dialog1.on_complete = -> {
dialog2 = Dialog.new("Second message", pos, size)
dialog2.on_complete = -> {
engine.resume_game
}
dialog2.show
}
dialog1.show
```
## Styling
```crystal
dialog.background_color = RL::Color.new(r: 20, g: 20, b: 40, a: 240)
dialog.text_color = RL::Color.new(r: 200, g: 200, b: 255, a: 255)
dialog.font_size = 24
dialog.padding = 30.0
```
## Common Gotchas
1. Input delay: Dialog waits one frame before accepting input
```crystal
dialog.show
# First frame: dialog appears but ignores input
# Second frame: input accepted
```
2. Choice callbacks aren't saved: Re-register after loading
```crystal
# After loading a save with dialogs:
dialog.choices.each_with_index do |choice, i|
choice.action = get_action_for_choice(i)
end
```
3. Modal behavior: Dialogs don't pause the game automatically
```crystal
engine.pause_game # Stop game updates
dialog.show
dialog.on_complete = -> { engine.resume_game }
```
## Input Handling
- No choices: Click or Space to close
- With choices: Click on choice or use number keys (1-9)
- Input is consumed to prevent click-through
## See Also
- FloatingDialog - Speech bubbles for characters
- DialogTree - Complex branching conversations
- Character#say - Simplified character speech
Constructors
new(text : String, position : RL::Vector2, size : RL::Vector2)
Sourcenew(ctx : YAML::ParseContext, node : YAML::Nodes::Node)
Sourcenew
Sourcenew(*, __context_for_yaml_serializable ctx : YAML::ParseContext, __node_for_yaml_serializable node : YAML::Nodes::Node)
SourceInstance methods
add_choice(text : String, &action : -> Nil)
Adds a choice option to the dialog.
Choices are displayed in the order they are added. When selected,
the associated action block is executed.
- text : The choice text shown to the player
- &action : Block to execute when this choice is selected
```crystal
dialog.add_choice("Accept the quest") do
player.add_quest("main_quest")
dialog.hide
end
```
NOTE: Maximum of 9 choices supported (keyboard shortcuts 1-9)
character_name=(character_name : String | Nil)
Optional character name to display above the text
consumed_input=(consumed_input : Bool)
Whether this dialog consumed input this frame (prevents click-through)
draw
Abstract method that must be implemented by including classes
This method should contain the actual rendering logic for the object. It will be called automatically during the rendering phase if the object is visible.
hide
Hides the dialog and triggers the completion callback.
```crystal
dialog.on_complete = -> { engine.resume_game }
dialog.hide # Calls on_complete after hiding
```
on_complete=(on_complete : Proc(Nil) | Nil)
Callback executed when dialog is closed (runtime only)
ready_to_process_input=(ready_to_process_input : Bool)
Whether dialog is ready to accept input (internal flag)
show
Makes the dialog visible and ready for interaction.
The dialog will wait one frame before accepting input to prevent
accidental dismissal from the click that opened it.
```crystal
dialog.show
# Dialog appears but ignores input for one frame
```
update(dt : Float32)
Source