The 2.3.0 release of GameMaker sees some changes to the way that scripts are now handled in all current versions of GameMaker, 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.
The Old Way (GameMaker 2.2.5 And Every Version Before That)
Previously, a Script asset was used to write a single custom function in that script file, and this function would then be called elsewhere in your code by using the Script name as the function name.
So your Script might be called "Hello" and have this single line of code in it:
show_message("Hello world!");
And when you wanted to call that Script inside a different script or object event, or wherever, you simply wrote:
Hello();
The New Way (GameMaker 2.3.0 And Every Version After That)
This is no longer the case and scripts, while still global in scope, are now capable of being a type of "container" for one or more functions.
What this means is that when you run your game, all of your scripts are now called right at the start of your game (and therefore in the global scope), so that all lines of code outside of function definitions will be considered global and therefore any variables you declared at the top of your scripts, for example, will be initialised right at the start of the game.
(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.
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 (to you) names like "player_functions" or "camera_functions" or whatever.
This is easier to visualize with an example, so let's look at how to make a script function.
Declaring as a Script Function
Consider this simple move_follow()
script and how it used to be written in previous GameMaker versions:
/// @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 old GML Visual version would look like this:
Now, however, move_follow() 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 the new way of achieving that in GML Visual:
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.
Also note that if you want to define macros, enums, or global variables you do NOT need to use "function" line each time and can add them into the script just as you did in 2.2.5 and older.
Declaring as a Method
Note that in GML Code you can also now declare move_follow() in another way , 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 the function as a method variable rather than as a script function and so 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);
Multiple Functions Can Be Written In One Script
So, as we mentioned above, scripts can now contain multiple functions and these should be defined with the format already shown above, where you have:
- An optional JSDoc comment to identify the function we are about to declare, in the format @function <name>(<arguments>) (and this can run over multiple lines and contain lots of extra info you wish to expose to the autocomplete popup)
- The function declaration line
- An opening curly brace (this can be on the line above, that's up to you)
- The body of the function
- A closing curly brace (again, this can come at the end of a line with other content on it)
Here you can see an example of 3 functions all in the 1 Script asset:
For GML Visual, the same is true - you would simply wrap each of the different functions in a script asset in the Declare A New Function action:
Importing Older Projects
Finally, for older projects which are 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 a copy of it to a new location. This is because the conversion process to 2.3.0 and above is not backwards compatible and these new copies of your projects cannot be opened in older GameMaker versions (your original copy still can).