Programming the Dialogue
Now that you have the basic project structure, it’s time to make it work!
To start with, you’ll need to have a couple of initialisation actions to set up the project correctly. This event block will hide the Dialogue layer and load the JSON project file into the JSON object:
Condition
System ▶︎ On start of layout
Action
System ▶︎ Set layer “Dialogue” to invisible
AJAX ▶︎ Request project file (remember to pick your JSON file), tag “dialogues”
System ▶︎ Wait for previous actions to complete
JSON ▶︎ Parse JSON string AJAX.LastData
Before we get into the meat of the dialogue system, it’s worth setting up the functions and variables you’ll need to make the rest of the events work.
Firstly, you’ll need two Global Numbers – curScene and curDialogue. These two numbers are used to track which scene and dialogue the game is currently using and we display the correct data accordingly.
Next, let’s tackle the functions needed for this project – there are four in total. Starting with the three return functions. These functions provide us with values that are then used elsewhere in the project.
Firstly, there’s getNBScenes. This function looks through the JSON file, counts how many scenes are in the file and returns that value:
On function getNBScenes
Local number, Variable1
Condition
JSON ▶︎ For each entry in “scene”
Action
System ▶︎ Add 1 to Variable1
Sub-event Action
Functions ▶︎ Set return value to Variable1 -1
Next, you’ll need a similar function to count the number of lines in each scene. Again, this will return that number to use as an expression later. So, for getNBLines:
On function getNBLines
Local number, Variable1
Condition
JSON ▶︎ For each entry in "scene." & curScene & ".dialogues"
Action
System ▶︎ Add 1 to Variable1
Sub-event Action
Functions ▶︎ Set return value to Variable 1 -1
The final return value function is the one used to format the text before it’s displayed. This function passes the text string through several replace expressions to add in formatting:
On function format, string parameter String
Local string, Line
Function Action
System ▶︎ Set Line to replace(String,"(b)","[ b]")
System ▶︎ Set Line to replace(Line,"(/b)","[ /b]")
System ▶︎ Set Line to replace(Line,"/br",newline)
Functions ▶︎ Set return value to Line
The parameter "string" is passed through a replace() expression that allows us to apply various formatting aspects and by using the local variable line we can run the text through several of these expressions.
The expression turns any instances of "/br" into newline (putting the text onto a new line), any "(b)" into "[ b]" (without the space) and "(/b)" into "[ /b]" (without the space).
We have to use replace expressions here because traditional BBCode cannot be written into the JSON file (or in our C3 comments without applying the formatting!)
Now onto the main function dispDialogue. This is the function that allows us to display a specific line of text:
On function dispDialogue, number parameter dialogueID
Function Action
System ▶︎ Set layer “Dialogue” to visible
Portrait ▶︎ Set animation to JSON.Get("scene."& curScene &".dialogues."& dialogueID &".char")
CharNameTxt ▶︎ Set text to JSON.Get("scene."& curScene & ".dialogues." & dialogueID & ".char")
DialogueTxt ▶︎ Set text to Functions.format(JSON.Get("scene."& curScene & ".dialogues." & dialogueID &".line"))
You should spot the first use of one of our return functions here. The Functions.format section of that last action is using the return value from the format function as an expression. Handy!
That’s all of the functions defined, so now we can move onto actually making the dialogue system itself. The whole thing is controlled by touch (or click) gestures so the main functionality will be nested under a touch event:
Condition
Touch ▶︎ On any touch end
Sub-event Condition
System ▶︎ curDialogue < Functions.getNBLines
Sub-event Action
System ▶︎ Add 1 to curDialogue
Functions ▶︎ Call dispDialogue (dialogueID: curDialogue)
Sub-event Condition
System ▶︎ Else
System ▶︎ curScene < Functions.getNBScenes
Sub-event Action
System ▶︎ Add 1 to curScene
System ▶︎ Set curDialogue to 0
Functions ▶︎ Call dispDialogue (dialogueID: curDialogue)
These events will check what line and scene should be in use, and then call the function with the appropriate parameter to ensure the correct text is displayed.
There are just two more events to finish off this project. One to recognise when there is no more dialogue, and one to set the debug text to show what scene and dialogue is currently being displayed.
To check for the end of all dialogue and display the restart message:
Condition
System ▶︎ Compare two values ▶︎ curScene = Functions.getNBScenes
System ▶︎ Compare two values ▶︎ curDialoge = Functions.getNBLines
Action
DemoTxt ▶︎ Set text to “Press F5 to restart”
And finally to set the debug text:
Condition
System ▶︎ Every Tick
Action
DebugTxt ▶︎ Set text to "curScene: " & curScene & "/" & Functions.getNBScenes & " - curDialogue: " & curDialogue & "/" & Functions.getNBLines
And that’s it! If you preview your project, you should be able to tap through a dialogue showing two different NPC names and portraits, with formatted text and two separate conversations.