An introduction to JSON dialogue systems

16

Index

Attached Files

The following files have been attached to this tutorial:

Stats

9,086 visits, 21,615 views

Tools

Translations

This tutorial hasn't been translated.

License

This tutorial is licensed under CC BY 4.0. Please refer to the license text if you wish to reuse, share or remix the content contained within this tutorial.

Published on 4 Dec, 2019. Last updated 4 Aug, 2020

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.

Next Tutorial In Course

Using a JSON dialogue system with NPCs 07:16

Carrying on from the previous tutorial, here we apply the dialogue system to a scenario using NPC objects. Adding keyboard control, and using the replace expression to insert variables into the text.

  • 15 Comments

  • Order by
Want to leave a comment? Login or Register an account!
  • My god. I've been sitting with this the whole day, not understanding what I'm doing wrong. Looks like I forgot an "s" at the end of 1 word. Never give up people...

    Thank you so much, amazing guide!

  • This is really tough for a beginner. I got stuck at the final return value 'on function format' I could not figure out how to implement the replace() expressions. Even looking at the final .json i could not work out how to enter the 'System ▶︎ Set Line to replace(String,"(b)","[ b]")' or other 3 lines???

  • Sorta newb in Construct, trying to follow this tutorial and am stuck- I added a local variable1, but cannot add another just like it without it having a different name. Will that matter? How did you add an identical local variable when the program doesn't allow it?

    Thank you!

    • I doesn't matter. It's because if you select the function and press V, you create a local variable outside of the function. That's why it doesn't let you name it Variable1 again. I found 2 solutions to the problem.

      1. Just create the Variable2, them move it in to the function and rename it to Variable1 once inside.

      2. Select a condition inside the function and press V(shortcut for creating local variable). That way you can just name it Variable1 right away, since it's inside.

      You probably solved it by now but I thought this might help someone.

  • Thanks so much for your tutorial. I am new to Construct 3. I can't figure out how you added a local variable. I'm on page 3 of your tutorial and I'm stuck. I got as far as LOCAL NUMBER, VARIABLE1 this. How do I add a local variable? And furthermore, how do I add it to the event page? Thanks.

  • still a tiny error on the initial actions, the json command is not load is parse, it was good that the last comment has it right, or I would have never find how to use this.

  • Load more comments (8 replies)