GameMaker: Opening links in a new tab on HTML5

On some occasions you may want to open a link in a new tab a GameMaker' HTML5 game.

As simple as it may look, this presents a bit of a problem:

  • url_open opens links in the same tab.
  • url_open_ext can open links in a new tab, but triggers popup blocker.
  • clickables can open links in a new tab, but have to be repositioned manually.
    (particularly inconvenient if scaling-positioning the game for mobile browsers)
  • Adding an actual link (<a> element) into the game template allows to open links in a new tab, but requires basic understanding of JavaScript and HTML to hide/unhide dynamically.

url_open_ext is by far the most convenient of these, so let me explain why that does not work:

To prevent any page from being able to randomly open indefinitely large quantities of new tabs, the browser will automatically block attempts to open new tabs\windows unless they originate from user interaction (click event);

GameMaker handles events, and writes down new input states to later dispatch GML-level events at the right time and place (see event order). This means that your GML code inside a "Mouse Pressed" event does not count as originating from a user interaction (as it executes a few milliseconds later), and thus is not allowed to open new tabs (and do some other things).

However, with a bit of JS (and understanding of internal workings of GM), it is possible to accomplish the intended result, and this post is about that.

Extension' code

The extension consists of 2 GML scripts, 1 GML macro, and 1 JS function.

The GML side (browser_click_handler.gml) is as following:


#define gmcallback_browser_click_handler
/// ()
//#browser_click_handler global.g_browser_click_handler
var q = browser_click_handler;
if (script_exists(q)) script_execute(q);

#define browser_click_handler_init_gml
/// ()
browser_click_handler = -1;
if (browser_click_handler_init_js()) {
    gmcallback_browser_click_handler();
}

Here you can see:

  • A macros with name browser_click_handler and value global.g_browser_click_handler.
    This essentially makes a global variable with auto-completion (related post).
  • gmcallback_browser_click_handler is a GML script that will be called when the user clicks somewhere. gmcallback_ prefix ensures that it will not be automatically minified (and thus available as window.gml_Script_gmcallback_browser_click_handler); the script itself retrieves the script index from the aforementioned global variable and calls the script if it's valid.
  • browser_click_handler_init_gml is a GML script that should be set as "initialization" script for the extension file. It sets the global variable to a default value, calls the JS side init function, and includes a reference to the gmcallback_ script to prevent it from being removed compilation-time in older versions of GMS due to lack of apparent use.

JavaScript side of things is a single function that binds the gmcallback_ script to the click event:

///
function browser_click_handler_init_js() {
    window.addEventListener("click", window.gml_Script_gmcallback_browser_click_handler);
    return 0;
}

If your canvas has a fixed ID, you could replace window by document.getElementById("yourCanvasID) to have the code not trigger when clicking outside the canvas (if it does not cover the entire page).

Using the extension

Once the extension is ready and imported, the use is straightforward: assign a script into the browser_click_handler variable when you need to,

browser_click_handler = scr_clicked;

and handle new-tab-related actions from there:

/// scr_clicked()
with (obj_link_button) if (position_meeting(mouse_x, mouse_y, id)) {
    url_open_ext(url, "_blank");
}

(in this case, having obj_link_button' instances open their url in new tab when clicked)

Much like room creation code, the script will execute for no particular instance.

And that's it. A pre-compiled extension (along with a live demo) can be found on itch.io:

Download (itch.io)

Have fun!

Related posts:

3 thoughts on “GameMaker: Opening links in a new tab on HTML5

  1. Oh man, I want this one. It’s so frustrating itch.io downloads doesn’t work for me even selecting “Enable alternate download mode” 🙁

Leave a Reply

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