The 2.3.0 release of GameMaker sees some changes to the way that scripts are now handled, which we'll explain in this article as well as point out how scripts in projects created with previous versions will be imported and handled.
Previously, a script was a single resource that was created on a global scope and used to create a single custom function which would then be called using the script name as the function name. This is no longer the case and scripts, while still global in scope, are now a type of "container" for one or more functions.
What this means is that when you compile your project, scripts are no longer called individually, but are actually all run at the start of the game in the global scope, so all variables that are defined in the script (outside of function definitions) will be considered global. That said, you should still use the global identifier to explicitly define and identify global variables in your code.
The reason for this change is that scripts can now contain multiple functions. If you've only used built-in GML Code functions to code projects then the idea of user defined functions may be something new to you, but think of them as being the same as scripts used to be, only explicitly assigned to a variable and with named arguments. This is easier to visualize with an example, so let's look at how to make a script function. Consider this simple script from previous GameMaker versions, move_follow()
:
/// @function move_follow(object, speed);
/// @param {index} object The Object to follow
/// @param {real} speed The speed to follow at
var _o = argument0;
var _s = argument1;
if (point_distance(x, y, _o.x, _o.y) > 0)
{
direction = point_direction(x, y, _o.x, _o.y);
speed = _s;
}
else speed = 0;
The GML Visual version would look like this:
Now, however, this would be defined as a script function like this:
/// @function move_follow(object, speed);
/// @param {index} object The Object to follow
/// @param {real} speed The speed to follow at
function move_follow(_object, _speed)
{
if (point_distance(x, y, _object.x, _object.y) > 0)
{
direction = point_direction(x, y, _object.x, _object.y);
speed = _speed;
}
else speed = 0;
}
And this would be in GML Visual:
Note that in GML Code you can also declare the function in another way too, like this:
move_follow = function(_object, _speed)
{
if (point_distance(x, y, _object.x, _object.y) > 0)
{
direction = point_direction(x, y, _object.x, _object.y);
speed = _speed;
}
else speed = 0;
}
However this way creates a method variable and not a script function and would be best used when defining a function in an object rather than a script asset.
To call a script function you would do it just as you used to for the old scripts, eg:
move_follow(obj_Player, 5);
You'll notice that arguments are now named and you can use their names in your code. Named arguments will be local in scope to the function, although you can still use the built in argument0, argument1, etc... variables. You can also still use variable arguments in functions using the argument_count and argument[N] variables.
So, as we mentioned above, scripts can now contain multiple functions and these should be defined with the format shown above where you have the @function <name>(<arguments>) JS doc comment to identify the function, then the function definition below, and then the next JS Doc comment, and then the function, etc...
For GML Visual, the same is true and you would simply wrap each of the different functions in a script asset in the Declare A New Function action:
It is worth noting that this means that script names no longer need to be the same as any of the functions, and so you can give them meaningful names like "tween_library" or "getter_functions" or whatever. Also note that if you want to define macros, enums, or global variables, you do NOT need to use "function" and can add them into the script as before.
Finally, for older projects that imported into GameMaker 2.3.0 and above, these will automatically be converted to use the new "function" call or action and should work just as before. The only difference will be that the script contents will have their formatting updated. Below is an image of a script created in a previous version that has been auto-updated on import:
Note that when opening a project from a previous version, you will be prompted to save it to a new location. This is because the conversion process to 2.3.0 and above is not backwards compatible so projects that have been updated and converted cannot be opened in prior versions anymore.