Legacy GM Easy Branching Dialogue System

S

ShadowMan

Guest
GM Version: GMS 1.4+
Target Plateform: Any
Dialogue v1.21 EXE+GMZ: (2.9mb)DialogueGMS_v1.21 (713kb)DialogueSource
Required Extension: none
Required DLL: none
Manual(9 Pages): https://www.dropbox.com/s/uuww52f73ff7kr7/Manual.docx?dl=0
Example: (24kb) https://www.dropbox.com/s/ht8j4vo0ssi25uy/Example1_21.gmz?dl=0

Video:


I highly recommend skimming over the manual before trying anything!

This program, paired with the example, is supposed to make branching dialogue systems easy to make in Game Maker Studio. Most help that people have given on the forums is a “do it yourself” with a couple of links to things they thought might be useful. While there are some branching dialogue systems floating around there for Game Maker Studio, none of them were satisfactory for my tastes. It would be really hard for a novice to easily obtain/make a branching dialogue system. It would also take a considerable amount of time for anyone else, who wanted to easily make a branching dialogue system, to create one. This project can be both used by novices and advanced users.

The main bulk of the tutorial is located in the Manual! So please take if something does not make sense.
Looking over the tutorial example will also help you implement this dialogue system into your game!

If you run into a bug with the program, or just need help please do not hesitate to message me!
If you have any suggestions for future improvements or any complaints, direct them towards me



Update 1.2!
Highly improved text-box functionality! You can now highlight, click, drag, cut, copy, paste whatever you want into the text-boxes! If you want to know how it works, the code is publicly available in the GMZ download!
There were also a couple of minor bug fixes (certain arrangements would not export properly)

Update 1.21!
https://forum.yoyogames.com/index.php?threads/easy-branching-dialogue-system.707/#post-8207
Greetings! I just started school for video game design and I had an idea for dialogue, but I wasn't sure where to go or who to ask. Maybe you, or someone reading this could assist. I am designing a RPG game that requires character interaction, but I want to avoid that style where the NPC speaks, and then the player is given a list of responses to choose from. Instead, I would like to go back to the more interactive style common in classic games where the player's character encounters a NPC and two dialogue boxes appear; one the player's, the other's NPC. In the NPC dialogue box will say something like "greetings traveler" or another greeting (friendly or otherwise). Now the player gets to type in his or her dialogue box a response--any response he or she feels like. I understand it's a lot of work as there are so many responses, words, topics, a player can type, but this freedom of speech and interaction is critical for the goal of this character-based video game. I am not looking for a pure text adventure, but a visual RPG that uses text-based adventure elements in a conversation style with NPCs. Thank you in advance for any advice or program suggestions that would allow this. :)
 
Greetings! I just started school for video game design and I had an idea for dialogue, but I wasn't sure where to go or who to ask. Maybe you, or someone reading this could assist. I am designing a RPG game that requires character interaction, but I want to avoid that style where the NPC speaks, and then the player is given a list of responses to choose from. Instead, I would like to go back to the more interactive style common in classic games where the player's character encounters a NPC and two dialogue boxes appear; one the player's, the other's NPC. In the NPC dialogue box will say something like "greetings traveler" or another greeting (friendly or otherwise). Now the player gets to type in his or her dialogue box a response--any response he or she feels like. I understand it's a lot of work as there are so many responses, words, topics, a player can type, but this freedom of speech and interaction is critical for the goal of this character-based video game. I am not looking for a pure text adventure, but a visual RPG that uses text-based adventure elements in a conversation style with NPCs. Thank you in advance for any advice or program suggestions that would allow this. :)
Unfortunately, this system is not setup for that kind of dialog. If you are looking for an easy way to get "freedom of speech" in your video game, then you are out of luck. Many game developers opt out of giving the player too many options that will affect the story later down the line, as it would cause an unimaginable amount of branching
If you want a simple solution, using the string_count(substr,str) to search for things in the user's input, like "store" or "fight"-- and then using a switch statement to determine what the npc should do
Another solution, although I haven't seen it done in GM, is by using neural networks. Building one from scratch is very difficult.
 
A

acidhoover

Guest
hy Noobswestand

i love it really good idea and yoü did it great...büt i have problems i downloadet it and did some dialoüges then i export it and load the txt file in the inclüded files büt then what?? i did make a new room püt the obj_player and obj_npcbob in the room büt nothing happens what do i wrong??plz help me
 
M

mjmiller1824

Guest
One option would be to use something like the "Stupid Backoff" method of text prediction, build a corpus of conversations in games and text messages (corporate customer service chats would be perfect for this if you can find them because they're so structured). Then do a frequency count of n-grams in responses. You would do this in something like R, Java, or python first and use the Stupid Backoff algorithm to come up with a list of reasonable responses and save them as a text file. You would have to limit your characters starting options but this would give your conversation a tone that the player should follow. So the idea is:

NPC: Hey

Char: Hello, my name is Kevin.

program tries to find "Hello my name is Kevin". it can't so it searches for "my name is Kevin" (and I would probably have a list of names so that the game can identify when you're using a name at the end and exclude it from the ngram search) It find's "my name is Kevin"

the most common response is "Hello Kevin, how are you?"

So the NPC says "Hello Kevin, how are you"

but I'm not sure how to make this work in GM outside of an external plugin written in Java or something like that. And all of the heavy lifting with processing the corpus would have to be done ahead of time. Google uses something like 2 trillion phrases in their model. And they have massive amounts of server power to do it. But you could limit it to the top like 300 responses for each NPC which would give you something like 80% coverage simulating an actual conversation.
 
A

Atra

Guest
SO i have an idea for a game with a branching dialogue system. You could say it is completely dependend on it and i find your solution for the branching paths interesting. But one thing is nagging me and i am not smart enough to figure it out by myself ^^"

Would it be possible that the Questions in the switch box, are transported outside of the box itself and be its own clickable Box with its own connected paths? With its own gui etc.? I dont know if i made it clear so let me give an example of the idea^^

Current:
Do you like me?

1. Yes
2. No

Idea

Do you like me?
______________
I............................I
I...........Yes...........I
I______________I


______________
I............................I
I...........No............I
I______________I
 

GMWolf

aka fel666
Its a difficult task, but blur unsurmountable.

First build a I've dictionary to replace words with generics. ( so 'hi, where am I?', would become 'hello, where am player?')

Next remove any words you don't know/care about. So 'hi, where am player' becomes 'where player'

Next, match against pattern database. Needs to be pretty big!

To make this simpler, make sure you try to build a dictionary to natches the most words, to as little generics as possible. This will allow you to build up only the patterns you want.

This can become very interesting if you allow your system to generate patterns as the player does things. Far more complex however.


Not a perfect approach, but probably the best you can do within a game.

[Edit] I think I replied to the wrong thread ^^
 
Last edited:

Mick

Member
This branching dialogue system is great, thanks for making it available for others! I changed the editor so the different types of boxes have their unique colours (visible in the gif), makes things clearer. When testing out the editor I might have found a bug, if you check the gif, you can see that the second switch don't give the options "Yes" and "No" like it should I guess?



The colours are implemented like this (just add the code to the start of the event scripts, very simple):

objNode create:
Code:
color_type[0]=$71ae68; // textbox
color_type[1]=$5353c1; // scriptbox
color_type[2]=$c18e53; // switchbox
color_type[3]=$d26db4; // checkbox
objNode draw:
Code:
color = color_type[clamp(type,0,3)]
 
Last edited:

Mick

Member
Also, @NoobsWeStand, is there a good way to make alternatives in the switches show and hide depending on some value? For example if the player has an item then a switch alternative is shown that otherwise would be hidden.
 
Unfortunately, these requests for a more versatile dialog system, where the user can enter anything, is not within the scope of this project.
Hopefully this video can shed some light on how you might implement such a system:

SO i have an idea for a game with a branching dialogue system. You could say it is completely dependend on it and i find your solution for the branching paths interesting. But one thing is nagging me and i am not smart enough to figure it out by myself ^^"

Would it be possible that the Questions in the switch box, are transported outside of the box itself and be its own clickable Box with its own connected paths? With its own gui etc.? I dont know if i made it clear so let me give an example of the idea^^

Current:
Do you like me?

1. Yes
2. No

Idea

Do you like me?
______________
I............................I
I...........Yes...........I
I______________I


______________
I............................I
I...........No............I
I______________I
This shouldn't be too hard. All you have to do is edit the code around line 66, where it says, "//draw options"
Here is some example code, so you can compare the two and see the differences:
Code:
///textBox2
if showText=true{
    var xx,yy,ww,hh;
    xx=global.gui_width-672 yy=global.gui_height-160  ww=382 hh=96
 
    //Draw the box
    draw_set_alpha(0.70)
    draw_set_color(c_black)
    draw_rectangle(xx, yy, xx+ww, yy+hh, false)
    draw_set_alpha(1)
 
    //Draw the Name
    draw_set_valign(fa_top)
    draw_set_halign(fa_center)
    draw_set_font(fnt_chat)
    draw_text_shadow_color(xx+34,yy+10,name, c_aqua)
    xx+=32 ww-=32

    //Draw the Main Line
    var p=string_pos("|",line[on0,on1]);//Get rid of the commands
 
    var str="";
    if p=0{
        str=line[on0,on1]
    }else{
        str=string_copy(line[on0,on1],1,p-1)
    }
 
    //typewriter effect
    if dialougeTextOn<string_length(str){
        dialougeTextOn++
        if dialougeTextOn%3==0{
            dialougeTalk=!dialougeTalk
        }
    }else{
        dialougeTalk=0
    }
    str=string_copy(str,1,dialougeTextOn)
    draw_text_shadow_color_ext(xx+(ww/2)-8,yy+28,str,20,ww-44, c_black, c_white)
 
    //Draw options
    if ds_exists(op0[on0,on1],ds_type_list) && ds_list_size(op0[on0,on1])>0{
        var _yy=yy+(string_height_ext(line[on0,on1],25,ww)+60);
        for(i=0;i<ds_list_size(op0[on0,on1]);i++){
            if !scr_GUIhover(xx-32,_yy,xx+ww,_yy+24){
                draw_set_alpha(0.70)
                draw_set_color(c_black)
                draw_rectangle(xx-32, _yy, xx+ww, _yy+20, false)
                draw_text_shadow_color(xx+(ww/2),_yy,
                ds_list_find_value(op0[on0,on1],i),merge_color(c_blue,c_aqua,0.5))
            }else{
                if mouse_check_button(mb_left){
                    draw_set_alpha(0.70)
                    draw_set_color(merge_color(c_dkgray, c_black, 0.75))
                    draw_rectangle(xx-32, _yy, xx+ww, _yy+20, false)
                    draw_text_shadow_color(xx+(ww/2),_yy,
                    ds_list_find_value(op0[on0,on1],i),merge_color(c_blue,c_aqua,0.5))
                }else{
                    draw_set_alpha(0.70)
                    draw_set_color(merge_color(c_dkgray, c_black, 0.5))
                    draw_rectangle(xx-32, _yy, xx+ww, _yy+20, false)
                    draw_text_shadow_color(xx+(ww/2),_yy,
                    ds_list_find_value(op0[on0,on1],i),merge_color(c_blue,c_aqua,0.5))
                }
            
                if mouse_check_button_released(mb_left){
                    scrNPCCDialogOption(i)
                    dialougeTextOn=0
                    break;
                }
            }
            _yy+=24
        }
    }else{
        //draw the Continue button
        if !scr_GUIhover(xx-32, yy+hh+4, xx+ww, yy+hh+24){
            draw_set_alpha(0.70)
            draw_set_color(c_black)
            draw_rectangle(xx-32, yy+hh+4, xx+ww, yy+hh+24, false)
            draw_text_shadow_color(xx+(ww/2)-16,yy+hh+6,"Click here to continue",merge_color(c_blue,c_aqua,0.5))
        }else{
            if mouse_check_button(mb_left){
                draw_set_alpha(0.70)
                draw_set_color(merge_color(c_dkgray, c_black, 0.75))
                draw_rectangle(xx-32, yy+hh+4, xx+ww, yy+hh+24, false)
                draw_text_shadow_color(xx+(ww/2)-16,yy+hh+6,"Click here to continue",merge_color(c_blue,c_aqua,0.5))
            }else{
                draw_set_alpha(0.70)
                draw_set_color(merge_color(c_dkgray, c_black, 0.5))
                draw_rectangle(xx-32, yy+hh+4, xx+ww, yy+hh+24, false)
                draw_text_shadow_color(xx+(ww/2)-16,yy+hh+6,"Click here to continue",merge_color(c_blue,c_aqua,0.5))
            }
            if mouse_check_button_released(mb_left){
                if dialougeTextOn<string_length(str){
                    dialougeTextOn=string_length(str)
                }else{
                    scrNPCDialogContinue()
                    dialougeTextOn=0
                }
            }
        }
    }
}

draw_set_alpha(1)
draw_set_color(c_white)
Here is what it looks like in game:




This branching dialogue system is great, thanks for making it available for others! I changed the editor so the different types of boxes have their unique colours (visible in the gif), makes things clearer. When testing out the editor I might have found a bug, if you check the gif, you can see that the second switch don't give the options "Yes" and "No" like it should I guess?



The colours are implemented like this (just add the code to the start of the event scripts, very simple):

objNode create:
Code:
color_type[0]=$71ae68; // textbox
color_type[1]=$5353c1; // scriptbox
color_type[2]=$c18e53; // switchbox
color_type[3]=$d26db4; // checkbox
objNode draw:
Code:
color = color_type[clamp(type,0,3)]
That is because the checks have to lead to either another switch, or a text box. They cannot only lead to a script that doesn't have anything else connected to it. I will probably make it so you can do that type of behavior later, but for now, you cannot
Never mind! I just checked and it seems like you can do this, but in your case, you needed your scripts to look like this: "sleep()", instead of "sleep". Although, there might be some weird behaviour if you do not connect the scripts to anything else

As for the alternative switch statements depending on the player has an item, I would do something like this:

Although right now there is a bug where you cannot have have the convo(questID,QuestON) in an if statement.

Thanks for the suggestion! I like the colors, and it makes it easier to follow along!

I will work on the bugs tonight and tomorrow and hopefully fix them all and release a new version soon


edit: Here is a quick patch. v1.24
Downloads: exe(3mb) source(716kb) example(185kb)
Changes:
-Fixed that bug that would not allow the command "convo(QuestID,QuestON)" to work within an if statement in a script
-Fixed many graphical bugs
-Optimizations with larger projects--allows for many more nodes to be present at one time
-Added in the cool color patch that Mick suggested, and provided code for!
-Dynamic camera scrolling with zoom level added for arrow keys
-Update the example to include the save files
 
Last edited:
T

TheEnderPrime

Guest
Hi! I am trying to add your branching dialogue system into a game I have been working on for a while now. I am hitting some road blocks when it comes to integrating your system. I am wondering if you have a list of your variables and what they do hidden somewhere? For instance, I have a quest variables already but it works differently then yours and I am trying to get them to match up. So if you have any descriptions on your quests variables (checkQuest, checkOn, checkText) these would be immensely helpful to me! Thanks!
 
Hi! I am trying to add your branching dialogue system into a game I have been working on for a while now. I am hitting some road blocks when it comes to integrating your system. I am wondering if you have a list of your variables and what they do hidden somewhere? For instance, I have a quest variables already but it works differently then yours and I am trying to get them to match up. So if you have any descriptions on your quests variables (checkQuest, checkOn, checkText) these would be immensely helpful to me! Thanks!
checkQuest, checkOn, and checkText in parNPC are just used for determining which dialog tree to jump to when starting a conversation, based on the quest state. For the most part, you do not have to worry about these variables

Depending on how yours is set up will determine how hard it is to transfer mine to yours, or vise versa
As for mine, it is fairly simple and straight forward. All the quest information is stored in an array setup in objControl in the create event as such:
Code:
//QuestInfo
for(i=0;i<100;i++){
    quest[i]=0 //stores the quest info
}
Each quest state is stored in a position in this array.
So if I set quest[0]=1, then if an NPC has a "convo" of (0,1), then it will automatically search for the first Node in the conversation

I am not entirely sure what you needed-- so I hope this helps
 
B

Buzz Killdrin

Guest
Hi
I've been planning on using your dialog system for a couple of days now and I'm really excited to replace the dialog code that I have with yours, but the nature of the game I'm working on makes it too convoluted to be able to use your dialog program as-is. I figure I have to adapt it first (as I understand, you're fine with that) but I haven't managed to get a good grasp on the source code for it. The manual is enough to teach me how to play around with the example game you uploaded, but the documentation for the code isn't enough to understand it.

I wouldn't ask anything like an in depth explanation on how the system works, that's crazy, but if you already posted more info on it somewhere else that would be an awesome read.
 
Hi
I've been planning on using your dialog system for a couple of days now and I'm really excited to replace the dialog code that I have with yours, but the nature of the game I'm working on makes it too convoluted to be able to use your dialog program as-is. I figure I have to adapt it first (as I understand, you're fine with that) but I haven't managed to get a good grasp on the source code for it. The manual is enough to teach me how to play around with the example game you uploaded, but the documentation for the code isn't enough to understand it.

I wouldn't ask anything like an in depth explanation on how the system works, that's crazy, but if you already posted more info on it somewhere else that would be an awesome read.
You can do whatever you want with it
The documentation thing is my fault. I have to comment on everything more - especially with the example
I am planning on working on it this weekend. I also have BB textbox commands coming up, but it still needs some kinks ironed out
 
Last edited:
D

DonyThePony

Guest
Hey Awesome Thing and it was very easy and clean to install it into my Project.
I have a Question. Is it possible to colorize some Words or to set some Cool Effects in the Editor? Like Waving etc.

- DonyThePony
 
Hey Awesome Thing and it was very easy and clean to install it into my Project.
I have a Question. Is it possible to colorize some Words or to set some Cool Effects in the Editor? Like Waving etc.

- DonyThePony
As stated above, I am working on that right now! The update is coming this week, so keep an eye on this topic

I still have to add waving and shaking text options
 

mycelia

Member
Thanks for the awesome system, and I'm looking forward to the update! Quick question -- I want to have the dialog trigger when the player hits space within a certain distance of the NPC (using distance_to_object), rather than just on collision. I figure it's got something to do with showText and showText2, but I can't for the life of me figure out what to do with them. Any chance you could let me know what I need to change?

edit: Also, I don't know if anyone's interested, but I prefer a keyboard control system so I added a couple of things to my parNPC script, in the Draw function. It uses X to continue and the number keys to pick dialog options. I'll put it here; I haven't tested it thoroughly but it's working so far. Note that I spell it 'dialogue', so find+replace if you've got the variables and scripts as dialouge.

Code:
///textBox
event_inherited();

//draw the TextBox
if showText=true{
    var xx,yy,ww,hh;
    xx=30 yy=global.gui_height-200  ww=350+32 hh=150
    //Fancy outlines
    draw_set_alpha(1)
    draw_set_font(fnt_chat)
    draw_set_alpha(0.8)
    draw_set_color(c_dkgray)
    draw_rectangle(xx,yy,xx+ww,yy+hh,false)
    draw_set_alpha(1)
    draw_set_color(c_black)
    draw_rectangle(xx,yy,xx+ww,yy+hh,true)
  
  
    //Draw the Face
    if dialogueSprite!=-1 && sprite_exists(dialogueSprite){
        draw_sprite(dialogueSprite,dialogueTalk,xx+5,yy+(hh/2)-(sprite_get_height(dialogueSprite)/2))
    }else{
        draw_sprite(sprNPCUnkown,0,xx+5,yy+(hh/2)-(sprite_get_height(dialogueSprite)/2))
    }
  
    //Draw the Name
    draw_set_halign(fa_center)
    draw_set_color(c_black)
    draw_text(xx+5+16+1,yy+(hh/2)+(sprite_get_height(dialogueSprite)/2)+1,name)
    draw_set_color(c_white)
    draw_text(xx+5+16,yy+(hh/2)+(sprite_get_height(dialogueSprite)/2),name)
  
    xx+=32 ww-=32
  
  
    //Draw the Main Line
    var p=string_pos("|",line[on0,on1]);//get rid of the commands
    draw_set_halign(fa_center)
    draw_set_color( c_black );
  
  
    var str="";
    if p=0{
        str=line[on0,on1]
    }else{
        str=string_copy(line[on0,on1],1,p-1)
    }
  
    //typewriter effect
    if dialogueTextOn<string_length(str){
        dialogueTextOn++
        if dialogueTextOn%3==0{
            dialogueTalk=!dialogueTalk
        }
      
    }else{dialogueTalk=0}
    str=string_copy(str,1,dialogueTextOn)
  
    draw_text_ext(xx+(ww/2)+1,yy+16,str,25,ww-xx)
    draw_set_color( c_white );
    draw_text_ext(xx+(ww/2),yy+15,str,25,ww-xx)
  
  
    //draw options
    if ds_exists(op0[on0,on1],ds_type_list) && ds_list_size(op0[on0,on1])>0{
        var _yy=yy+(string_height(line[on0,on1])+30);
      
        for(i=0;i<ds_list_size(op0[on0,on1]);i++){
            currentDialog= string(i+1); //Make the number of dialog options into a string that we can reference in keyboard_check_pressed.
            if !scr_GUIhover(xx+5,_yy,xx+ww-5,_yy+19){
                draw_text_shadow_color(xx+(ww/2),_yy,
                ds_list_find_value(op0[on0,on1],i),merge_color(c_blue,c_aqua,0.5))
                if keyboard_check_pressed(ord(currentDialog)){ //Use the number keys to select an option

                    scrNPCCDialogOption(i)
                    dialogueTextOn=0
                    break;
                  
                }
            }else{
                if mouse_check_button(mb_left){
                    draw_text_shadow_color(xx+(ww/2),_yy,ds_list_find_value(op0[on0,on1],i),c_white)
                }else{
                    draw_text_shadow_color(xx+(ww/2),_yy,ds_list_find_value(op0[on0,on1],i),c_ltgray)
                }
              
                if mouse_check_button_released(mb_left){
                    scrNPCCDialogOption(i)
                    dialogueTextOn=0
                    break;
                }
            }
            _yy+=20
        }
      
    }else{
        //draw the Continue button
        if !scr_GUIhover(xx+5,yy+hh-25,xx+ww-5,yy+hh){
            draw_text_shadow_color(xx+(ww/2),yy+hh-20,"Click here to continue",merge_color(c_blue,c_aqua,0.5))

                if keyboard_check_pressed(ord("X")){ //Keyboard control to advance text
                  
                        if dialogueTextOn<string_length(str){
                        dialogueTextOn=string_length(str)
                            }else{
                        scrNPCDialogContinue()
                        dialogueTextOn=0
                }
            }
      
        }    else
            {
                if mouse_check_button(mb_left){
                  draw_text_shadow_color(xx+(ww/2),yy+hh-20,"Click here to continue",c_white)
                }   else{
                    draw_text_shadow_color(xx+(ww/2),yy+hh-20,"Click here to continue",c_ltgray)
                }
                if mouse_check_button_released(mb_left){
                    if dialogueTextOn<string_length(str){
                        dialogueTextOn=string_length(str)
                    }else{
                        scrNPCDialogContinue()
                        dialogueTextOn=0
                }
            }
        }
    }
  
}
 
Last edited:
D

DonyThePony

Guest
Go To your Parent Object of your NPC's
Then in the Step Event.
There is an if Statement This one:

if showText2=true{
if place_meeting(x,y,Player){

Change it to:

if showText2=2{
if(place_meeting(x,y,Player) && keyboard_check_key_pressed(vk_space))

This could be the Solution for it.
 

mycelia

Member
Thanks, but unfortunately that just makes the text box pop up for a half-second before disappearing. keyboard_check keeps it open for as long as I'm holding it, so I'm thinking that's a clue. I'll keep experimenting.

edit: Haha! Found it! In the Create event, showText2 is set to true. Changing it to false, along with the fixes as proposed by @DonyThePony, solved it.
 
Last edited:
@mycelia and @DonyThePony
The reason why there is 2 variables for controlling if the textbox is shown or not, is that if you have a script node containing "showChat", it will cut off the dialog, and stop displaying it. However, the player will most likely still be colliding with the NPC, so it toggles showText2 to false. In order for showText to become true, is if showText2 is true. showText2 can only become true if the player is colliding with the NPC and also presses the space key. This logic can be found in the parNPC in the normal step event.

As for the distance, instead of colliding with the player, you can simply replace the code in the step event of parNPC with this:
Code:
///DistanceToPlayer
[IMG]https://www.dropbox.com/s/qrwtpikmna3lzfl/BBText.png?dl=1[/IMG]

var nn=instance_nearest(x,y,objPlayer);
if showText2=true{
    if point_distance(x,y,nn.x,nn.y)<50{
        showText=true
    }else{
        showText=false
    }
}else{
    showText=false
    if keyboard_check_released(vk_space)
    && point_distance(x,y,nn.x,nn.y)<50{
        showText2=true
    }
}

And there is an update (v1.25)!
This update mainly focuses on cool new text effects for the text box! These effects work just like they do on the forums. [command=value]Hello World![/command]



Here is the list of commands that can be used (can also be found in the manual):
[color=c_red]

Changes the color of the text. You can either use GM’s c_ values, or put your own hex with $ infront of it (eg. $4455ed)

[font=fnt_name]

Changes the font. The font must exists in your game as an asset

[alpha=0.75]

Changes the alpha value of the text

[speed=0.1]

Changes the speed of the typewriter effect

[waveA=1]

Changes the wave amplitude

[waveF=1]

Changes the wave frequency

[waveO=25]

Changes the offset of the wave effect per character

[shake=1]

Shake amount in both X+Y

[shakeX=3]

Shake amount in only the X direction

[shakeY=2]

Shake amount in only the Y direction

[hsv=1]

Shifts through the HSV values at the given rate. This will override the [color] tag

I have also tried to add useful comments in the Example to help people out.

Downloads:
Source (720kb)
EXE (3MB)
Example (190kb)
 
K

KitKatKatu

Guest
I'm trying to figure something out. What I'm hoping for is:

Switch: Did you find my glasses?
1: Yes
----------Script: Does the player have glasses in their inventory?
----------1: Yes
--------------------Text: Thank you!
----------2: No
--------------------Text: No, that's not them.
--------------------Text: They should be somewhere in this room!
2: No
Text: They should be somewhere in this room!

Right now I can get the item to disappear from their inventory, but I don't want them to say "Thank you!" if the item isn't there.
 
Last edited by a moderator:
I'm trying to figure something out. What I'm hoping for is:

Switch: Did you find my glasses?
1: Yes
----------Script: Does the player have glasses in their inventory?
----------1: Yes
--------------------Text: Thank you!
----------2: No
--------------------Text: No, that's not them.
--------------------Text: They should be somewhere in this room!
2: No
Text: They should be somewhere in this room!

Right now I can get the item to disappear from their inventory, but I don't want them to say "Thank you!" if the item isn't there.
Maybe something like this:

Note that you have to "pin" the switch statement, so it starts out there. Otherwise the system will think the text node that says, "No, that's not them." is the first node in the conversation!


To do this you also have to update to the latest version! I added a label and goto commands for an easier alternative to the confusing "convo" system!
The above picture should be a great example of how to use them!

label(str)
This will set a pointer in the dialog tree, so when you call “goto(str)”, it will automatically find the label, and jump to that Node

goto(str)
This will jump to the corresponding label. If the label does not exist, the editor will tell you



Downloads:
EXE (3mb)
Source (720kb)
Example (190kb)
 
Last edited:
B

Buzz Killdrin

Guest
Possible dumb question
Is this how your dialog system finds it's next 2d array row positions?

EBDS.jpg

As the text suggests, I'm thinking that array row index progression follows the first option in every branch until the branching stops, then moves to the next branch. At that point the row index skips a number, presumably so that the algorithm knows the branch ended (?).

To clarify, all the numbered nodes in the tree are switch nodes so it's implied that the column index of the 2d array of each node is 0.
 
K

KitKatKatu

Guest
Maybe something like this:

Note that you have to "pin" the switch statement, so it starts out there. Otherwise the system will think the text node that says, "No, that's not them." is the first node in the conversation!


To do this you also have to update to the latest version! I added a label and goto commands for an easier alternative to the confusing "convo" system!
The above picture should be a great example of how to use them!

label(str)
This will set a pointer in the dialog tree, so when you call “goto(str)”, it will automatically find the label, and jump to that Node

goto(str)
This will jump to the corresponding label. If the label does not exist, the editor will tell you



Downloads:
EXE (3mb)
Source (720kb)
Example (190kb)
Thank you so much!! Yes, I think this will do the trick!
 
Possible dumb question
Is this how your dialog system finds it's next 2d array row positions?

As the text suggests, I'm thinking that array row index progression follows the first option in every branch until the branching stops, then moves to the next branch. At that point the row index skips a number, presumably so that the algorithm knows the branch ended (?).

To clarify, all the numbered nodes in the tree are switch nodes so it's implied that the column index of the 2d array of each node is 0.
That is almost exactly how it does it! Although, it uses a much simpler system to find when the branching stops, and when to move to the next branch.

As you know, everything is stored in a 2D array. text[on0,on1]. When you click the "continue" button, for a non-branching dialog option, then it will simply increment on0 by one. If text[on0+1,on1] does not contain anything, then the NPC will stop talking, and the interface will close.

If there is a branch in the dialog, then it will reset on0 to 0, and in on1 will then increment by one.
The example and Dialog editor have no idea where it will go next. All they do is follow some very simple instructions. When there is a branching dialog option, the editor will export which line to jump to, and all they have to do is follow it
You can actually open up what the dialog editor exports and read how it works
 
B

Buzz Killdrin

Guest
That is almost exactly how it does it! Although, it uses a much simpler system to find when the branching stops, and when to move to the next branch.

As you know, everything is stored in a 2D array. text[on0,on1]. When you click the "continue" button, for a non-branching dialog option, then it will simply increment on0 by one. If text[on0+1,on1] does not contain anything, then the NPC will stop talking, and the interface will close.

If there is a branch in the dialog, then it will reset on0 to 0, and in on1 will then increment by one.
The example and Dialog editor have no idea where it will go next. All they do is follow some very simple instructions. When there is a branching dialog option, the editor will export which line to jump to, and all they have to do is follow it
You can actually open up what the dialog editor exports and read how it works
Sweet
Also thanks for the text labeling system you showed KitKatKatu, that makes conditional dialog replies much more convenient than what I was about to try.
One thing I've noticed about it though is that, if you link a branch that's not connected directly to the main tree from the out of the last node in it with the in of a switch node that's supposed to be accessed before said branch, like the "no, that's not them" branch is looped back to the "did you find my glasses" switch node, and you have more than 1 'if' statement nodes that directs to multiple unconnected branches through different labels, the text line that will be displayed is the one in the last unconnected branch that loops back into the switch node --- if the 'loose' branches don't loop back to the switch node, or if only the first one does, then the dialog works correctly.

I managed to make word salad of the post so hopefully a screen shot will make better sense
Nodes 0,8 through 0,5 are what I referred to as 'loose' nodes that aren't part of the main dialog tree, like node 0,4 in KitKatKatu's example. In the screenshot all 4 are looped back into a start-of-dialog switch node that isn't visible in the pic. When they are looped like this, only the the bottom branch is displayed, the one with label(outcome5) -- if I 'unloop', say, the 4th branch, then only the branch that comes before it will be displayed, and so on.
So I'm wondering if I'm doing something wrong or if adding successive if statements like I did with scr_condition2,3,4,5 is outside the scope of the program.
EBDS2.jpg EBDS2.jpg
 
Sweet
Also thanks for the text labeling system you showed KitKatKatu, that makes conditional dialog replies much more convenient than what I was about to try.
One thing I've noticed about it though is that, if you link a branch that's not connected directly to the main tree from the out of the last node in it with the in of a switch node that's supposed to be accessed before said branch, like the "no, that's not them" branch is looped back to the "did you find my glasses" switch node, and you have more than 1 'if' statement nodes that directs to multiple unconnected branches through different labels, the text line that will be displayed is the one in the last unconnected branch that loops back into the switch node --- if the 'loose' branches don't loop back to the switch node, or if only the first one does, then the dialog works correctly.

I managed to make word salad of the post so hopefully a screen shot will make better sense
Nodes 0,8 through 0,5 are what I referred to as 'loose' nodes that aren't part of the main dialog tree, like node 0,4 in KitKatKatu's example. In the screenshot all 4 are looped back into a start-of-dialog switch node that isn't visible in the pic. When they are looped like this, only the the bottom branch is displayed, the one with label(outcome5) -- if I 'unloop', say, the 4th branch, then only the branch that comes before it will be displayed, and so on.
So I'm wondering if I'm doing something wrong or if adding successive if statements like I did with scr_condition2,3,4,5 is outside the scope of the program.
At first look, this might be a bug with exporting. I will take a look at it tomorrow, and see what is up. I think it should work, but I am not entirely sure why it is not working for you
If you could also give me the file (through PM), that would also help greatly!
 
Okay! Update time! v1.26!

Downloads:
EXE (3mb)
Source (725kb)
Example (200kb)



Added)
-Syntax Highlighting for scripts and text (can be disabled with options)
-Highlight which text Node the dialog editor is one when testing
-New variable system and [var=xxx] tags!
-Go to Options -> Change Variables to access this new feature
-Just a simple DS Map, but it can be used for a more dynamic dialog system
-Example: Hello [var=playerName], my name is Bob!
-You can also change the variables in the ds_map with simple scripts!
-Example: playerName="Bob"
playerMoney+=999
-You can also check what is inside the ds_map with scripts:
-Example: if playerMoney<100{playerMoney+=1000}

Fixed)
-Fixed the previously stated bug


Note: to get the value of the variables inside the NPC, just do:
chatMap[?key], where "key" is your variable name
To set the variables outside the dialog, you can simply do chatMap[?key]=value


Also, I have to get better at this, but these are the objects/scripts you need to update in your current project to get all these new features!
draw_text_bb_ext_black_centered
draw_text_bb_ext_centered
load_npcChat
scr_npcDialogCommands
parNPC - Create Event ADD: chatMap=ds_map_create()
 
Last edited:
F

Frioniel

Guest
Hi, I'm using your script very well, but I got some problem

First is, can this system print different languages? such as japanese or chinese or korean

Second is, can I make dialogue with the object?(using Uses Physics function from GameMaker)
Well.. this one is the very basic problem using GameMaker not this system... (I used GameMaker only 6days...)
What I tried is.. meet Player in front of NPC, press button to talk.
For example, if space key pressed and Player's x position is NPC's x position - 32
then the textbox needs to appear, but didn't appear

are there any ways to solve this two problem?
-----------------------------------------------------------------------

After this post

I tried korean (my native language is korean)

Korean can be printed but some words don't print well, it prints blank

is it keyboard-string bug or i need to find out what is the problem
 
Last edited by a moderator:
S

shuikun0

Guest
Hi, I'm using your script very well, but I got some problem

First is, can this system print different languages? such as japanese or chinese or korean

Second is, can I make dialogue with the object?(using Uses Physics function from GameMaker)
Well.. this one is the very basic problem using GameMaker not this system... (I used GameMaker only 6days...)
What I tried is.. meet Player in front of NPC, press button to talk.
For example, if space key pressed and Player's x position is NPC's x position - 32
then the textbox needs to appear, but didn't appear

are there any ways to solve this two problem?
This do support CJK languages. As long as you have add the characters in the font. BTW, the draw_string_ext function in GMS doesn't support CJK for some reason. If you wanna know more about using CJK languages in GMS, I highly recommed you see this https://forum.yoyogames.com/index.php?threads/localizing-for-chinese.1555/.
Hope that can help you some how. Sorry for my poor English.
 
Hi, I'm using your script very well, but I got some problem

First is, can this system print different languages? such as japanese or chinese or korean

Second is, can I make dialogue with the object?(using Uses Physics function from GameMaker)
Well.. this one is the very basic problem using GameMaker not this system... (I used GameMaker only 6days...)
What I tried is.. meet Player in front of NPC, press button to talk.
For example, if space key pressed and Player's x position is NPC's x position - 32
then the textbox needs to appear, but didn't appear

are there any ways to solve this two problem?
-----------------------------------------------------------------------

After this post

I tried korean (my native language is korean)

Korean can be printed but some words don't print well, it prints blank

is it keyboard-string bug or i need to find out what is the problem
You could try to edit your fonts so that it includes a wider range of characters:
It looks like the Korean ascii values are from 40,000 to 50,000, although I am not entirely sure
You can also try font_add()

If you can get it to work, PM me or something. I will try to get it to work later this week
 
F

Frioniel

Guest
Thanks for the reply!
After your reply what I did is
try with font_add() and add code where fnt_default works
(I tried both, otf and ttf version of font)
4.png
3.png
and I'm sad to say, it still not prints well
*Explanation
7.png
this reply system indicates Korean as spam something so I replace with image

Also, has serious frame drop

minFPS, maxFPS, avgFPS
0, 73, 7

I think Korean Ascii is 44032~55203, there are too many words to compile, so it causes frame drop

After this, I tried the first one that you suggested in reply (add Ascii number to the font)

Actually, I tried before your reply(add Ascii number to the font)

what I really did is, I thought too many unnecessary Korean words between 44032~55203 causes missing words
6.png
so I just add few words
and the result is.. sadly

5.png
still, have missing words

Well.... I need to find out more ways to solve out, and this is what I did best to solve the problem currently
 
Last edited by a moderator:
M

Marmaduke

Guest
Hi I've been using your script recently and it's great! However when I tried to have to separate NPC's in the same room with their own dialogue it doesn't seem to work. The NPC that I place down first (and that gets loaded by the game first I assume) has the dialogue working fine but when I go to the second one the dialogue box pops open for a second and then closes. I can see the text is correct but it just wont stay open. I realise this is probably me making a stupid mistake and so would appreciate if you could help me out if you know of any solution. Thanks!
 
H

hoyakim

Guest
Thanks for the reply!
After your reply what I did is
try with font_add() and add code where fnt_default works
(I tried both, otf and ttf version of font)
View attachment 7317
View attachment 7316
and I'm sad to say, it still not prints well
*Explanation
View attachment 7320
this reply system indicates Korean as spam something so I replace with image

Also, has serious frame drop

minFPS, maxFPS, avgFPS
0, 73, 7

I think Korean Ascii is 44032~55203, there are too many words to compile, so it causes frame drop

After this, I tried the first one that you suggested in reply (add Ascii number to the font)

Actually, I tried before your reply(add Ascii number to the font)

what I really did is, I thought too many unnecessary Korean words between 44032~55203 causes missing words
View attachment 7318
so I just add few words
and the result is.. sadly

View attachment 7319
still, have missing words

Well.... I need to find out more ways to solve out, and this is what I did best to solve the problem currently
hi Frioniel.
I am glad to meet Korean people.
I also used this tool and experienced the same problem.

The problems and solutions are as follows.
Problem: Korean input can not be handled properly by game maker... This problem is not a problem with this tool.

Solutions :
Add Korean font to the source and recompile it. => Not displayed in an item such as an answer is displayed!
But The character is still missing during Korean input...
first In a program such as Notepad, write, copy and paste.

I solved it this way. It is a little inconvenient, but it is a problem of the GMS itself.
 
Q

Quailfail

Guest
Firstly, want to say thank you for the lovely dialogue branch engine, I have been experimenting with it but have been running into a few issues.

When Player collides into the NPC to chat, the first conversation goes well, but after the dialogue is finished and Player collides again to start a new conversation, it does not start up. Neither the dialogue that comes up when a Quest is unfinished or the dialogue when a Quest is finished will show. I've noticed if I skip the 1st dialogue that would "start" the Quest and just finish said Quest the 2nd dialogue (for completion) will pop up. I think there might be something amiss with collision as I can only get one conversation to happen per test run.

I will admit I am very new to this engine, I'm sorry if I'm asking anything that has an obvious answer.
 
S

shuikun0

Guest
Thanks for the reply!
After your reply what I did is
try with font_add() and add code where fnt_default works
(I tried both, otf and ttf version of font)
View attachment 7317
View attachment 7316
and I'm sad to say, it still not prints well
*Explanation
View attachment 7320
this reply system indicates Korean as spam something so I replace with image

Also, has serious frame drop

minFPS, maxFPS, avgFPS
0, 73, 7

I think Korean Ascii is 44032~55203, there are too many words to compile, so it causes frame drop

After this, I tried the first one that you suggested in reply (add Ascii number to the font)

Actually, I tried before your reply(add Ascii number to the font)

what I really did is, I thought too many unnecessary Korean words between 44032~55203 causes missing words
View attachment 7318
so I just add few words
and the result is.. sadly

View attachment 7319
still, have missing words

Well.... I need to find out more ways to solve out, and this is what I did best to solve the problem currently
Chinese works with no problem so Korean should be no problem. What l do is write all character in somewhere of the code and then click the plus button in font, choose add from code. Hope that helps.
 
T

Team Shinigami

Guest
Hi, quick question:

I copied all of the scripts in the Dialogue section into my game, but it gives me an error:
Code:
ERROR!!! :: ############################################################################################
FATAL ERROR in
action number 1
of Alarm Event for alarm 0
for object parNPC:


global variable <unknown built-in variable>(-1610512734, -2147483648) not set before reading it.
 at gml_Script_load_npcChat (line 2) - if !file_exists(global.NPCdirectory+"\"+string(argument[0])+".txt"){return 0}
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_load_npcChat (line 2)
called from - gml_Object_parNPC_ObjAlarm0_1 (line 8) - if load_npcChat(pid) = 1{
I was wondering how I would be able to fix it? It is stopping me from progressing further into my game, and it would be greatly appreciated if you could take some time to help me.

--Team Shinigami
 
Hi, quick question:

I copied all of the scripts in the Dialogue section into my game, but it gives me an error:
Code:
ERROR!!! :: ############################################################################################
FATAL ERROR in
action number 1
of Alarm Event for alarm 0
for object parNPC:


global variable <unknown built-in variable>(-1610512734, -2147483648) not set before reading it.
 at gml_Script_load_npcChat (line 2) - if !file_exists(global.NPCdirectory+"\"+string(argument[0])+".txt"){return 0}
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_load_npcChat (line 2)
called from - gml_Object_parNPC_ObjAlarm0_1 (line 8) - if load_npcChat(pid) = 1{
I was wondering how I would be able to fix it? It is stopping me from progressing further into my game, and it would be greatly appreciated if you could take some time to help me.

--Team Shinigami
I believe you have to set global.NPCdirectory.
By default, it should look something like this:
Code:
//The directory to store the exported .txt files
global.NPCdirectory="Dialog/"
This is just for organizational reasons-- to put all your dialog.txt's into a single folder

A better place to copy all the scripts from would be the Example project that is provided. Those are more clearly commented, and does not have the extra fluff of the editor stacked on top of it
 
T

Team Shinigami

Guest
I believe you have to set global.NPCdirectory.
By default, it should look something like this:
Code:
//The directory to store the exported .txt files
global.NPCdirectory="Dialog/"
This is just for organizational reasons-- to put all your dialog.txt's into a single folder

A better place to copy all the scripts from would be the Example project that is provided. Those are more clearly commented, and does not have the extra fluff of the editor stacked on top of it
Thanks!

I was thinking about making a monologue in this system, is it doable?
 
Thanks!

I was thinking about making a monologue in this system, is it doable?
I would think so - You would just use the text Node, and just have that connected to other text Nodes - with no branching
Unless you want a branching monologue

You might have to do more explaining on what you want your monologue to do
 
T

Team Shinigami

Guest
I would think so - You would just use the text Node, and just have that connected to other text Nodes - with no branching
Unless you want a branching monologue

You might have to do more explaining on what you want your monologue to do
I was just thinking about doing an introduction, kind of like the ones in Danganronpa
 
I was just thinking about doing an introduction, kind of like the ones in Danganronpa
I see.
It might just be easier to make an array that stores your text, and then have a variable that ticks up every time you continue in the dialog

This program is for more complicated stuff; like giving the player choices, and then executing some scripts based off those decisions
Branching dialog can quickly get out of hand, and manually coding it can get confusing. This is mainly an easy way of visualizing your dialog trees, and testing your dialog trees

If you are doing something as simple as a monologue, then it would be easier to code it yourself. If you need helping coding something like that, you can PM me, and I can help you there!
 

mycelia

Member
Oh sweet, updates! Thanks for all your hard work @NoobsWeStand, this system is amazing.

One question, the answer for which is probably obvious but I can't seem to figure it out: if I want a conversation to restart from the beginning the next time I approach the same NPC, how do I do that?
 
Q

Quailfail

Guest
One question, the answer for which is probably obvious but I can't seem to figure it out: if I want a conversation to restart from the beginning the next time I approach the same NPC, how do I do that?
Ah, I know this one! Your last node after the finishing text needs to be a script node. Write convo(?,?) the "?" replaced with whatever you named your QuestID and QuestON. Like this,

Untitled.png
 
Oh sweet, updates! Thanks for all your hard work @NoobsWeStand, this system is amazing.

One question, the answer for which is probably obvious but I can't seem to figure it out: if I want a conversation to restart from the beginning the next time I approach the same NPC, how do I do that?
Or you can simply do something like this, if you do not want to deal with the convo system:

Just make sure you pin the first node, so that the dialog editor knows where to begin
 
Q

Quailfail

Guest
No problem, mycelia!

I hope it's alright to show everyone what I'm using this lovely text engine in,
scrsht008.png

I've been steadily tweaking the text box and come across a few issues. Such as wanting to slow down the typewriting speed. I found this:
Code:
textSpeed=1;             //speed at which text typwriter effect goes. Can be changed with [speed=x] tags
Where do I put the speed tag? As putting in the parNPC code will just make said npc start moving, not the text itself. Changing the number on textSpeed doesn't seem to affect it either.
 
Top