Featuring more tricks that you probably haven't heard about, and not just for old GameMaker versions!
It feels like I explain this one to someone about once a year or so and can never quickly locate my previous explanation, so it's a post for me and you.
What's screen_redraw
screen_redraw
was a function that would immediately redraw the game,
much like what GameMaker does every frame - with backgrounds, tiles, running the Draw events, etc.
Being able to do this "on spot" allowed for certain code patterns -
for example, if you had a modal dialog box where the player might make a few choices
before backing out, usually you would have to make a little state machine in one or other form,
but with screen_redraw
you could have code like
dlg_show("Hello!"); switch (dlg_show("Nice day, isn't it?", "Yeah", "Not really")) { case 0: // ... case 1: // ... }
with dlg_show
drawing the dialog box in a loop with screen_redraw,
getting the user input, and finally returning the chosen response.
Rest assured, games would occasionally make use of this.
And then the function was removed in GameMaker: Studio as this wasn't a desirable pattern on some platforms and an outright impossible one on others (like HTML5!).
The trick
- Open a GameMaker: Studio project
- Create an extension by right-clicking the Extensions folder in the resource tree
and picking "Create Extension".
I named the extension "gms_screen_redraw" but this doesn't matter much. - Add an empty GML file to the extension by right-clicking it in the resource tree
and picking "Add placeholder" ➜ "Add GML file".
- Add a function to this GML file by right-clicking it in the resource tree and picking "Add Function".
- Open the function properties by double-clicking it in the resource tree.
- Set "External name" to
action_sleep
. - Set "Name" to what you'd like.
This can be anything except for names of existing and obsolete functions, so you may not call itscreen_redraw
. I named itsleep_ext
. - Set "Help" to
sleep_ext(ms, redraw)
(with your own name if appropriate).
And that's it! You can now call it like sleep_ext(0, true)
to just re-draw the screen
or sleep_ext(16, true)
to re-draw the screen and then wait for 16ms.
How does this work
The above is admittedly closer to entering a cheat-code than to a "normal" tutorial.
Function tricks
When loading an extension, GameMaker goes over all functions that were specified in the extension editor and links them up.
For GML files in the extension, this will first look for a script with a matching name (as per External Name) as those are added to the pile with the game's scripts, but if that doesn't exist, it'll look for a same-named built-in function instead.
I suspect that this behaviour originates from code re-use somewhere, but it's been great help as it allows you to use functions that the compiler doesn't know about but the runtime does.
So, for example, if you are taking advantage of the source code access in the Enterprise package
and want to add a one-off function for your project,
you can register it on the runtime side with Function_Add
and make an extension like this -
without modifying GMAssetCompiler
and adding the function definition to fnames
/GmlSpec for the IDE to see it.
In context of GameMaker: Studio, this enables access to both functions that are marked obsolete but still exist and functions that are intended for GameMaker Studio 2 but made it into the last few GM:S updates because much of the runtime source code was shared between the two.
action_sleep
It's the function that was used for this Drag & Drop block!
It was removed from the DnD palette in GM:S, but still remained in the runtime source code up until GameMaker Studio 2.3 or so.
How about screen_refresh?
As far as I'm aware, there are no Cool Tricks to replicate screen_refresh
,
but I made an extension
for that at some point.
Modern alternatives
Pausing the game is typically done by adding something like
if (global.pause) exit;
to the beginning of all gameplay objects' Step events.
If you are only beginning to develop the game, you may instead opt to use a User Event instead of a Step event so that you get more control over when and whether these are executed, and in what order.
Cutscenes and other "non-instant" code can be implemented by either running the code snippets in a little interpreter (I wrote a tutorial series on that) or using a library like Juju's Coroutines (which uses advanced macro tricks to output code that you wouldn't want to write by hand).
And that's about it! You can grab my test project from GitHub if you'd like.