GML [SOLVED]The scripts is keep looping itself without the 'repeat' function

C

Cesur Basoglu

Guest
So, I try to combine Beyond Us Games' s multi dialogue system with FriendlyCosmonaut's cutscene system. The abomination actually works for the most part. The problem is when the time comes for scrCutsceneDialogue, the game created a lot of dialogue boxes, this is evident because I programmed the text to write like a typewriter and make a sound as it is typing. So as soon as the first dialogue box is created you can hear more typewriting sounds in the background and when you choose an option, the first text box is destroyed, but in this case, another text box is beneath the second one.

obj_player > Create Event
Code:
if(!instance_exists(obj_cutscene)){
    if(keyboard_check_pressed(ord("B"))){
        with(obj_sergent){
            scrCreateCutscene(t_scene_info);
        }
    }
}
The code above is in my obj_player's Create Event, and it is suppose to statr the cutscene when the player presses B.


scrCreateCutscene
Code:
/////@description Create Cutscene
var inst = instance_create_layer(0,0,"Instances", obj_cutscene);
with(inst){
    scene_info = argument0;
    event_perform(ev_other, ev_user0);
}
When this script is run, it takes the scene from the given object and runs the obj_cutscene's User Event[0].



obj_cutscene > User Event[0]
Code:
current_scene = scene_info[scene];
var len = array_length_1d(current_scene) -1;
current_scene_array = -1;
current_scene_array = array_create(len, 0);
array_copy(current_scene_array, 0, current_scene, 1, len);
This is a bit confusing to explain. What it does is, it takes the scene information (which has scripts with arguments) from the crate event of the object. Then it removes all scripts from their arguments with '-1' and that information is stored in 'len'. In other words that line helps to remove the first entry in the array length which are scripts. Then current scene array is set to '-1' to use this event again and again. The fourth line is to set all entries to 0. At last copy, the current_scene to current_scene_array.


obj_sergent > Creation Code
Code:
///–––––Vars
voice = snd_voice3;
text_col = c_green;
font = fnt_14;
///–––––Cutscenes
t_scene_info = [
    [scrCutsceneWait, 1],
    [scrMoveObject, obj_sergent, 352, 610, false, 4],
    [scrCutsceneWait, 1],
    [scrCutsceneDialogue, id, 0],
    [scrMoveObject, obj_sergent, 52, 61, false, 4],
];
///–––––The Dialogue
myDialogue[0,0] =@"Sir we've lost our second and third engine and the planet belove us is pulling the ship. What
should we do?";
    ///–––––Options
    myDialogue[0,1] = "Hold on." + "99"
    myDialogue[0,2] = "Every one to the escape pods" + "99"
    myDialogue[0,3] = "Pray" + "99"
The Cutscene part is what it should be running when the player hits B. And it works perfectly until and it starts to create a lot of text objects at the same time. scrCutsceneDialogue is supposed to create a dialogue box and type 'The Dialogue' section.



If you need/want to see more of the code you can ask me.
 

samspade

Member
A couple questions:
  • There's an easy way to confirm that there are multiple instances (though given what you said it sounds correct). Either run the debugger and check the instances tab or call instance_number(obj_cutscene);
  • how many obj_sergents do you have? Because you reference the object id rather than the instance id you're telling it to create a cutscene for every single one, which may or may not be what you want.
  • This doesn't seem to be an issue, but the create event only runs when the instance is created. So the player would have to be created in the same step that you push b. This seems unlikely unless pushing b also creates the player. Again, doesn't seem to be the problem, but it makes me wonder why it is set up this way.
 
C

Cesur Basoglu

Guest
A couple questions:
Either run the debugger and check the instances tab or call instance_number(obj_cutscene);
I followed your advice and I think this code is responsible for it.

Code:
///Begin a dialogue between PC and NPC
var box_height = sprite_get_height(spr_dialoguebox);
dialoguebox = instance_create_layer(view_wport[view_current]/2, (box_height/2), "Instances", obj_dialoguebox);
with(dialoguebox){
    maxHeight = sprite_height-2;
    maxLenght = sprite_width-2;
    myMessage = messageGiver.myDialogue[index1, index2];
    messageIndex = 0;
    if(array_length_2d(messageGiver.myDialogue, index1) > 1){
        hasChoice = true;
    }else{
        hasChoice = false;
    }
    ///Go to the next page if exiding the mx Lenghth and maxHeight
    if(string_height_ext(myMessage, seperatoin, maxLenght) > maxHeight){
        textHeight = string_height_ext(messageGiver.myDialogue[index1, index2], seperatoin, maxLenght);
        amount = (textHeight / maxHeight);
        startingAt = 0;
        for (i = 0; i < amount; i++;){
            myMessage[i] = string_copy(messageGiver.myDialogue[index1, index2], startingAt, (string_length(messageGiver.myDialogue[index1, index2])) / amount);
            startingAt = string_length(myMessage[i]) * (i + 1);

        }
    }
    else{
        myMessage[messageIndex] = messageGiver.myDialogue[index1, index2];
    }   
    currentText = "";
    position = 0;
}
this is the code that creates obj_dialogueboxes and text and sets other details. But when I ran it through the debugger I saw that at the end of this code, it went back to the script that was calling the code above. And in the instance tab, I saw that the number of obj_dialougeboxes skyrocketed

How many obj_sergents do you have?
Only one, but I didn't know that could be a problem thanks! and I after changing, it still doesn't work

  • This doesn't seem to be an issue, but the create event only runs when the instance is created. So the player would have to be created in the same step that you push b. This seems unlikely unless pushing b also creates the player. Again, doesn't seem to be the problem, but it makes me wonder why it is set up this way.

Yeah, I am sorry that is a mistake on my part it is actually run on the step event.
 

samspade

Member
What is the code that is calling this script and where is it located and how is it called?

Essentially, if you've confirmed that the issue is that a lot of obj_dialougeboxes are being created then the problem is almost certainly an instance_create . . . dialoguebox. So you should check every place in your code you create a dialoguebox and figure out whether or not it is being called multiple times and if so why.

With the code you just posted, it appears that it would only be called once. However, if it is being called in a script or certain events it could be called repeatedly which would cause the problem.
 
C

Cesur Basoglu

Guest
I think I finally found the answer. To understand it I first need to explain what is going on from the start.
1) Scripts and arguments are taken from obj_sergent's creation code
2)Then that data (scripts and arguments) are taken through the scrCreateCode and User Event[0]
3)Then the data is put through another script that I haven't mentioned(scrExacute). In essence, it takes [scrCutsceneWait, 1] and makes it scrCutsceneWait(1);
And there is my problem. scrExacute is called from obj_cutscene's step event.
Code:
scrExecuteAlt(current_scene[0], current_scene_array);
Because I actually never set those variables (current_scene[0], current_scene_array) to none or -1 again it repeats this step over and over again.
It actually makes sense. Because only another script that I ran was scrMoveObject, which states to change the x and y location of an object until that object reached there. It doesn't matter how many times scrExecuteAlt runs because that object has a fixed position to go. On the other hand, scrCutsceneDialogue has to create a dialoguebox, and thus it creates 60 of them per second.

Now I don't know how to fix it. The problem is the player will take their time to read the message and every other second is, 60 new dialogueboxes are added. But I also can't take scrExecuteAlt out of the step event because it has to check if my scene has changed.
 

samspade

Member
I think I finally found the answer. To understand it I first need to explain what is going on from the start.
1) Scripts and arguments are taken from obj_sergent's creation code
2)Then that data (scripts and arguments) are taken through the scrCreateCode and User Event[0]
3)Then the data is put through another script that I haven't mentioned(scrExacute). In essence, it takes [scrCutsceneWait, 1] and makes it scrCutsceneWait(1);
And there is my problem. scrExacute is called from obj_cutscene's step event.
Code:
scrExecuteAlt(current_scene[0], current_scene_array);
Because I actually never set those variables (current_scene[0], current_scene_array) to none or -1 again it repeats this step over and over again.
It actually makes sense. Because only another script that I ran was scrMoveObject, which states to change the x and y location of an object until that object reached there. It doesn't matter how many times scrExecuteAlt runs because that object has a fixed position to go. On the other hand, scrCutsceneDialogue has to create a dialoguebox, and thus it creates 60 of them per second.

Now I don't know how to fix it. The problem is the player will take their time to read the message and every other second is, 60 new dialogueboxes are added. But I also can't take scrExecuteAlt out of the step event because it has to check if my scene has changed.
Without re-looking through all of the code, and probably some other code that isn't posted I can't answer for sure (and I don't really want to look through that much code), but it sounds like you already have the solution. Either (1) move the script or (2) add a check. You say you can't move the script, which might true as is, but you could probably split the script into two - a run at the start and a run every step. Or similarly, you could add a check in the script itself that prevents the problem portion from running after it runs once. For example:

Code:
if (run == true) {
    run = false;
    ///add code
}
where you set run to true somewhere such as when you call the script for the first time.
 
C

Cesur Basoglu

Guest
OMG it has worked. I just put a check where the obj_box is created and it worked. Thank you so much for your help!!!
 
Top