The Asynchronous Events

Object Editor Async Events An asynchronous event is one that is fired off when GameMaker Studio 2 receives a "call back" from some external source, which can be from the web or from the device running your game. Basically, you tell GameMaker Studio 2 to do something, like load an image, and it'll start to do this but continue doing whatever it else it has to do meanwhile its working. Then, when the request has been completed, a call-back will be sent to GameMaker Studio 2 and any Asynchronous Events defined for that type of call back will be fired. Please note that the Asynchronous Events are fired for all instances that have them, much like the key events, so you can do an http_get call in one instance, yet have the Asynchronous HTTP event in another to deal with the call back.

NOTE: You should be aware that due to XSS protection in browsers, requests to and attempts to load resources from across domains are blocked and may appear to return blank results when using any of the following events


There are various types of events associated with the Asynchronous event category, and they are all explained in the sections below:

NOTE: The variable async_load which is mentioned in the following sections is only valid in these events, as the ds_map that is points to is created at the start of the event, then deleted again at the end, with this variable being reset to a value of -1 at all other times.


This event can only be triggered by the audio queue play functions and will return a ds_map stored in the variable async_load, containing different key/value pairs relating to the audio queue that has triggered the event. The event is triggered when you have selected an audio queue to playback and a buffer in that audio queue is finished playing.

The following keys will be available in the ds_map:

  • "queue_id" - the queue index for the queue that has finished playing, as returned by the function audio_create_play_queue.
  • "buffer_id" - the buffer ID for the buffer that is no longer being played from
  • "queue_shutdown" - this is set to 0 during normal playback and 1 when the event is received because audio_free_play_queue has been called. When this is set to 1, you don't want to queue up any further data.
Since an audio queue can be created from multiple buffers, this event can be triggered multiple times for one queue as the end of each section of buffered audio is reached, hence the "buffer_id" key.

NOTE: The variable async_load is only valid in the asynchronous events, as the ds_map that is points to is created at the start of the event, then deleted again at the end, with this variable being reset to a value of -1. However, all further data-structures created from the event must be cleaned up using the appropriate functions.

In the example of use given below we will create an audio queue with 10 buffered audio sounds added to it and then play the queue:

audio_queue = audio_create_play_queue(buffer_s16, 11052, audio_mono);
for (var i = 0; i < 10; i++;)
   {
   audio_queue_sound(audio_queue, audio_buffer[i], 0, buffer_get_size(audio_buffer[i]));
   }
audio_play_sound(audio_queue, 0, true);


Every game step now that the recording is detected will trigger an asynchronous Audio Recording event where you can deal with the recorded input something like this:

var queue = async_load[? "queue_id"];
var num = 0;
if queue = audio_queue
   {
   for (var i = 0; i < 10; i++;)
      {
      if async_load[? "buffer_id"] == audio_buffer[i]
         {
         buffer_seek(audio_buffer[i], buffer_seek_start, 0);
         num = i;
         }
      }
   if num == 9
      {
      audio_stop_sound(audio_queue);
      audio_free_play_queue(audio_queue);
      }
   }


Here we check the queue ID and if it's the one we want, we then check the buffer ID to see which buffer has finished being played. We also then set a local var to that index value for checking later and set the buffer back to the start for that sound. Once our local variable reaches 9, indicating that the queue has finished, we stop the sound playing and free the queue.

This event can only be triggered by the audio_start_recording() function and will return a ds_map stored in the variable async_load, containing different key/value pairs depending on the call-back from the function that has triggered the event.

The following keys will be available in the ds_map:

  • "buffer_id" - the ID of the temporary buffer you can use to retrieve the audio data
  • "channel_index" - the recording channel index as returned by the calling function that this data came from
  • "data_len" - the length of data (in bytes) you've received
NOTE: As mentioned at the start of this page, the variable async_load is only valid in the asynchronous events, as the ds_map that is points to is created at the start of the event, then deleted again at the end. However, note that the temporary buffer in which all audio is stored with the map will also be removed at the end of the event so you should copy it to a custom buffer if you want to keep it for later use.

In the usage example below we will create a custom buffer to store our recorded audio, and also set our game to record from input source 0:

channel_index = audio_start_recording(0);
audio_buffer = buffer_create(len, buffer_fast, 1);


Every game step now that the recording is detected will trigger an asynchronous Audio Recording event where you can deal with the recorded input something like this:

var channel = async_load[? "channel_index"];
if channel == channel_index
   {
   len = async_load[? "data_len"];
   buffer_copy(async_load[? "buffer_id"], 0, len, audio_buffer, 0);
   }


Here we simply check the "channel_index" key to make sure it matches the value returned when we started recording, and if it does we copy the contents of the temporary buffer created for this event into our custom buffer. After that you can do what you want with the custom buffer - you could play it using the dedicated buffer audio functions, you could process it and send it over the network, you could save it to disk... Once you have your recorded audio in a buffer, you can do basically anything you want.

The Cloud Event is one that is triggered by the call back from one of the cloud_ functions, like cloud_synchronise. It actually generates a ds_map that is exclusive to this event and is stored in the special variable async_load (please see the individual functions for code examples that explain the use of this event in further detail). This ds_map has the following structure:

  • "status": This holds the status code, where a negative value denotes an error, a description of which will be contained in the “errorString”. A value of 0 (or a positive value) indicates a success(see below for exact values), and the “resultString” will contain the returned data or a success message.

  • "id": The id which was returned from the called function. If you fire off a series of cloud_ requests then you need to know which one you are getting the reply to, and so you would use this value to compare to the value you stored when you originally sent the request to find the right one.

  • "description": The description of the last uploaded file.

  • "resultString": This holds a string which is the data blob returned from the cloud.

  • "errorString": returns an Error String for any error.
The exact meaning of the returned "status" map entry is explained in the following table:
Status Value errorString / resultString Description
-1 errorString = "Not logged in to <SERVICE>" You have not successfully logged in to the given Cloud Service
0 resultString = recovered data New game data downloaded from the cloud (following a cloud_synchronise call)
1 resultString = "AlreadySynchronized" No new data since you last called cloud_synchronise
2 resultString = "ConflictDeferral" A conflict was encountered, but the gamer chose to ignore it
3 resultString = "GameUploadSuccess" data from cloud_string_save or cloud_file_save was successfully uploaded to the cloud
-n errorString = Description of error Any other negative number means a synchronisation failure

Like the above events, the Dialogues event is only triggered when it gets a call back from one of the special asynchronous user functions, like get_login_async() (please see this function for an extended code example of how this event is used). These events are the ones that ask for some type of user input, which can be a name, login details, a number or a colour etc... As most devices do not like sitting in a loop waiting for a reply, they have to be asynchronous and GameMaker Studio 2 will continue to run in the background while these functions have a dialogue open and until they get the required user input which triggers this event.

Again, a ds_map is returned with the id held in the special variable async_load. The values held in this map will depend on the function used, and you should consult the individual entries for each function in this manual for more details.

The HTTP Event is one that is triggered by the call back from one of the http_ functions, like http_post_string. It actually generates a ds_map (sometimes known as a "dictionary") that is exclusive to this event and is stored in the special variable async_load (please see the individual functions for code examples that explain the use of this event in further detail). This ds_map has the following structure:

  • "id": The id which was returned from the command. If you fire off a series of http_ requests then you need to know which one you are getting the reply to, and so you would use this value to compare to the value you stored when you originally sent the request to find the right one.

  • "status": Returns a value of less than 0 for an error, 0 for success and 1 if content is being downloaded.

  • "result": The data received (string only), or the path to the file downloaded if you have used http_get_file().

  • "url": The complete URL you requested.

  • "http_status": The raw http status code (if available). This returns the standard web status code for most browsers, eg: 304 for "Not Modified" or 204 for "No Content", etc...
That is for when you use the http_post_string() function, but each of the http_ functions may return a slightly different map, so please refer to the manual entry for each function to find out the precise data that is returned for it.

NOTE: As async_load creates a ds_map, these functions are particularly useful when coupled with the json_encode and json_decode functions.


There could also be additional data supplied by this map if you have requested files for downloading. In this case, the "status" will have a value of 1 and the ds_map will hold these extra keys:

  • "contentLength": This is the size of file that the web server has said you should expect to receive (may be -1 if the server does not return this data).

  • "sizeDownloaded": The size of the data that has already been downloaded.
Note that the event will not be triggered for every single data packet that is received, but will rather update at any time during the download within the main game loop. Also note that currently this functionality is only available for regular Windows target platforms.

This event can only be triggered by the various In App Purchase extensions for the different target platforms available on the Marketplace. This event will always generate a DS map that is exclusive to this event and stored in the special variable async_load. This DS map will have different key/value pairs depending on the extension function that triggered it, but there will always be an "id" key which can ten be used to identify the type of IAP event that it is. For exact details of the possible return values and functions that generate this event, please see the individual PDF manuals included with each of the extensions.

This event is triggered when you load an image into GameMaker Studio 2, as long as you have used a valid URL or path with the applicable load file function. For example say you want to load a sprite image, and only change the current sprite for the instance to the new one when it has loaded. Well you would have something like this in a create event or an alarm event (for example):

spr = sprite_add("http://www.angusgames.com/game/background1.png", 0, false, false, 0, 0);

This will now start to load the image into the device or the browser, but it will not block GameMaker Studio 2 while it waits for the file to be loaded. Instead GameMaker Studio 2 will keep running as normal until the image is loaded and the call back triggers the Image Loaded event, where a ds_map is created and stored in the special variable async_load. The map contains the following information:

  • "filename": The complete path to the file you requested.

  • "id": The ID of the resource that you have loaded. This will be the same as the variable that you have assigned the resource to.

  • "status": Returns a value of less than 0 for an error.

You would then assign the newly loaded image to a background in this event. The above is also true for sprites and sounds, with a ds_map being generated for each of these resources as shown above, and the following code example demonstrates how the returned information would be used in this event:

if ds_map_find_value(async_load, "id") == spr
   {
   if ds_map_find_value(async_load, "status") >= 0
      {
      sprite_index = spr
      }
   }

The above code will first check the id of the ds_map that has been created, then check the status of the callback. If the value is greater than or equal to 0 (signalling success) the result from the callback will then be used to set the background index to the newly loaded image.


The Networking event is one which will be triggered by any incoming network traffic, and is linked to the Network Functions. This event generates a special ds_map that is exclusive to this event and is stored in the special variable async_load. This ds_map will contain different information depending on the type of network event that generated it.
The following keys are common to all received network functions and will always be present in the async_load map:

  • "type": This will have one of the constants listed below as its return value, and designates the network event type.

  • "id": The socket id (a real number, as returned by the network_create_server or network_create_socket function) that is receiving the event. In most cases the socket ID returned is the ID of TCP or UDP socket that triggered the event, however if the event is triggered in a server and it's a Data Event (see below) then the socket ID is that of the client that sent the data.

  • "ip": The IP address of the socket (as a string).

  • "port": The port associated with the IP address (useful when working with UDP).
The possible return values for the "type" key can be any of the three constants listed below:
Constant Description
network_type_connect The event was triggered by a connection.
network_type_disconnect The event was triggered by a disconnection.
network_type_data The event was triggered by incoming data.
network_type_non_blocking_connect The event was triggered by a connection configured as non-blocking (you can use the function network_set_config() for this).

When you have an event of the type network_type_connect or network_type_disconnect, the async_load map will have the following additional key:

  • "socket": This key will hold the connecting/disconnecting socket id.

If the event is of the type network_type_non_blocking_connect, then additionally there will be the following key:

  • "succeeded": This key will be either 0 or 1, where 0 means the connection timed out and 1 means it succeeded and the socket is ready to use.
It is worth noting that the Networking Event does not get triggered in clients when the server disconnects, and that neither of the network_type_* events will be triggered in clients when the server they are connected to disconnects, even if the connection is TCP based.

When you have a network_type_data type event, which signifies that your network has received data, the map created will have the following keys:

  • "buffer": This is the unique "buffer id" which is generated by the event. A "grow" type buffer, byte aligned to 1, is created to hold the id should be stored in a variable and used for all further function calls to the buffer in this event. Just like the async_load map, the buffer created is automatically removed from memory at the end of this event. For more information on buffers, please see Reference - Buffers

  • "size": This is the size (in bytes) of the buffer data that is being received.
NOTE: The buffer created is only valid in these events and will be freed when the event is over.

The Push Notification Event is one that is triggered by the call back from push notifications on the device OS, either from a local source using the function push_local_notification, or from a remote source (ie: your server). It generates a ds_map that is exclusive to this event and is stored in the special variable async_load (please see the individual functions that trigger asynchronous events for code examples that explain the use of this event in further detail). This ds_map has the following keys:

  • "type": Value can be "local" for a device local notification, "remote" for a remote notification, or "register" for remote notification registration.
  • "status": Value will be "1" for success or "0" for an error.
There may be additional key entries based on the "type" returned and the "status" value. For "status", if an error has been returned ("0"), then you will also have the following key:

  • "error": Contains details of the error received.
If the "status" value is 1 (ie: no errors) then the ds_map will contain the following additional values, depending on the value of the "type" key:

  • "reg_id": If the "type" received was "register", then this key will hold the device registration id for remote notifications.
  • "data": If the "type" received was "local" or "remote", then this key will hold the string payload that you defined when you called the notification function.
To understand this better, we have created a small example snippet below for you to look at. In this example we will send a local push notification using the following code:

var fireTime = date_inc_day(date_current_datetime(), 1);
var data = "daily_reward";
push_local_notification(fireTime, "Ahoy!", "Catch The Haggis Has A Present", data);


This will set a timer to "push" a notification to the device when one day has passed. When the day is up, if your game is either in the background or not running, a notification will be shown to the user with the given title and message (on iOS, the game name is shown and the title is ignored), and then an asynchronous Push Notification Event will be called. Note that if the game is in the foreground when the time for the notification comes, it will not be shown, but the asynchronous event will still trigger. In the event itself you would handle the callback something like this:

var type = ds_map_find_value(async_load, "type");
var status = ds_map_find_value(async_load, "status");
if status == 0
   {
   //error of some kind
   var error = ds_map_find_value(async_load, "error");
   show_debug_message("error=" + string(error));
   }
else
   {
   if type == "register"
      {
      global.reg_id = ds_map_find_value(async_load, "reg_id");
      }
   else
      {
      var data = ds_map_find_value(async_load, "data");
         if data == "daily_reward"
         {
         global.Gold += 1000;
         }
      }
   }


This event will be triggered by certain functions related to loading and saving buffers to files, as well as when loading or unloading audio from memory. The event itself will contain the built in async_load DS map which will be populated by the keys required for the specific function. These are listed in the sections below.
When you use the functions buffer_save_async() or buffer_load_async() an asynchronous event will be triggered when the data transfer has been completed. This event will populate the async_load map with the following key/value pairs

  • "id": the ID of the async function as returned by the function used.
  • "status": will return true if the data was saved/loaded correctly, and false otherwise.
This permits you to poll the saving/loading progress and display a message or change rooms etc... when the process is complete.

When working with Audio Groups, you can load them an unload them from memory using the functions audio_group_load() and audio_group_unload(). When using the load function, it will trigger this event when the full set of audio files set for the group has been loaded into memory and will populate the map with the following key/value pairs:

  • "type": this tells us the type of event being called and will be "audiogroup_load" for loading audio.
  • "group_id": will return the ID of the audio group that has been loaded (as defined in the Audio Group Editor).
When all audio has been loaded for a group, this event will trigger and it can then be used to change rooms, or play a music track etc...

This event can only be triggered by the various specific Social Functions and will return a ds_map stored in the variable async_load, containing different key/value pairs depending on the callback from the function that has triggered the event.

The ds_map will contain a number of keys, the most important of which is the "id" key. This will return a constant which can then be checked in code to determine which of the many callbacks the event has received. Once you have parsed this key and compared the value returned with the available constants, you can then continue to extract the rest of the information from the map.
The function pages on Social Gaming - Achievements and Leaderboards in the Reference section detail the functions and callbacks as well as the constants used to trigger this event, but there are also certain circumstances in which it will be triggered without a function call from the game that is running:

  • when your game is launched from the OS dashboard
  • when you complete a challenge
  • when another player completes a challenge
  • when the game is started from the OS dashboard by selecting a challenge

Any of the above callbacks will trigger the Social Event and an async_load map will be generated with the following details (note that there is a different "id" key value to define each of the different reasons that the event was called, but all other contents of the map are the same):

  • "id" - The value of this key will depend on the type of callback triggering the event. it can be one of these constants:

    • achievement_challenge_received - A challenge has been received
    • achievement_challenge_completed - A challenge has been completed.
    • achievement_challenge_completed_by_remote - A challenge has been completed by the other player.
    • achievement_challenge_launched - The game was launched from the OS dashboard with the given challenge.
  • "playerid" - The player id for the challenge.

  • "issuerid" - The id of the person that issued the challenge.

  • "state" - The state of the challenge, which will have a value of 0 - 3 (as a string) for invalid, pending, completed or declined.

  • "message" - The text message for challenge.

  • "issueddate" - The issue date for challenge

  • "completeddate" - The completion date for challenge.

  • "type" - The type of challenge given. Can be one of two constants:

    • achievement_type_score_challenge - A challenge based on the score value.
    • achievement_type_achievement_challenge - A challenge based on an achievement.
  • "identifier" - The identifying string for the challenge.

  • "score" - The score tied in with the challenge.
Below you can find a small snippet of code as an example of use:

var ident = ds_map_find_value(async_load, "id" );
if ident == achievement_challenge_completed;
   {
   player_id = ds_map_find_value(async_load, "playerid");
   issuer_id = ds_map_find_value(async_load, "issuerid");
   state = ds_map_find_value(async_load, "state");
   date_completed = ds_map_find_value(async_load, "completeddate");
   date_issued = ds_map_find_value(async_load, "issueddate");
   ach_type = ds_map_find_value(async_load, "type");
   ach_ident = ds_map_find_value(async_load, "identifier");
   ach_score = ds_map_find_value(async_load, "score");
   }



This event can only be triggered by the Steam API functions and will return a ds_map stored in the variable async_load, containing different key/value pairs depending on the call-back from the function that has triggered the event. The map will always contain the key "event_type" which can then be parsed to find the type of function that triggered the event and change the code required to suit.

When calling any function that triggers this event, it will generate a unique async ID value which should be stored in a variable and checked, as the async_load map will always contain an ID key which you can then parse and ensure that you are responding to the correct event. In fact, the map will always hold the following keys, regardless of the Steam function used to generate the async response:

  • "id" - The async ID returned by the function that triggered the event

  • "result" - The result of the operation (a real value). This will either be the GML constant ugc_result_success or some other real number. So you should check for this constant to ensure that the call was successful, and if otherwise something has not worked correctly. The rest of the possible values returned are shown as the result of the Steam "EResult" value and you should see steamclientpublic.h in the SDK headers for all 89 possible values.

  • "event_type" - A string denoting the type of event (see below for the details)
When using the Steam functions for uploading a leaderboard (either steam_upload_score() or steam_upload_score_buffer()) the returned ds_map will have the following key/value pairs:

  • "event_type" - This key will hold the value "leaderboard_upload"

  • "post_id" - This key should match the ID value returned by the upload calling function

  • "lb_name" - This key holds the name of the leaderboard which was posted to

  • "success" - Will be 1 if the post succeeded, 0 failed

  • "updated" - Will be 1 if the leaderboard score was actually updated (ie: the new score was better) or 0 otherwise

  • "score" - This key holds the score which was posted
You can see examples of this on the pages for the score upload functions.

When using the Steam functions for downloading a leaderboard (steam_download_scores(), steam_download_scores_around_user() or steam_download_friends_scores()) the returned ds_map will have the following key/value pairs:

  • "event_type" - This key will hold the value "leaderboard_download"

  • "id" - This key should match the ID value returned by the download calling function

  • "status" - The status of the callback, where -1 equals a failure or that no results were returned, and 0 equals a success.
  • "lb_name" - This key holds the name of the leaderboard which was posted to

  • "numEntries" - The number of "rows" of leaderboard data that is being returned.

  • "entries" - A JSON object string that contains another ds_map, which will either contain the key "default" (signifying that no results are contained within) or the key "entries", which you can then get the value of. this returned value for "entries" will be a ds_list containing each of the ranks from the leaderboard, where each entry in the list will itself reference another ds_map which will contain the keys "name", "score" and "rank", and it may also contain a "data" key depending on the function used to upload.
We will show an example of how downloading score data works by requesting the top ten ranking for the given leaderboard and parsing its results in the Steam Async Event (for uploading examples, please see the appropriate function pages). To start with we need to request the scores with the following code:

score_get = steam_download_scores("Game Scores", 1, 10);


This will send off a request to the Steam Server for the scores from the leaderboard "Game Scores", storing the async ID of the request in the variable "score_get". This will then be handled in the Steam Async Event in the following way:

var async_id = ds_map_find_value(async_load, "id");
if async_id == score_get
   {
   var entries = ds_map_find_value(async_load, "entries");
   var map = json_decode(entries);
   if ds_map_exists(map, "default")
      {
      ds_map_destroy(map);
      exit;
      }
   else
      {
      var list = ds_map_find_value(map, "entries");
      var len = ds_list_size(list);
      var entry;
      for(var i = 0; i < len; i++;)
         {
         entry = ds_list_find_value(list, i );
         steam_name[i] = ds_map_find_value(entry, "name");
         steam_score[i] = ds_map_find_value(entry, "score");
         steam_rank[i] = ds_map_find_value(entry, "rank");
         if (ds_map_exists(entry, "data"))
            {
            var data = ds_map_find_value(entry, "data");
            var buffId = buffer_base64_decode(data);
            var message = buffer_read(buffId, buffer_string);
            show_debug_message( " -- attached message: " + string(message));
            buffer_delete(buffId);
            }
         ds_map_destroy(entry);
         }
      ds_list_destroy(list)
      }
   ds_map_destroy(map)
   }


What we do here is first check the "id" key of the special async_load map. If this value is the same as the value of the original call-back function (stored in the "score_get" variable) we then continue to process the data. The first thing we do is parse the async_load ds_map for the key "entries" which will contain a JSON object containing the leaderboard data. This JSON object is then decoded (see json_decode) as another ds_map, and this new map id is stored in the variable "map".

This map is checked for the key "default" and if that is found then the map is destroyed and the event is exited. If no "default" key is found, the code will then parse the map to extract the necessary information about the leaderboard, by first extracting a ds_list from the "entries" key of the ds_map, and then looping through each entry of the list to get another ds_map with the name, score and rank of each entry. These values are then stored in arrays and then we check to see if there is an additional "data" key. If there is (ie: the score was uploaded with an additional data package) then we also parse that and send it to the compiler console for debugging, before destroying the buffer and then continuing on to destroy the map. Note that if the "data" key is included, it needs to be decoded using the buffer_base64_decode() before it can be correctly read.

Once the loop has finished, the entries list is destroyed as is the map that it was taken from. There is no need to destroy the async_load ds_map as this is handled for you by GameMaker Studio 2.

When using the Steam functions for downloading User Generated Content (UGC), a number of them will trigger this event. However, each function will generate an async_load ds_map with differing key/value pairs (although they will always contain the general "id", "result" and "event_type" keys), so please see the page specific to the function being used for details and examples.

The Steam Async event can also be triggered when a user subscribes to an item outside of the game - for example, they tab away to a browser and subscribe to a new item then tab back to the game. In these cases the async_load map will only contain the following details (and none of the default values listed at the top of this page):

  • "event_type" - This key will hold the value "ugc_item_installed"

  • "published_file_id" - the ID of the newly installed UGC item (you can use the function steam_ugc_get_item_install_info() to get the path to the installed item)

The Steam Async event can also be triggered when a workshop item is subscribed to - either from within the app, or externally from a workshop browser - and in these cases the async_load map will contain the following key/value pairs:

  • "event_type" - This key will hold the value "ugc_item_subscribed""

  • "published_file_id" : This key has the published file ID of the newly subscribed item

The event will be triggered should any item be un-subscribed too, with the DS map holding the following:

  • "event_type" - This key will hold the value "ugc_item_unsubscribed""

  • "published_file_id" : This key has the published file ID of the un-subscribed item


This event can only be triggered by a system level event (such as the detection of a gamepad or the automatic signing in to XBox Live) and it will return a ds_map stored in the variable async_load, containing different key/value pairs depending on the system level event that triggered the call-back.

When this event is triggered for a gamepad being connected or disconnected it will return one of the following key/value pairs in the async_load map:

  • "event_type" - the type of system event received, which will be one of the following strings:

    • "gamepad discovered" - happens when the system reports a new gamepad has been connected
    • "gamepad lost" - happens when the system has lost connection to a gamepad
  • "pad_index" - the index of the pad that has been added or removed

This event now permits you to move all your gamepad checking logic from the Step Event or an Alarm event into the System Event and only run it when it's actually required.

IMPORTANT! This event will NOT be triggered unless you have at least one gamepad_* function or DnD™ action in your game code. The runner will only initialise the gamepad sub-system when the functions are used in the project, so if they aren't present, adding/removing gamepads will not trigger the System Event.

When this event is triggered for a virtual keyboard being opened or closed it will return the following key/value pairs in the async_load map:

  • "event_type" - the type of system event received, which will be "virtual keyboard status" for virtual keyboards.

  • "screen_height" - the height of the virtual keyboard (in pixels). This will be 0 if the keyboard is invisible.

  • "keyboard_status" - the current status of the keyboard, returned as one of the following strings:

    • "hiding"
    • "hidden"
    • "showing"
    • "visible"

See here for more information on the virtual keyboard.


The asynchronous system event can be triggered when targeting the XBox One using the UWP export and checking the Enable XBox Live option in the UWP Game Options. When you start GameMaker Studio 2 UWP project that has Xbox Live enabled the project will automatically try silently sign-in to Xbox Live. The results of this sign-in attempt will be returned as one of the following key/value pairs in the async_load map:

  • "event_type" - the type of system event received, which will be one of the following strings:

    • "user signed in" - the silent user sign-in has been completed successfully
    • "user sign in failed" - the silent user sign-in has failed (when this happens you can use the function xboxlive_show_account_picker() to get the user to choose an account to sign in with)
    • "user signed out" - the user has signed out

For more information on the specific functions available for XBox Live, please see here.


This event type is specifically for use when working with the HTML5 target, as it will be triggered every time the Web Audio context status changes. This means that if you have, for example, a piece of looping background music, then you can pause it or stop and restart it, based on this event triggering. This can be checked by looking for the following key/value pair in the async_load map:

  • "event_type" - the type of system event received, which will be the following string for an audio event:

    • "audio_system_status" - The audio system has initialised or the context has changed.

If this event type is triggered, then there will be an additional key in the async_load map:

  • "status" - The status of the audio system, which will be one of the following two strings

    • "available" - The audio system is initialised and available to play sounds
    • "unavailable" - The audio system is not initialised, or the context is not currently running, and so can't play sounds (all sound playing functions will return -1)

For more information on the specific functions available for Audio, please see here.

NOTE: While this event is designed for use with the HTML5 target, it will also be triggered on all other platforms, but on everything (except HTML5) it will only be triggered once on Game Start when the audio engine is first initialised.