Dialogues

A huge topic in game and multimedia app development is good and none-redundant dialogue or conversation management. With Gorilla3D you have an easy-to-use component which is also able to handle complex conversations.

Features

  • Complex & flexible design in tree structure
  • (Un)lockable items
  • Crosslinking of items possible
  • Question and Answer/Option model
  • Display-Time and Timeout configuration
  • Design of dialogues & monologues with colloquist information
  • Multilingual system easily definable
  • Auto-language selection
  • Set variables to implement gaming elements
  • Set parameters to interact back with your game/application
  • Events for: showing text and images, playing audio, video and animations, executing method calls, property settings, redirection & more
  • Events with different scopes: dialogue item, UI-element, gaming element
  • Pause, stop and skip dialogues and items
  • Storable as single or multiple dialogue files/streams (dynamic loading possible)
  • Storeable in xml format
  • Loadable from xml file/stream
  • Readable and understandable xml format, to outsource design & management of dialogues.
  • Fully customizable in Delphi

DialogueDesigner

We already built a helper tool for you to setup dialogues by a flow chart editor.

  • Create dialogues, items and events simply by drag & drop
  • Move, rearrange and delete items & events
  • Configure every dialogue, item and event in detail
  • Treeview for easy dialogue navigation
  • Preview dialogues in sandbox viewer

TGorillaDialogueSystem

The dialogue system is the basis component for setting up and manage multiple dialogues/conversations and variables. Imagine the dialogue system as a hierarchy, which is able to jump between leaves (items) and execute events, to playback animations, sounds or execute scripts:

DialogueSystem

  1. Dialogues
    1. Characters (conversation partner)
    2. Items (Textfragments of conversation)
      1. Events (do something)
  2. Variables

To start setting up a system, a few properties are important to know:

Property Description
IdUnique id for a specific dialogue system. On creation automatically a random id will be generated, but it's possible that this id is not unique. The user should take care, that this id is unique!
LanguageDefines the currently used language by id. This property affects auto language map handling for items and events. Dialogue Designer uses ISO language id's, like “en-us”, “de-de”, …
DialoguesA collection of available dialogue instances.
VariablesA hashmap of <name>,<TObject> pairs. Register variables to connect another environment with the dialogue system.

Simply set up a dialogue system at runtime like in the following code snippet:

uses
  Gorilla.Utils.Dialogue.System;
 
[...]
 
FDialogueSys : TGorillaDialogueSystem;
FDialogue : TGorillaDialogue;
 
[...]
 
// create a dialogue system on our form (its a none-visual component)
FDialogueSys := TGorillaDialogueSystem.Create(Self);
 
// create a new dialogue
FDialogue := FDialogueSys.Dialogues.Add() as TGorillaDialogue;

UserInterface

Because the dialogue system is a logical component without any visual or game interactive feedback, you have to use a visual UI framework on top. We provide a simple one for you in the Gorilla.UI.Dialogue.Overlay or by the Gorilla.UI.Dialogue.Sandbox unit.

All UI interfaces for a dialogue system bind its callback event to display text, playback audio or whatever.

EventDescription
OnBeginDialogueItemEvent Callback event gets called when an item event gets executed.
OnEndDialogueItemEvent Callback event gets called when an item event gets stopped.
OnBeginDialogueItem Callback event gets called when an item is going to be displayed.
OnEndDialogueItem Callback event gets called when an item is going to be hidden.
OnStartDialogue Callback event gets called when a specific dialogue was started.
OnStopDialogue Callback event gets called when a specific dialogue was stopped.
OnPauseDialogue Callback event gets called when a specific dialogue was paused.
OnSkippedDialogue Callback event gets called when a specific dialogue was skipped by user interaction.
OnSkipAvailability Callback event gets called on start of a specific item. The callback submits if a skip is available for this specific item. Use this event to display a skip button only when skipping is allowed.
OnBeginItemTimeout Callback event gets called on dialogue item start, when a display time is set. The callback is called before event execution.
OnEndItemTimeout Callback event gets called on execution timeout in the DoOnExecTimerEvent() routine. The callback is called before timeout events execution.
uses
  Gorilla.UI.Dialogue.Overlay;
 
[...]
 
FHUD := TGorillaDialogueHUD.Create(Self);
FHUD.Parent := Self;
FHUD.Align := TAlignLayout.Client;
FHUD.Viewport := GorillaViewport1;
FHUD.AudioManager := GorillaAudioManager1;
FHUD.Dialogue  := FDialogue;
 
[...]
 
FHUD.Start();

Conversation (TGorillaDialogue)

A TGorillaDialogue instance is a single closed conversation. So if you want to have a dialogue between character A and B this is the point to start. A TGorillaDialogue manages items and characters. An item can be seen as a text-fragment in your conversation but is much more. A character is a helper structure to organize your conversation. Because it's always important to know who is speaking. Besides this simple fact, a character is used as variable, which can be accessed.

As you've seen above, you add a new dialogue by adding a collection item in the TGorillaDialogueSystem.Dialogues collection. In the next step we should add two characters for our conversation partners, which is also done by adding a collection item. You can of course add more than 2 characters, but to keep it simple, we'll stay here with A and B.

FCharacterA := FDialogue.Characters.Add() as TGorillaDialogueCharacter;
FCharacterA.Name := 'A';
 
FCharacterB := FDialogue.Characters.Add() as TGorillaDialogueCharacter;
FCharacterB.Name := 'B';

Once you've done that, we can start adding our text fragments.

Text-Fragments (TGorillaDialogueItem)

A text fragment is an entity representing a snippet of a conversation or monologue. In most cases its a phrase, a sentance or longer text passage spoken by a single character. So the main duty for setting up a conversation is to split it up the complete text into parts or so called items.

A TGorillaDialogue and a TGorillaDialogueItem are both inherited from TGorillaDialogueParentItem, which is able to hold further sub-items. So you can to setup a hierarchy, that represents a text playback order automatically.

Dialogue
    "Hello World!"
        "How are you?"
            "I'm fine"

The example above will playback the text fragments in order:

  1. “Hello World”
  2. “How are you?”
  3. “I'm fine”

Each item also has the possibility to register events to control the text flow. Those events allow the dialogue system to handle even complex conversation flow. What events can do for you, you can read further below.

Property Description
Kind Currently the following item kinds are supported: Question, Answer, Flow, Reference
DisplayNameThis value should be unique, but is managed by the user
CharacterDefines a linked character. If DisplayName is not set, but a character is defined, the component will return the characters name as display name.
ReferenceIn case the kind is set to TGorillaDialogueItemKind.Reference, this property needs to be set to the DisplayName of the linked item.
DisplayTime Defines a time, for how long an item is going to be displayed, before it gets automtically skipped by the system.
Text The hashmap is a list of «language-id>,<text» pairs. The hashmap is a list of «language-id>,<text» pairs. Use the GetCurrentText() method to request the currently translated text content, depending on the dialogue system language setting.
Events Returns a collection of item events.

Kinds of items

A dialogue seldomly is just a text flow. You nearly always will have questions, answers to choose from or points to which to return to. Our dialogue system allows to configure those variations easily.

Kind Description
TGorillaDialogueItemKind.Noneundefined kind - should never be set
TGorillaDialogueItemKind.QuestionA text-fragment marked as question. This will load up sub-items as possible answers to choose from.
TGorillaDialogueItemKind.AnswerText-fragments marked as possible options to choose from. The parent item should be a question item.
TGorillaDialogueItemKind.FlowA default text-fragment, simply plays back for a defined timespan and then switches to the next item in row
TGorillaDialogueItemKind.ReferenceA reference item is used as dummy fragment to forward to another item. Use this to jump at specific text-fragments in your dialogue. For example if you want to reask a question.

Events

Events in items allow interaction with your game and to control the text flow of the conversation.

LItem : TGorillaDialogueItem;
LEvent : TGorillaDialogueItemEvent;
 
[...]
LEvent := LItem.Events.Add() as TGorillaDialogueItemEvent;
LEvent.Kind := TGorillaDialogueEventKind.Text;
LEvent.Trigger := TGorillaDialogueEventTrigger.OnBegin;

A few configuration properties allowing you to setup an event for many purposes:

Property Description
OwnerEvent It is possible to execute events by another event. For example for animations, where you have a starting and finish event.
KindDefines the kind of event. Supported types are: Text, Image, Audio, Video, Animation, Method, ObjProperty, Redirect, Timer, Misc
Trigger Defines the moment of event execution. Supported types are: OnBegin, OnEnd, OnTimeout
Scope A scope should be a component name or a dialogue item ident. Which value to be used depends on the kind of event. Use “ui” to work on the linked UIElement of the current dialogue item. Use “self” to work on the current event. It's possible to use variable names here or different item id's.
Data Defines the multilingual data container. Use this property to define language specific texts, f.e. for displaying a text event.
Iterations If the property is set to zero, functionality is disabled. Values larger than zero, perform iteration checks inside Execute() method. For example: Value=3, the event will be called only if the item was played back 3 times.

Kind of events

The system distinguishes between internally managed events and user specific events. Internally handled events can not be influenced by the UI. But user-specific events will only be handled by the user interface.

EventTypeDescription
TGorillaDialogueEventKind.TextUser-Specificintended to show a text on screen
TGorillaDialogueEventKind.ImageUser-Specificintended to show an image on screen
TGorillaDialogueEventKind.AudioUser-Specificintended to playback an audio file
TGorillaDialogueEventKind.VideoUser-Specificintended to playback a video file
TGorillaDialogueEventKind.AnimationUser-Specificintended to start a model animation or a TAnimation instance
TGorillaDialogueEventKind.MethodInternalexecutes a published method by RTTI
TGorillaDialogueEventKind.ObjPropertyInternalsets a specific property
TGorillaDialogueEventKind.Redirect Internalredirects to another item
TGorillaDialogueEventKind.TimerUser-Specificstarts timeout counter and allows to run another event
TGorillaDialogueEventKind.MiscUser-Specificintended to use for individual purposes

The data value used depends on the kind of event. While for text, image, audio or video a language specific data value is important, the data value for method or object-properties is generally valid.

Example for adding multilingual sound files:

LEvent.Kind := TGorillaDialogueEventKind.Audio;
LEvent.Data.AddOrSetValue('en-us', 'flash_en-us.mp3');
LEvent.Data.AddOrSetValue('de-de', 'flash_de-de.mp3');

Example for adding generally available texts, by using “*” as language key:

LEvent.Kind := TGorillaDialogueEventKind.Text;
LEvent.Data.AddOrSetValue('*', 'a b c d e f');

Example for setting an object property. Here a disabled flow-item will be enabled by an event.

LEvent.Kind := TGorillaDialogueEventKind.ObjProperty;
 
// scope is the item to change property defined in "Paramaters"
LEvent.Scope := 'Question1_Answer2_FlowItem3';
LEvent.Parameters.AddOrSetValue('Enabled', TValue.From<Boolean>(true));

Load & Save

The dialogue system supports loading and storing conversations to file (*.dia;*.dlg). The AssetsManager also supports this file format, so you can push those files to your game package.

FDialogueSys := TGorillaDialogueSystem.Create(Self);
FDialogueSys.LoadFromFile('MyDialogues.dia');

To store your dialogue settings, simply call SaveToFile or SaveToStream.

FDialogueSys.SaveToFile('MyDialogues.dia');

Next step: SkillSystem