Part 1 : Basic structure
1.1 Layout and objects
The layout will stay quite simple all through the tutorial.
It is based on the following elements :
- The select menu and a "Start" button at top. These will be our trigger for starting a dialog. In a real game, this would be done by clicking on a PNJ for example.
- The text output (the focused element in the screen capture) will display the text here. In a real game, this could be a Sprite Font, or anything really, events will just evolve a little depending.
- The "Next" button will only be visible when the dialog currently displayed has a next dialog. In a real game, this would be a blinking arrow, or an "Press enter to continue".
Some other objects are used but don't show, such as :
- CSV Plugin. Only particularity is that it is set to ";" as a separator, for a better handle by excel.
- AJAX. It is essential to load project files, and the dialog will be in an external CSV.
- Function. I renamed it "F" for shorter events later.
At last, there is the CSV Dialog file. I only imputed 2 dialog, each made of 3 screen of text letting us know which dialog is currently displayed :
It's really simple to use, you can modify it in text mode too (notepad ++ is your friend), and will let us add more columns in the future parts.
First of all, we have to load the database : let's use the CSV !
The code is commented, but I'll add some explanation on event 4 : I just constructed a string to display in the menu what dialog you are selecting.
1.3 Starting the Dialog
Now that the menu is ready, we will add some controls on the elements.
From now on, I'll make heavy use of the Function object, as it will make things easier in the next parts for adding elements.
Remember the CSV ? Take a look back if you don't. The first column is used as a row name, and I call it the ID of the dialog. You should be sure that you keep each line with an increment in the CSV file, as I'll keep this as a principle in the next parts.
The event 8 is the global function that is made to handle the dialog, the only one you'll be supposed to use when programming the rest of the game. It would be made public in object languages, as opposed to the other functions that would be private (only used in the dialog handling itself).
For example, if you have a PNJ that talks when you are near him, PNJ.DialogID being the ID of the dialog for this PNJ, you'll just have to have an event :
If Distance(player,PNJ) < 2 m
Trigger once while true
This function is very important. It is to be completed with all the different types of dialogs, like multiple choices or special effects ... (next parts ;D)
When it comes to a module that you are likely to use in multiple projects, it's better to be the more formal possible.
The event 9 checks if the dialog is a "Speach" dialog by calling a function named "Get_Dialog", passing it the first param received : the dialogID, and asking for the "Type" column. I find it a lot easier to read to have some simple functions that do that kind of job. The function is quite simple, it just uses the parameters to return the value in the CSV. It is just convenient for reading later, and let you modify the CSV if you ever what to. Here is how this function goes :
1.4 Displaying the Dialog
In the 1.3, we didn't do a thing in the end, just called a function we didn't write yet, that should handle the display of a "Speach" type dialog.
What I call a "Speach" dialog is a simple dialog of 1 to 3 pages of text, said by the same PNJ in order.
As we want to keep in mind there will be other types of dialog, we have to choose useful variables.
Those are going to be static/global as a dialog won't occur in just 1 tic. Having the dialog ID seems essential, as well as the current state of the dialog, to keep record of where we are.
Side Note : This isn't fully optimized, it would require to have the variables stocked on the output object, to handle multiple dialogs at once, but we will see this later. For now, the variables seems enough.
Every step of displaying the dialog should then be the same :
Display current page of text
If next page of text exist and isn't empty
Then show a button that will allow the player to go to the next text
Else this is the end of the dialog
Display current page of text requires to use the previous function (Get_Dialog) to retrieve the text, and then output it.
If next page of text exist and isn't empty will need us to know the name of the next page. Take another look at the CSV :
The first page is "Part1", second is "Part2" and third is "Part3". We can then make a function "Speach_NextPart" that would return the name of the next part, based on the name of the current part :
We can now check the text of the next page, see if it exists and isn't empty !
Then show a button that will allow the player to go to the next text is as simple as it sounds : set the "next" button visible.
Else this is the end of the dialog need us to hide the "next" button as no more dialog is to be displayed for now. Alternatively, we could add a "end" button that hides the dialog.
The "next" button should just increment the current state of the dialog (Part1->Part2->Part3->none).
Here is how it goes then :
Last, we will handle the initialization of the speach, the function we called in the 1.3. With what we've got now, it's just setting the system up. Let's set the variables right and call the first "Speach_Step" to handle it !
As this is a "Speach" type of dialog, the first step is the "Part1", and, if we take a look back to how we called the Initialize_Speach function, we received the dialogID as a parameter.
1.5 First part conclusion
This first part is now over. You can download the current capx in the sidebar.
Here is also the output as it is. Not a lot of dialog, what's important is the structure for now.
We have now a first system of dialog, simple output function of a speech by a PNJ or a menu, ... If you want to copy past it in your project, first add the objects I used (all of them) in a layout where you want the dialog to work, and copy/past then import the event sheet. You may have to rename the objects, but I tried to use some kind of namespace.
Next time, we will expend on the dialog types.
This style of tutorial could be interesting mostly if you participate in the comments, asking questions or giving ideas for more additions in the parts to come.
I'll update with the next parts in the upcoming days and weeks, so feel free to check back !
PS : just saw I didn't write "Speech" right in the code... Not native ^^ sorry