Dialog engine

Analysis of Current DialogueEngine Implementation
I've completed an initial analysis of the current DialogueEngine implementation. The flowchart below summarizes the workflow of the current implementation:



As can be seen from the flowchart, the current implementation goes through the following major stages once a dialogue has been initiated:
 * Initialization of the Dialogue Engine
 * Processing of Dialogue Commands
 * Processing of Responses and User Input

In the initialization stage the DialogueEngine loads the dialogue data for a specific NPC and extracts the start dialog node from the dialogue data, which is used to start the dialogue flow. The programmer also has to define some dialogue command callbacks (see Dialogue Commands) and a dictionary of game state data used to check response conditions (see Response Conditionals).

Once a start dialogue node is selected the DialogueEngine begins processing any dialogue commands it finds in the dialogue node (see Dialogue Commands). Depending upon the commands it encounters the DialogueEngine may end the dialog, change the dialogue flow by returning to a previous dialog node, or present the player with a list of valid responses which ultimately causes the DialogueEngine to start processing the commands from a different dialog node.

Once a 'responses' command is encountered within a dialogue node, the DialogueEngine processes any conditional statements for defined responses and presents the user with a list of valid responses contingent upon the result of the conditional tests. The user can then select a repy and feed it back into the DialogueEngine, which as noted above begins processing the corresponding dialogue node's commands.

This cycle continues until an 'end' command is reached, at which point the DialogEngine exits the dialogue.

Dialogue Data Structures
TODO

YAML Dialogue Files
Dialogue nodes are defined by entries under the "SECTIONS" YAML tag. For example, consider the following dialogue definition file:

NPC: Old Man AVATAR: gui/icons/crazy_swede.png START: main_dialogue

SECTIONS: main_dialogue: - say: "[The old man looks up at you from his chair with a dazed look upon his face] ...Lucy?" - meet: old_man - responses: -            - "Who's Lucy?" - help_find_lucy -            - "I don't have time for your dulusions old man!" - parting_shot

help_find_lucy: - say: "[The old man looks at you expectedly] Can you help me find Lucy?" - responses: -            - "Where is Lucy?" - rusted_lockbox -            - "I have better things to do." - parting_shot rusted_lockbox: - say: "[The old man gazes over his shoulder to the far side of the shanty where a metal lockbox rests on the floor] Can't open it any more... rusted..." - responses: -            - "I'll see what I can do." - parting_shot -            - "Fix your own problems, old man!" - parting_shot

parting_shot: - say: "[The old man sighs and begins to stare remorsefully at the smouldering embers in the fireplace.]" - responses: -            - end

This dialogue definition file defines the following dialogue nodes:
 * main_dialogue
 * help_find_lucy
 * rusted_lockbox
 * parting_shot

Dialogue Commands
Each dialogue node contains two or more commands:
 * a 'say' command, which tells the dialogue engine to display the following text to the user
 * a 'responses' command, which contains the various responses that the player may be able to reply with (see Response Conditions)
 * other misc. commands, such as 'start_quest', 'set_value' etc. which are defined by callbacks at runtime
 * special commands that change the flow of the dialogue, such as 'back' and 'end'

The 'say' and 'responses' commands are mandatory and must appear once and only once within every dialogue node. Of all the commands, 'responses' is probably the most complicated

Response Conditionals
TODO

Dialogue State: the Dialogue Stack
The Dialogue Engine stores a particular dialogue's state as a stack of dialogue node identifiers. For instance, if a player responded "Who's Lucy?" and then "I have better things to do.", the dialogue stack would look like this just before the player ended the dialogue:

Note that the dialogue stack is implemented as a simple Python list. Currently the stack is cleared at the end of each dialogue, meaning that dialogues with the same NPC follow exactly the same flow each time assuming no response conditions change. In theory, the stack could be used to persist the state of the dialogue instead of relying upon game state checks to determine dialogue flow, though this might not be the best method of dialogue persistence since the memory needed would scale proportionally to the number of NPC's with persistable dialogues.