Question

I'm using GameMaker:Studio Pro and trying to execute a script stored in a variable as below:

script = close_dialog;
script_execute(script);

It doesn't work. It's obviously looking for a script named "script". Anyone know how I can accomplish this?

Was it helpful?

Solution

This question's quite old now, but in case anyone else ends up here via google (as I did), here's something I found that worked quite well and avoids the need for any extra data structures as reference:

scriptToCall = asset_get_index(scr_scriptName);
script_execute(scriptToCall);

The first line here creates the variable scriptToCall and then assigns to it Game Maker's internal ID number for the script you want to call. This allows script_execute to correctly find the script from the ID, which doesn't work if you try to pass it a string containing the script name.

I'm using this to define which scripts should be called in a particular situation from an included txt file, hence the need to convert a string into an addressable script ID!

OTHER TIPS

You seem to have some confusion over how Game Maker works, so I will try to address this before I get around to the actual question.

GML is a rather simple-minded beast, it only knows two data types: strings and numbers. Everything else (objects, sprites, scripts, data structures, instances and so on) is represented with a number in your GML code.

For example, you might have an object called "Player" which has all kinds of fancy events, but to the code Player is just a constant number which you can (e.g.) print out with show_message(string(Player));

Now, the function script_execute(script) takes as argument the ID of the script that should be executed. That ID is just a normal number. script_execute will find the script with that ID in some internal table and then run the script.

In other words, instead of calling script_execute(close_dialog) you could just as well call script_execute(14) if you happened to know that the ID of close_dialog is 14 (although that is bad practice, since it make the code difficult to understand and brittle against ID changes).

Now it should be obvious that assigning the numeric value of close_dialog to a variable first and then calling script_execute on that variable is perfectly OK. In the end, script_execute only cares about the number that is passed, not about the name of the variable that this number comes from.

If you are thinking ahead a bit, you might wonder whether you need script_execute at all then, or if you could instead just do this:

script = close_dialog;
script();

In my opinion, it would be perfectly fine to allow this in the language, but it does not work - the function call operator actually does care about the name of the thing you try to call.

Now with that background out of the way, on to your actual question. If close_dialog is actually a script, your suggested code will work fine. If it is an extension function (or a built-in function -- I don't own Studio so what do I know) then it does not actually have an ID, and you can't call it with script_execute. In fact, you can't even assign close_dialog to a variable then because it does not have any value in GML -- all you can do with it then is call it. To work around this though, you could create a script (say, close_dialog_script which only calls close_dialog, which you can then use just as above.

Edit: Since it does not seem to work anyway, check whether you have a different resource by the name of close_dialog (perhaps a button sprite). This kind of conflict could mean that close_dialog gives you the ID of the sprite, not of the script, while calling the script directly would still work.

After much discussion on the forums, I ended up going with this method.

I wrote a script called script_id()

var sid;
sid = 6; //6 = scriptnotfound script :)

switch (argument0) {
    case "load_room":
        sid = 0;
        break;
    case "show_dialog":
        sid = 1;
        break;
    case "close_dialog":
        sid = 3;
        break;
    case "scrExample":
        sid = 4;
        break;
}

return sid;

So now I can call script_execute(script_id("close_dialog"));

I hate it, but it's better than keeping a spreadsheet... in my opinion.

There's also another way, with execute_string(); Should look like this:

execute_string(string(scriptName) + "();");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top