screen_redraw in GameMaker: Studio

A screen recording shows use of the function in a loop, \allowing the game to update "on spot" (mouseover/click to play GIF)

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

  1. Open a GameMaker: Studio project
  2. 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.
  3. Add an empty GML file to the extension by right-clicking it in the resource tree and picking "Add placeholder" ➜ "Add GML file".
  4. Add a function to this GML file by right-clicking it in the resource tree and picking "Add Function".
  5. Open the function properties by double-clicking it in the resource tree.
  6. Set "External name" to action_sleep.
  7. Set "Name" to what you'd like.
    This can be anything except for names of existing and obsolete functions, so you may not call it screen_redraw. I named it sleep_ext.
  8. 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!

A screenshot of "Sleep" / action_sleep Drag & Drop block in GameMaker 8.1

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.

Related posts:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.