• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker [Solved] Having issues with my dialogue system

N

Nambuc

Guest
Hi!
First of all, I'm a beginner. Be nice with me :)
I'm trying to build a dialogue system for my narrative game, but I'm having issues with one specific
line of code. I've created an object containing my dialogue lines and branching. I've also put a kind of menu that appears when a choice needs to be made (when we meet a branching). Here's the create event :
Code:
///Interactive menu
menu_x = x;
menu_y = y;
button_h = 32;
//buttons
button[0] = "Provoke"
button[1] = "Reassure"
button[2] = "Interpret"
button[3] = "Keep silent"
buttons = array_length_1d(button);

menu_index = 0;
last_selected = 0;

///Text
textMap = ds_map_create();

value = "";

//Booleans (true or false)
question = false;


//Path example
ds_map_add(textMap,"","Paul:\n\nSir...I'm...\nnot going very well these days.");
ds_map_add(textMap,"E","Can't sleep.\nCan't wake up.\nCan't go outside.\n*");
ds_map_add(textMap,"E0", "I'm provoking you.");
ds_map_add(textMap,"E1", "Be reassured, it's alright.");
ds_map_add(textMap,"E2", "I'm trying to interpret something.");
ds_map_add(textMap,"E3", "...");
And here is the Draw event :
Code:
draw_set_font(fSpecial_Elite);
draw_set_color(c_black);

draw_set_halign(fa_center);
draw_set_valign(fa_center);


///Find branching in dialogues
txt = ds_map_find_value(textMap,value)

if (string_char_at(txt,string_length(txt)) == "*")
{
    question = true;   
}
else
{
    question = false;
}

//Drawing the txt variable (converted to a string)
draw_text_speed(x,y,string(txt),0.10) //room_speed = one second

//If question is false, you can press space
//If question is true, opens the choices menu
draw_set_font(fSpecial_Elite);
draw_set_color(c_red);
if (question == false)
{
    draw_text(x,y + 250/*pixels*/,"(Space) Continue");
}
else //Show interaction menu
{       
            var i = 0;
            repeat(buttons) {
                draw_set_font(fDialogChoice);
                draw_set_halign(fa_right);
                draw_set_color(c_black);
    
                if (menu_index == i) draw_set_color(c_red)
                draw_text(menu_x, menu_y + button_h * i, button[i]);
                i++;
                };           
}
The Press Enter Event (when the menu appears to make a choice):
Code:
if (question == true) switch (menu_index)
        {
            case 0:
                value += "0";
                draw_text_speed("Reset");
                
            case 1:
                value += "1";
                draw_text_speed("Reset");
                
            case 2:
                value += "2";
                draw_text_speed("Reset");
                        
            case 3:
                value += "3";
                draw_text_speed("Reset");
        }
And the Press Space event:
Code:
if (question == false)
{
    value += "E" ;
    draw_text_speed("Reset");
}
Just in case here are the Step and Clean up events (but there's no problem with them, I guess)
Code:
menu_move = keyboard_check_pressed(vk_down) - keyboard_check_pressed(vk_up);

menu_index += menu_move;
if (menu_index < 0) menu_index = buttons - 1;
if (menu_index > buttons -1) menu_index = 0;

if (menu_index != last_selected) audio_play_sound(snDialogChoice,1,false);

last_selected = menu_index;
Code:
ds_map_destroy(textMap);

Here's my problem: when I run the game, everything works fine (the dialogue starts and we can keep going pressing space) until the first branching: the interactive menu appears all right, but when I pick a choice (any of them) I've got this fatal error message:
FATAL ERROR in
action number 1
of Draw Event
for object cont_text_ULTIMATE_try:

string_length argument 1 incorrect type (undefined) expecting a String (YYGS)
at gml_Object_cont_text_ULTIMATE_try_Draw_0 (line 14) - if (string_char_at(txt,string_length(txt)) == "*")
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Object_cont_text_ULTIMATE_try_Draw_0 (line 14)
It refers to this :
Code:
if (string_char_at(txt,string_length(txt)) == "*")
{
    question = true;   
}
else
{
    question = false;
}
Any ideas of what I did wrong?
THANKS A LOT.

PS: I followed some tutorials for this as I am not a pro. One was for the dialogue system, the other was for the menu buttons: I tried to mix them in a single object...
 

Simon Gust

Member
I guess the ds map returns undefined somewhere.
above those lines that cause the error, put this
Code:
show_debug_message(txt);
What is the output on your console window?
Does it say undefined?

Try tracking your variable called value (which I'd rather name key), and see if it ever changes to something that does not exist in the ds map (if the address doesn't exists, the value returns undefined).
 
N

Nambuc

Guest
I guess the ds map returns undefined somewhere.
above those lines that cause the error, put this
Code:
show_debug_message(txt);
What is the output on your console window?
Does it say undefined?

Try tracking your variable called value (which I'd rather name key), and see if it ever changes to something that does not exist in the ds map (if the address doesn't exists, the value returns undefined).
Thanks for your answer.
I've just checked, and indeed it says "undefined".
What should I do?
 

Simon Gust

Member
You can also print the value to the console window.

Put this code also above the error-causing code
Code:
show_debug_message(value);
What does it say? Does it exist as an address in your map?
 
N

Nambuc

Guest
You can also print the value to the console window.

Put this code also above the error-causing code
Code:
show_debug_message(value);
What does it say? Does it exist as an address in your map?
When I choose case 0 (press Enter for "Provoke") it shows :
"undefined
E0123"

> doesn't exist in my map (it sould show "E0")​

When I choose case 1 ("Reassure") it shows:
"undefined
E123"

> doesn't exist in my map (it should show "E1")​

When I choose case 2 (Interpret) it shows:
"undefined
E23"

> doesn't exist (it should show "E2")​

When I choose case 3 ("Keep silent") it...works, it shows, like expected:
E3

I still don't undesrtand why the others can't work...
 
Last edited by a moderator:
N

Nambuc

Guest
Is there something wrong with this code maybe?
Code:
if (question == true) switch (menu_index)
        {
            case 0:
                value += "0";
                draw_text_speed("Reset");
                
            case 1:
                value += "1";
                draw_text_speed("Reset");
                
            case 2:
                value += "2";
                draw_text_speed("Reset");
                        
            case 3:
                value += "3";
                draw_text_speed("Reset");
        }
 

Simon Gust

Member
wow, I see it now. I looked at your code for so long
You forgot to add breaks after the cases.
Code:
if (question == true) switch (menu_index)
{
    case 0:
        value += "0";
        draw_text_speed("Reset");
    break;
    case 1:
        value += "1";
        draw_text_speed("Reset");
    break;
    case 2:
        value += "2";
        draw_text_speed("Reset");
    break; 
    case 3:
        value += "3";
        draw_text_speed("Reset");
    break;
}
 
N

Nambuc

Guest
wow, I see it now. I looked at your code for so long
You forgot to add breaks after the cases.
Code:
if (question == true) switch (menu_index)
{
    case 0:
        value += "0";
        draw_text_speed("Reset");
    break;
    case 1:
        value += "1";
        draw_text_speed("Reset");
    break;
    case 2:
        value += "2";
        draw_text_speed("Reset");
    break;
    case 3:
        value += "3";
        draw_text_speed("Reset");
    break;
}
Wow man, thank you so much!
It's working like a charm now :)
ā¤
 

Yal

šŸ§ *penguin noises*
GMC Elder
It could be worth pointing out that leaving breaks out is an intended feature, it lets you have multiple cases with the same code block:
Code:
case 4:
case 5:
case 17:
  do_thing();
break;

It also lets you do stuff where two cases are MOSTLY the same, but one has some extra functionality:
Code:
case special_fish:
  is_special = true;
case fish:
  weight = fish_weigh()
  score += weight + special*100;
break

So it's a bug in your case, but it can be useful occasionally.
 
Top