1. Hey! Guest! The 32nd GMC Jam will take place between Feb 22nd, 12:00 UTC (Friday noon) and Feb 25th, 12:00 UTC (Monday noon). Why not join in! Click here to find out more!
    Dismiss Notice

GML [SOLVED] Dialog System Woes

Discussion in 'Programming' started by Zahk, Feb 11, 2019.

  1. Zahk

    Zahk Member

    Joined:
    Sep 29, 2018
    Posts:
    13
    I'll start by saying I'm a beginner - I'm only just starting to get the hang of GML, and I hesitate to even say that, especially given my current predicament.

    I'm using a version of the dialog system created by Heartbeast in his RPG tutorial videos from a few years ago, which I've modified to suit my purposes. Almost everything is finally working as I intended - after days of agonizingly slow progress as I struggled to grasp and alter the code - but I just noticed that there seems to be a strange threshold of printed text that the draw_GUI event needs to reach before the player can continue to the next message/step of the array. That would be fine if that threshold were the end of the string, just like my code seems to say, but for some reason it's about halfway through a full dialog box. If the string is only a few words, the game doesn't recognize that the 'confirm_key' is pressed to continue to the next stage of the array for a couple of seconds after the string is finished printing. If the visible string passes this inexplicable threshold, the player can skip to the next step of the array before the current string has finished printing. Though I can explain that this is happening, I can't explain why, because the code seems like it should be working as intended to me. So, instead of throwing in the towel, I've come here for help.

    The code is sprawled out over a few scripts and objects, so I'll just try to include the parts I believe are relevant:

    This is in scr_talk_state, which is in the player's step event. "speaker" is the NPC instance:
    Code:
    with (speaker) {
        //Turn the sprite
        if (x > obj_player.x) {
            sprite_index = left_sprite;
        } else if (x < obj_player.x) {
            sprite_index = right_sprite;
        }
        if (y > obj_player.y) {
            sprite_index = up_sprite;
        } else if (y < obj_player.y) {
            sprite_index = down_sprite;
        }
             
        if (!instance_exists(dialog)) {
            dialog = instance_create_depth(camera_get_view_x(view_camera[0]), camera_get_view_y(view_camera[0]) + camera_get_view_height(view_camera[0]), 0, obj_dialog_box);
            dialog.text = text;
    
        } else {
            if (obj_player.confirm_key and dialog.text_count >= string_length(dialog.text[text_page])) {
                dialog.text_page++;
                dialog.text_count = 0;
                if (dialog.text_page > array_length_1d(dialog.text)-1) {
                    sprite_index = default_sprite;
                    with (obj_player) {
                        speaker = noone;
                        state = scr_move_state;
                    }
                    with (dialog) {
                        instance_destroy();
                    }
                }
            }
        }
    }
    And this is in the Draw GUI event for the dialog box (obj_dialog_box):
    Code:
    if (string_char_at(text[text_page], text_count) == " ") {
        last_space = text_count;
    } else {
        last_space = noone;
    }
    
    if (last_space != noone) {
        var text_words = scr_string_copy_words(text[text_page], 1, text_count);
     
        if (string_width(text_words)*display_scale >= width-(xmargin)) {
            //Remove the space
            text[text_page] = string_delete(text[text_page], last_space, 1)
     
            //Add a return. Using "\n" will enter a return (like pressing enter)
            text[text_page] = string_insert("\n", text[text_page], last_space);
        }
    }
    
    
    text_visible = string_copy(text[text_page], 0, text_count);
    
    var xx = (x - camera_get_view_x(view_camera[0])) * display_scale;
    var yy = ((y-48) - camera_get_view_y(view_camera[0])) * display_scale;
    
    draw_text_ext_transformed(xx+xmargin, yy+ymargin, text_visible, 8, width, display_scale, display_scale, image_angle);
    
    if (obj_player.confirm_key_held) {
        spd = .99;
    } else {
        spd = .5;
    }
    text_count += spd;
    If you need to see more, please let me know. Any and all help is appreciated; I desperately want to be done with this so I can finally move on to the rest of the game, without worrying about the damn dialog system.
     
    Last edited: Feb 11, 2019
  2. Zahk

    Zahk Member

    Joined:
    Sep 29, 2018
    Posts:
    13
    I'm guessing that it's something to do with the if statement:
    Code:
    if (obj_player.confirm_key and dialog.text_count >= string_length(dialog.text[text_page]))
    especially since I tried to use basically the same check to create an instance in the step event of obj_dialog_box, and that didn't work correctly either... but I don't see what's wrong with it.
     
  3. Zahk

    Zahk Member

    Joined:
    Sep 29, 2018
    Posts:
    13
    Gonna throw in the Create event for the dialog box, for good measure:
    Code:
    depth = -1000;
    text = noone;
    
    text_visible = "";
    
    text_page = 0;
    
    text_count = 0;
    
    spd = .5
    
    display_scale = display_get_gui_width()/camera_get_view_width(view_camera[0]);
    
    width = sprite_width*display_scale
    xmargin = 10*display_scale;
    ymargin = 8*display_scale;
     
  4. Zahk

    Zahk Member

    Joined:
    Sep 29, 2018
    Posts:
    13
    Still having this issue! I did gather a little more information, however. The code
    Code:
    if (obj_player.confirm_key and dialog.text_count >= string_length(dialog.text[text_page])) {
                dialog.text_page++;
                dialog.text_count = 0;
                if (dialog.text_page > array_length_1d(dialog.text)-1) {
                    sprite_index = default_sprite;
                    with (obj_player) {
                        speaker = noone;
                        state = scr_move_state;
                    }
                    with (dialog) {
                        instance_destroy();
                    }
                }
            }
    Seems to run when text_count is greater than or equal to 50 and the player presses the confirm_key, and NOT when it is greater than or equal to the length of the string. As for why that is, I have no idea. Is it because checking for the string_length of an array variable just doesn't work correctly in gamemaker?

    I tried slowing down the rate at which the text_count variable increases, but no matter how fast or slow I make it, it's only when that variable reaches 50 or more that the code will run when the key is pressed.

    I'll also add that I printed the variables text_count and string_length(text[text_page]) to the screen so I could see the numbers, and string_length(text[text_page]) prints as the actual number it should be, not 50.
     
    Last edited: Feb 14, 2019
  5. FacesOfMu

    FacesOfMu Member

    Joined:
    Jun 23, 2018
    Posts:
    30
    Hi Zahk,
    I'm a beginner, too, and glad to hear others can also spend large amounts of time nutting out small sections of code, too! ;)

    I'm wondering about here:
    Code:
       if (!instance_exists(dialog)) {
           dialog = instance_create_depth(camera_get_view_x(view_camera[0]), camera_get_view_y(view_camera[0]) + camera_get_view_height(view_camera[0]), 0, obj_dialog_box);
           dialog.text = text;
    
    Where does the script get text from for the end of this line?
    Code:
    dialog.text = text;
    And my second question: Are you expecting text to appear at a rate of 30 characters per second? That's what I gather from spd = 0.5 and an assumed room speed of 60. I'm sorry if I misunderstand.
     
  6. Zahk

    Zahk Member

    Joined:
    Sep 29, 2018
    Posts:
    13
    The text variable comes from the speaker instance, which in this case is an NPC object. It's an array with a string input.

    And yes, text currently appears at a rate of 30 characters per second - unless you hold down the confirm_key, which speeds up the rate the text appears.
     
  7. Zahk

    Zahk Member

    Joined:
    Sep 29, 2018
    Posts:
    13
    Here's the create event of the speaker object where the text array is defined:
    Code:
    ///initialize NPC
    event_inherited();
    dialog = noone;
    text_page = 0;
    default_sprite = spr_mom_right;
    left_sprite = spr_mom_left;
    right_sprite = spr_mom_right;
    up_sprite = spr_mom_up;
    down_sprite = spr_mom_down;
    text[0] = "This text exists to test the functionality of the dialog box.";
    text[1] = "I guess I will increase the amount of text to see if it makes a difference. I am extending this text to further test the extent of this bug";
    text[2] = "Insert text here.";
     
  8. Lady Glitch

    Lady Glitch Member

    Joined:
    Feb 10, 2019
    Posts:
    15
    Shouldn't it be like this?
    Code:
    string_length(dialog.text[dialog.text_page])
     
    Zahk likes this.
  9. Zahk

    Zahk Member

    Joined:
    Sep 29, 2018
    Posts:
    13
    ...you are my hero. I've been stuck here for days. DAYS. I could KISS you!

    I still don't understand why the check was going through when text_count reached 50... but whatever, I guess it doesn't matter now.

    Thank you SO much.
     
    Lady Glitch likes this.
  10. Lady Glitch

    Lady Glitch Member

    Joined:
    Feb 10, 2019
    Posts:
    15
    Glad to help :)
    It seems like you have another variable called text_page in your speaker instance which leads your script to the wrong point in the array.
     
    Zahk likes this.
  11. Zahk

    Zahk Member

    Joined:
    Sep 29, 2018
    Posts:
    13
    Okay, yes, I figured it out - I was confused because text_page was set to 0 by default, and I thought it might be the length of the first index of the array, but it wasn't exactly 50, so I added a bunch of characters to the string and that increased the threshold.

    What a relief! Thank you again!
     
    Lady Glitch likes this.
  12. FacesOfMu

    FacesOfMu Member

    Joined:
    Jun 23, 2018
    Posts:
    30
    Thanks for your reply. It does look like a doozy.
    What happens if the text itself is shorter than 50 characters? Does your "next page" code ever run? (as in, it never meets the strange threshold of 50)


    Edit: didn't refresh my page and see the answers posted :)
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice