From 1fe5f730861bccc82f94acd79f189cc096cdeb73 Mon Sep 17 00:00:00 2001 From: YYBartT Date: Tue, 3 Oct 2023 10:52:37 +0200 Subject: [PATCH 01/97] [Feature]Feature Request #1318 * Added new function page using batch script and added item to ToC, updated links * Added new See Also that lists all functions that add assets at runtime and linked it on the page --- .../Assets_And_Tags/Assets_And_Tags.htm | 37 +++++----- .../Assets_And_Tags/asset_get_ids.htm | 72 +++++++++++++++++++ .../Assets_And_Tags/asset_get_index.htm | 8 +-- .../Assets_And_Tags/asset_get_tags.htm | 4 +- .../Assets_And_Tags/tag_get_assets.htm | 12 ++-- .../Object_Properties/Parent_Objects.htm | 60 +++++----------- Manual/contents/assets/scripts/gml.js | 2 + Manual/seealso/keywords.seealso | 2 +- Manual/toc/Default.toc | 1 + 9 files changed, 123 insertions(+), 75 deletions(-) create mode 100644 Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Assets_And_Tags/asset_get_ids.htm diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Assets_And_Tags/Assets_And_Tags.htm b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Assets_And_Tags/Assets_And_Tags.htm index 7da4edc34..9eb716dfa 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Assets_And_Tags/Assets_And_Tags.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Assets_And_Tags/Assets_And_Tags.htm @@ -4,7 +4,7 @@ Assets And Tags - + @@ -15,32 +15,33 @@

Assets And Tags

-

The functions listed here are specifically designed for getting information from any of the assets defined in the Asset Browser, as well as the tags that have been assigned to them. Tags are a very powerful tool, both in the Asset Browser and in your actual game code, as they can be read and created at run time, giving you additional ways to filter assets when your game is running and create conditional checks or "parent"-type systems outside of the object-based system.

-

For assets in general we have the following functions:

+

The functions listed here are specifically designed for getting information from any of the assets defined in The Asset Browser, as well as the tags that have been assigned to them.

+

Tags are a very powerful tool, both in The Asset Browser and in your actual game code, as they can be read and created at runtime, giving you additional ways to filter assets when your game is running and create conditional checks or "parent"-type systems outside of the object-based system.

+

Function Reference

+

General

-

 

-

For dealing with the Asset browser "tags" system, we have the following functions:

+

Tags

 

 

-

 

buffer_base64_decode_ext

-

With this function you can decode a base64 encoded string (created using the buffer_base64_encode() function) into a buffer. Unlike the function buffer_base64_decode(), - this will not create a buffer for you, but rather you should already have created the buffer (see buffer_create()), the id of which you would then use with this function. The "offset" is the - position within the buffer to decode the given string (in bytes).

+

With this function you can decode a base64 encoded string (created using the buffer_base64_encode() function) into a buffer. Unlike the function buffer_base64_decode(), this will not create a buffer for you, but rather you should already have created the buffer (see buffer_create()), the id of which you would then use with this function. The "offset" is the position within the buffer to decode the given string (in bytes).

 

Syntax:

buffer_base64_decode_ext(buffer, string, offset);

- + + - + - + + - + - + + - + - + + - +
ArgumentTypeArgumentType Description
bufferbufferBuffer ID The index of the buffer to decode the string into.
stringstringString The base64 encoded string to decode.
offsetoffsetReal The data offset value.

 

Returns:

-

+

N/A

 

Example:

-

buff = buffer_create(16384, buffer_grow, 2);
ini_open("Save.ini"); -
var str = ini_read_string("Save", "Slot1", "");
buffer_base64_decode_ext(buff, str, 0);
ini_close(); -

-

The above code will create a buffer and store the unique id for it in the variable "buff", then open an ini file and read a string from it into the local variable "str". This string is then decoded into the newly created buffer before - closing the ini file again.

+

buff = buffer_create(16384, buffer_grow, 2);
+ ini_open("Save.ini");
+ var str = ini_read_string("Save", "Slot1", "");
+ buffer_base64_decode_ext(buff, str, 0);
+ ini_close();

+

The above code will create a buffer and store the unique id for it in the variable "buff", then open an ini file and read a string from it into the local variable "str". This string is then decoded into the newly created buffer before closing the ini file again.

 

 

 

@@ -59,10 +62,10 @@

Example:

-
© Copyright YoYo Games Ltd. 2021 All Rights Reserved
+
© Copyright YoYo Games Ltd. 2023 All Rights Reserved
+ + + \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Buffers/buffer_get_size.htm b/Manual/contents/GameMaker_Language/GML_Reference/Buffers/buffer_get_size.htm index f9d7fec4e..12511612b 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Buffers/buffer_get_size.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Buffers/buffer_get_size.htm @@ -4,7 +4,7 @@ buffer_get_size - + @@ -29,14 +29,14 @@

Syntax:

buffer - Buffer ID + Buffer ID The index of the buffer to get the size of.

 

Returns:

-

Real

+

Real

 

Example:

var _size = buffer_get_size(player_data);
@@ -49,10 +49,10 @@

Example:

Back: Buffers
-
Next: buffer_get_surface
+
Next: buffer_resize
-
© Copyright YoYo Games Ltd. 2022 All Rights Reserved
+
© Copyright YoYo Games Ltd. 2023 All Rights Reserved

buffer_set_used_size

This function is primarily for use within extensions, and allows you to set the "used" size of the given buffer, which is the number of bytes that have been written to it.

-

When you write data to a buffer from an extension, GameMaker does not know how much of the buffer was filled by the extension code and is not able to read that data. This function can be called by the extension to tell the engine how many bytes of data - was written to the buffer, so the engine can read that data.

+

When you write data to a buffer from an extension, GameMaker does not know how much of the buffer was filled by the extension code and is not able to read that data. This function can be called by the extension to tell the engine how many bytes of data was written to the buffer, so the engine can read that data.

 

Syntax:

buffer_set_used_size(buffer, size);

- + + - + - + + - + - + + - +
ArgumentTypeArgumentType Description
bufferbufferBuffer ID The index of the buffer to use.
sizesizeReal The number of bytes to set as the "used" size.

 

Returns:

-

+

N/A

 

Example:

-

buffer_write(_bufferAddress, buffer_u8, 1);
buffer_write(_bufferAddress, buffer_u8, 2);
buffer_write(_bufferAddress, buffer_u16, 400);
-
buffer_set_used_size(_bufferAddress, 4);

+

buffer_write(_bufferAddress, buffer_u8, 1);
+ buffer_write(_bufferAddress, buffer_u8, 2);
+ buffer_write(_bufferAddress, buffer_u16, 400);
+
+ buffer_set_used_size(_bufferAddress, 4); +

The above functions would be called in an extension to write some data to a GameMaker buffer (through its memory address), and then set the number of bytes that were written to it so the engine can read that data.

 

 

@@ -51,10 +57,10 @@

Example:

Back: Buffers
-
Next: buffer_exists
+
Next: buffer_copy
-
© Copyright YoYo Games Ltd. 2021 All Rights Reserved
+
© Copyright YoYo Games Ltd. 2023 All Rights Reserved

buffer_sizeof

-

This function will return the size (in bytes) of the given Buffer Data Type Constant (listed here).

+

This function will return the size (in bytes) of the given Buffer Data Type Constant (listed here).

 

Syntax:

buffer_sizeof(type);

@@ -29,14 +29,14 @@

Syntax:

type - Buffer Data Type Constant + Buffer Data Type Constant The type of data that is to be checked (see the list of constants here).

 

Returns:

-

Real

+

Real

 

Example:

var b = 12 * buffer_sizeof(buffer_u8);
@@ -49,10 +49,10 @@

Example:

Back: Buffers
-
Next: buffer_md5
+
Next: buffer_set_used_size
-
© Copyright YoYo Games Ltd. 2022 All Rights Reserved
+
© Copyright YoYo Games Ltd. 2023 All Rights Reserved
-

Asset Management

-

The following sections explain the functions and variables that you have available to you for manipulating the different assets used in your project, including creating new dynamic assets or editing and changing those that are added into your game through the Asset Browser in the room editor or sequence editor.

+

Asset Management

+

The following sections explain the functions and variables that you have available to you for manipulating the different assets used in your project, including creating new dynamic assets or editing and changing those that are added into your game through The Asset Browser in The Room Editor or The Sequence Editor.

-

 

+

Dynamically Added Assets

+

Functions for Particle Systems can be found here: Particle Systems

There are also extra functions related to the handling of game assets and tags added from the Asset Browser. These functions can be found in the following section:

You get a handle when you create a new resource (with a _create() function) or reference an existing resource in your code (like referencing an object, getting an instance through a function, etc.).

diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Buffers/Buffers.htm b/Manual/contents/GameMaker_Language/GML_Reference/Buffers/Buffers.htm index bf15a1258..735975e91 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Buffers/Buffers.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Buffers/Buffers.htm @@ -24,14 +24,14 @@

Usage Notes

  • The "alignment" argument refers to how data is stored within a buffer. If your alignment is set to say, 4, and you write a single piece of data which is 1 byte in size then do a buffer_tell, you'll get an offset of 1. However, if you write another piece of data, also 1 byte in size, then do a buffer_tell, you'll get an offset of 5 as the alignment has "padded" the data to that size. Alignment only affects where things are written to, so if you do a buffer_tell after you write something, it'll return the current write position which immediately follows the data you've written. Note, however, that if you then write another piece of data, internally the buffer will move the write position along to the next multiple of the alignment size before actually writing the piece of data.
  • When dealing with "offset", this is the value in bytes to offset the data by within the given buffer. So if your buffer is 2 byte aligned and you want to skip the first 4 aligned places, you would have an offset of 2 * 4 bytes.
  • Some of the buffer functions also create a new buffer (like buffer_load for example). Remember that these buffers will also need to be removed from memory when not in use using the buffer_delete function.
  • -
  • The memory used for creating buffers is system memory so even when the game doesn't have focus, any data stored in a buffer should be safe, however if the app is closed or re-started then it will be lost.
  • +
  • The memory used for creating buffers is system memory so even when the game doesn't have focus, any data stored in a buffer should be safe, however if the app is closed or restarted then it will be lost.
  • The following pages explain how buffers work within the context of GameMaker and contain a couple of code examples for those users that are unsure of how to use them:

    -

    When you create a buffer, the index value used to identify it is an integer value starting at 0. These indices are re-used by GameMaker, so a destroyed buffer index value may be used by a newly created one afterwards, and we recommend that you set any variable that holds a buffer index to -1 after having destroyed the buffer.

    +

    When you create a buffer, a reference to the new buffer is returned. After the buffer is destroyed, we recommend that you set the variable that holds a buffer reference to -1.

    Function Reference

    General

      diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Buffers/buffer_async_group_begin.htm b/Manual/contents/GameMaker_Language/GML_Reference/Buffers/buffer_async_group_begin.htm index 0f57cfdc0..e4a23fbaa 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Buffers/buffer_async_group_begin.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Buffers/buffer_async_group_begin.htm @@ -4,7 +4,7 @@ buffer_async_group_begin - + @@ -14,12 +14,13 @@ -

      buffer_async_group_begin

      -

      This function is called when you want to begin the saving out of multiple buffers to multiple files (or loading multiple buffers). The groupname is a string and will be used as the directory name for where the files are saved, and should be used as part of the file path when loading the files back into the IDE later (using any of the buffer_load() functions). This function is only for use with the buffer_save_async() and buffer_load_async() functions and you must also end the async group by calling buffer_async_group_end() function otherwise the files will not be saved/loaded.

      -

      Note that for the console platforms (like PS4 for example), the groupname will be used as the save slot description, and using this function can help you avoid having the UI show for every file that is being saved out.

      +

      buffer_async_group_begin

      +

      This function is called when you want to begin the saving out of multiple buffers to multiple files (or loading multiple buffers).

      +

      The groupname is a string and will be used as the directory name for where the files are saved, and should be used as part of the file path when loading the files back into the IDE later (using any of the buffer_load functions). This function is only for use with the buffer_save_async and buffer_load_async functions and you must also end the async group by calling buffer_async_group_end function otherwise the files will not be saved/loaded.

      +

       For the console platforms (like PS4 for example), the groupname will be used as the save slot description, and using this function can help you avoid having the UI show for every file that is being saved out.

       

      Syntax:

      -

      buffer_async_group_begin(groupname);

      +

      buffer_async_group_begin(groupname);

      @@ -30,7 +31,7 @@

      Syntax:

      - +
      groupname StringThe name of the group (as a string).The name of the group
      @@ -39,7 +40,7 @@

      Returns:

      N/A

       

      Example:

      -

      buffer_async_group_begin("SaveGame");
      +

      buffer_async_group_begin("SaveGame");
      save1 = buffer_save_async(buff1, "Player_Save1.sav", 0, 16384);
      save2 = buffer_save_async(buff2, "Player_Save2.sav", 0, 16384);
      save3 = buffer_save_async(buff3, "Player_Save3.sav", 0, 16384);
      @@ -48,7 +49,6 @@

      Example:

      The above code starts a buffer group then sets it to save out 4 files asynchronously. The group definition is then ended (at which point saving will begin).

       

       

      -

       

      -

      buffer_async_group_end

      -

      This function finishes the definition of a buffer async group. You must have previously called the function buffer_async_group_begin() to initiate the group, then call the function buffer_save_async() for each file that you wish to save out (or buffer_load_async() to load buffers). Finally you call this function, which will start the saving of the files. The function will return a unique ID value for the save, which can then be used in the Asynchronous Save / Load event to parse the results from the async_load DS map.

      +

      buffer_async_group_end

      +

      This function finishes the definition of a buffer async group.

      +

      You must have previously called the function buffer_async_group_begin to initiate the group, then call the function buffer_save_async for each file that you wish to save out (or buffer_load_async to load buffers). Finally you call this function, which will start the saving of the files. The function will return a unique ID value for the save, which can then be used in the Asynchronous Save / Load event to parse the results from the async_load DS map.

       

      Syntax:

      -

      buffer_async_group_end();

      +

      buffer_async_group_end();

       

      Returns:

      Async Request ID

       

      -

      Extended Example:

      -

      The buffer_async_group_end() function can be called from any event, and since it is asynchronous the callback can be almost instantaneous or could take several seconds. Calling the function is simple and would look something like this:

      +

      Example:

      +

      The buffer_async_group_end function can be called from any event, and since it is asynchronous the callback can be almost instantaneous or could take several seconds. Calling the function is simple and would look something like this:

      buffer_async_group_begin("SaveGame");
      save1 = buffer_save_async(buff1, "Player_Save1.sav", 0, 16384);
      save2 = buffer_save_async(buff2, "Player_Save2.sav", 0, 16384);
      save3 = buffer_save_async(buff3, "Player_Save3.sav", 0, 16384);
      save4 = buffer_save_async(buff4, "Player_Save4.sav", 0, 16384);
      - save_id = buffer_async_group_end();

      -

      The above code starts a buffer group then sets it to save out 4 files asynchronously. The group definition is then ended (at which point saving will begin), storing the ID of the function call in the variable "save_id". When the save is complete, the asynchronous Save/Load event will be triggered and you can parse the async_load map for the correct ID of the function, like this:

      + save_id = buffer_async_group_end();

      +

      The above code starts a buffer group then sets it to save out 4 files asynchronously. The group definition is then ended (at which point saving will begin), storing the ID of the function call in the variable save_id. When the save is complete, the asynchronous Save / Load event will be triggered and you can parse the async_load map for the correct ID of the function, like this:

      if ds_map_find_value(async_load, "id") == saveid
      {
          if ds_map_find_value(async_load, "status") == false
      @@ -39,8 +40,7 @@

      Extended Example:

              show_debug_message("Save failed!");
          }
      }

      -

      The above code will first check the id of the DS map that has been created, then check the status of the callback, posting a debug message if there has been any issues.

      -

       

      +

      The above code first checks if the ID in the async_load DS map is the same as the one returned by the call to buffer_async_group_end, then checks the status of the callback and posts a debug message if there have been any issues.

       

       

      -

      buffer_compress

      -

      With this function you can compress part (or all) of a buffer using zlib compression. You supply the ID of the buffer to compress (as returned by buffer_create()), the offset within the buffer to use in bytes, and the size of the buffer data to compress (also in bytes). The function will return a new buffer ID value for the compressed buffer, or a value less than 0 if it has failed for any reason. This function will not alter the original buffer.

      +

      buffer_compress

      +

      This function compresses part (or all) of a buffer using zlib compression and returns a new buffer containing the compressed data.

      +

      You supply the buffer to compress (as returned by buffer_create), the offset within the buffer to use in bytes, and the size of the buffer data to compress (also in bytes). The function will return the compressed buffer as a new buffer, or -1 if it has failed for any reason.

      +

      The function does not alter the original buffer.

       

      Syntax:

      -

      buffer_compress(buffer, offset, size);

      +

      buffer_compress(buffer, offset, size);

      - + + - + - - - + + + + - + + - + - + + - +
      ArgumentTypeArgumentType Description
      bufferThe index of the buffer to compress.
      bufferBufferThe buffer to compress.
      offsetoffsetReal The offset within the buffer to compress (in bytes).
      sizesizeReal The size of the buffer area to compress (in bytes).

       

      Returns:

      -

      Buffer ID

      +

      Buffer or -1 in case anything went wrong

       

      Example:

      -

      var srcBuff = buffer_create(1024, buffer_grow, 1);
      - buffer_write(srcBuff, global.DataString);
      - var cmpBuff = buffer_compress(srcBuff, 0, buffer_tell(srcBuff));
      - buffer_save(cmpBuff, "Player_Save.sav");
      - buffer_delete(srcBuff);
      - buffer_delete(cmpBuff);

      -

      The above code will create a buffer then populate it with the data from a string. This buffer is then compressed and saved, and both the source and compressed buffers are deleted

      -

       

      +

      var _srcBuff = buffer_create(1024, buffer_grow, 1);
      + buffer_write(_srcBuff, global.DataString);
      + var _cmpBuff = buffer_compress(_srcBuff, 0, buffer_tell(_srcBuff));
      + buffer_save(_cmpBuff, "Player_Save.sav");
      + buffer_delete(_srcBuff);
      + buffer_delete(_cmpBuff);

      +

      The above code creates a buffer then populates it with the data from a string. This buffer is then compressed and saved, and both the source and compressed buffers are deleted.

       

       

      -
      © Copyright YoYo Games Ltd. 2022 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved

      buffer_copy_from_vertex_buffer

      -

      This function can be used to copy some (or all) of the vertex data stored in one vertex buffer into a previously created regular buffer. When copying from a vertex buffer into a regular buffer with this function, both buffers must have previously been created (using the vertex_create_buffer and buffer_create functions, for example). You can specify the range of vertex data that you wish to copy into the buffer, where the start vertex can be anywhere between 0 and the number of vertices -1, and you can give the number of vertices from that point on to copy. You can use the function vertex_get_number on the vertex buffer to get the total number of vertices stored. Finally you give the buffer index to copy the vertex data into, as well as a data offset to define the position to copy the vertex data to in the destination buffer.

      +

      This function copies some (or all) of the vertex data stored in one vertex buffer into a previously created regular buffer.

      +

      When copying from a vertex buffer into a regular buffer with this function, both buffers must have previously been created (using the vertex_create_buffer and buffer_create functions, for example). You can specify the range of vertex data that you wish to copy into the buffer, where the start vertex can be anywhere between 0 and the number of vertices -1, and you can give the number of vertices from that point on to copy. You can use the function vertex_get_number on the vertex buffer to get the total number of vertices stored. Finally you give the buffer index to copy the vertex data into, as well as a data offset to define the position to copy the vertex data to in the destination buffer.

       

      Syntax:

      buffer_copy_from_vertex_buffer(vertex_buffer, start_vertex, num_vertices, dest_buffer, dest_offset);

      @@ -28,8 +29,8 @@

      Syntax:

      vertex_buffer - Vertex Buffer ID - The index of the vertex buffer to copy from. + Vertex Buffer + The vertex buffer to copy from. start_vertex @@ -39,12 +40,12 @@

      Syntax:

      num_vertices Real - The total number of vertices to use. + The total number of vertices to copy. dest_buffer - Buffer ID - The index of the buffer to copy to. + Buffer + The buffer to copy to. dest_offset @@ -58,8 +59,9 @@

      Returns:

      N/A

       

      Example:

      -

      var v_num = vertex_get_number(model_buff); buffer_copy_from_vertex_buffer(model_buffer, 0, v_num - 1, player_buffer, 0);

      -

      The above code will copy the vertex data stored in the vertex buffer indexed in the variable "model_buffer", and then paste it into the buffer indexed in the variable player_buffer.

      +

      var _v_num = vertex_get_number(model_buff);
      + buffer_copy_from_vertex_buffer(model_buffer, 0, _v_num - 1, player_buffer, 0);

      +

      The above code copies the vertex data stored in the vertex buffer stored in the variable model_buffer, and then pastes it into the buffer stored in the variable player_buffer.

       

       

      -
      © Copyright YoYo Games Ltd. 2021 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved

      buffer_create

      -

      You use this function to allocate a portion of memory as a buffer in your game, with the function returning the unique buffer id that should be stored in a variable and used for all further function calls to the buffer. The buffer can then be used to store different types of data (specified when you write to the buffer using the buffer_write function, with the following constants being used to define the buffer type:

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Buffer Type Constant
      ConstantDescription
      buffer_fixedA buffer of fixed size.
      buffer_growA buffer that will "grow" dynamically as data is added
      buffer_wrapA buffer where the data will "wrap". When the data being added reaches the limit of the buffer size, the overwrite will be placed back at the start of the buffer, and further writing will continue from that point.
      buffer_fastSpecial "stripped" buffer that is extremely fast to read/write to. Can only be used with buffer_u8 data types, and must be 1 byte aligned.
      +

      This function creates a new buffer and returns it.

      +

      The function allocates a portion of memory for the buffer, which can then be used to store different types of data (specified when you write to the buffer using the buffer_writebuffer_poke or buffer_fill function).

      +

      The following constants can be used to define the buffer type:

      +

      Apart from the buffer type, you will also have to set the byte alignment for the buffer. This value will vary depending on the data that you wish to store in the buffer, and in most cases a value of 1 is perfectly fine. However, be aware that for some operations a specific alignment is essential, and an incorrect alignment may cause errors (for further details on alignment see Buffers). The following is a general guide to show which values are most appropriate for each data type (when in doubt, use an alignment of 1):

      • Strings should be aligned to 1 byte.
      • @@ -59,7 +31,7 @@

        buffer_create

      • Floats of up to 64bits should be aligned to 8 bytes.

       Byte alignment can be very important as the wrong choice may adversely affect performance.

      -

       It's important that you remove any dynamically created resources like this from memory when you no longer need them to prevent memory leaks, so when you are finished with the buffer that you have created you should free it up again using buffer_delete.

      +

       

      Syntax:

      buffer_create(size, type, alignment)

      @@ -89,11 +61,11 @@

      Syntax:

       

      Returns:

      -

      Buffer ID

      +

      Buffer

       

      Example:

      player_buffer = buffer_create(16384, buffer_fixed, 2);

      -

      The above code allocates 16384 bytes of memory to a buffer and returns the index of that buffer, which is stored in the variable player_buffer, for future use. The buffer is aligned to a two byte boundary.

      +

      The above code allocates 16384 bytes of memory to a buffer and returns the buffer, storing the reference to it in the variable player_buffer for future use. The buffer is aligned to a two byte boundary.

       

       

      -

      buffer_fill

      -

      This function can be used to fill a previously created buffer with a given data type and value. The data you fill the buffer with must be in agreement with the "type" argument of this function, meaning that you can't try to fill with a - string and use the unsigned 16bit integer type, for example. The type constants are the same as those used by the buffer_read() and buffer_write() functions. The "size" - is the size of the buffer (in bytes) that you wish to fill, while the offset is the offset value (also in bytes) from the start of the buffer to start the fill from.

      +

      buffer_fill

      +

      This function fills a previously created buffer with a given data type and value.

      +

      The data you fill the buffer with must be in agreement with the "type" argument of this function, meaning that you can't try to fill with a string and use the unsigned 16bit integer type, for example. The type constants are the same as those used by the buffer_read and buffer_write functions. The "size" is the size of the buffer (in bytes) that you wish to fill, while the offset is the offset value (also in bytes) from the start of the buffer to start the fill from.

       

      Syntax:

      -

      buffer_fill(buffer, offset, type, value, size);

      +

      buffer_fill(buffer, offset, type, value, size);

      - + + - + - - - + + + + - + + - + - + + - + - + + - + - + + - +
      ArgumentTypeArgumentType Description
      bufferThe index of the buffer to fill.
      bufferBufferThe reference to the buffer to fill.
      offsetoffsetReal The data offset value (in bytes).
      typetypeReal The type of data that is to be written to the buffer (see the list of constants here).
      valuevalueReal The data to write.
      sizesizeReal The size of the buffer (in bytes) that you wish to fill.

       

      Returns:

      -

      +

      N/A

       

      Example:

      -

      map_buffer = buffer_create(16384, buffer_fixed, 0);
      buffer_fill(map_buffer, 0, buffer_u16, 0, 16384);

      -

      The above code finds the start of the buffer with the id stored in the variable "buff" them writes a series of signed 16bit integer values to it.

      -

       

      +

      map_buffer = buffer_create(16384, buffer_fixed, 0);
      + buffer_fill(map_buffer, 0, buffer_u16, 0, 16384);

      +

      The above code finds the start of the buffer stored in the variable buff then writes a series of signed 16bit integer values to it.

       

       

      -
      © Copyright YoYo Games Ltd. 2021 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved
      -

      buffer_get_alignment

      -

      With this function you can get the a byte alignment for the given buffer ID.

      +

      buffer_get_alignment

      +

      This function gets the byte alignment of the given buffer.

       

      Syntax:

      -

      buffer_get_alignment(buffer);

      +

      buffer_get_alignment(buffer);

      - + + - + - - - + + + +
      ArgumentTypeArgumentType Description
      bufferThe index of the buffer to check.
      bufferBufferThe buffer to check.

       

      Returns:

      -

      +

      Real

       

      Example:

      -

      alignment = buffer_get_alignment(buff);

      -

      The above code will get the alignment of the buffer from the value indexed in the variable "buff" and store it in a variable.

      -

       

      +

      alignment = buffer_get_alignment(buff);

      +

      The above code gets the alignment of the buffer stored in the variable buff and store it in a variable.

       

       

      -
      © Copyright YoYo Games Ltd. 2021 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved
      -

      buffer_get_size

      -

      With this function you can get the size of the given buffer in bytes.

      +

      buffer_get_size

      +

      This function gets the size in bytes of the given buffer.

       

      Syntax:

      -

      buffer_get_size(buffer);

      +

      buffer_get_size(buffer);

      @@ -29,8 +29,8 @@

      Syntax:

      - - + +
      bufferBuffer IDThe index of the buffer to get the size of.BufferThe buffer to get the size of.
      @@ -41,8 +41,7 @@

      Returns:

      Example:

      var _size = buffer_get_size(player_data);
      var _temp = buffer_create(_size, buffer_fixed, 0);

      -

      The above code will create a new buffer and store its index in the local variable "_temp", with size of this new buffer being the same as that of the buffer indexed in the variable "player_data".

      -

       

      +

      The above code creates a new buffer and stores it in a local variable _temp, with the size of the new buffer being the same as that of the buffer stored in the variable player_data.

       

       

      -
      © Copyright YoYo Games Ltd. 2022 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved
      -

      buffer_load

      -

      This function is used to load a buffer that was previously saved using the buffer_save() functions, as well as any Included Files or files loaded externally. It will return a new buffer's ID which is created by the function as a "grow" buffer (see here) with a byte alignment of 1. This ID should be stored in a variable and used in all further function calls to this buffer. If the load fails for whatever reason, the function will return -1 and a message will be shown in the compiler output window saying that the load has failed.

      -

      NOTE It's important that you remove any dynamically created resources like this from memory when you no longer need them to prevent memory leaks, so when you are finished with the buffer that you have created you should free it up again using buffer_delete().

      -

      Platform-specific notes

      +

      buffer_load

      +

      This function loads a buffer that was previously saved using the buffer_save functions, as well as any Included Files or other files stored externally.

      +

      It returns a new buffer which is created by the function as a "grow" buffer (see here) with a byte alignment of 1. The buffer should be stored in a variable and used in all further function calls to this buffer. If the load fails for whatever reason, the function will return -1 and a message will be shown in the compiler output window saying that the load has failed.

      +
      +

      Platform-specific notes

      • On HTML5, any buffers loaded from the local storage will be decoded using base64 (since they are saved as base64 strings), however, using this function on Included Files or any external files will not use base64 decoding, as they are not expected to be in a base64 format.
      • On HTML5, all Included Files are stored as UTF-8 encoded text, which may result in an increase in the size of the loaded buffer when compared to the original file, as the UTF-8 encoded version of the file may have a different size than your original one (due to the change in format).

       

      -

       

      Syntax:

      -

      buffer_load(filename);

      +

      buffer_load(filename);

      - + + - + - + + - +
      ArgumentTypeArgumentType Description
      filenamefilenameString The name of the file to load from.

       

      Returns:

      -

      Buffer ID

      +

      Buffer

       

      Example:

      player_buffer = buffer_load("Player_Save.sav");

      -

      The above code will load a previously saved buffer into memory, creating a new buffer. The index of this new buffer is stored in the variable "player_buffer".

      -

       

      +

      The above code loads a previously saved buffer into memory, creating a new buffer. It is stored in a variable player_buffer.

       

       

      -
      © Copyright YoYo Games Ltd. 2022 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved
      -

      buffer_load_async

      -

      With this function you can load a file that you have created previously using the buffer_save() function (or any of the other functions for saving buffers) into a buffer. The "offset" defines the start position within the buffer for loading (in bytes), and the "size" is the size of the buffer area to be loaded from that offset onwards (also in bytes). You can supply a value of -1 for the size argument and the entire buffer will be loaded. Note that the function will load from a "default" folder, which does not need to be included as part of the file path you provide. This folder will be created if it doesn't exist or when you save a file using buffer_save_async().

      -

      The function returns a unique ID value which can then be used in the Save / Load Asynchronous event to check the async_load ID value, as shown in the extended example below. The async_load map in the event will have the following two key/value pairs:

      +

      buffer_load_async

      +

      This function loads a file that you have created previously using the buffer_save function (or any of the other functions for saving buffers) into a buffer.

      +

      The "offset" defines the start position within the buffer for loading (in bytes), and the "size" is the size of the buffer area to be loaded from that offset onwards (also in bytes). You can supply a value of -1 for the size argument to load the entire buffer. Note that the function will load from a "default" folder, which does not need to be included as part of the file path you provide. This folder will be created if it doesn't exist or when you save a file using buffer_save_async.

      +

      The function returns a unique ID value which can then be used in the Save / Load Asynchronous event to check the async_load's ID value, as shown in the extended example below. The async_load map in the event will have the following two key/value pairs:

      • "id": the ID of the async function as returned by the save function.
      • -
      • "status": will return true if the data was saved/loaded correctly, and false otherwise.
      • +
      • "status": will return true if the data was saved/loaded correctly, false otherwise.

      NOTE On HTML5, this is the preferred method for loading a file if you are loading from a server and not local storage, as loading synchronously has been deprecated on most browsers and will eventually be obsoleted.

      -

      Please read the buffer_load() page for platform-specific notes.

      +

      Please read the buffer_load page for platform-specific notes.

       

      Syntax:

      -

      buffer_load_async(buffer, filename, offset, size);

      +

      buffer_load_async(buffer, filename, offset, size);

      - + + - + - - - + + + + - + + - + - + + - + - + + - +
      ArgumentTypeArgumentType Description
      bufferThe index of the buffer to load.
      bufferBufferThe buffer to load.
      filenamefilenameString The name of the file to load.
      offsetoffsetReal The offset within the buffer to load to (in bytes).
      sizesizeReal The size of the buffer area to load (in bytes).

       

      Returns:

      -

      Async Request ID

      +

      Async Request ID

       

      -

      Extended Example:

      -

      The buffer_load_async() function can be called from any event, and since it is asynchronous the callback can be almost instantaneous or could take several seconds. Calling the function is simple and would look something like this:

      -

      loadid = buffer_load_async(buff, "Player_Save.sav", 0, 16384);

      -

      The above code loads the contents of the file "Player_Save.sav" to the given buffer, storing the ID of the function call in the variable "loadid". When the load is complete, the asynchronous Save/Load event will be triggered and you can parse the async_load map for the correct ID of the function, like this:

      +

      Example:

      +

      The buffer_load_async function can be called from any event, and since it's asynchronous the callback can be almost instantaneous or could take several seconds. Calling the function is simple and would look something like this:

      +

      loadid = buffer_load_async(buff, "Player_Save.sav", 0, 16384);

      +

      The above code loads the contents of the file "Player_Save.sav" to the given buffer, storing the ID of the function call in the variable loadid. When the load is complete, the asynchronous Save / Load event will be triggered and you can parse the async_load map for the correct ID of the function, like this:

      if ds_map_find_value(async_load, "id") == loadid
      {
          if ds_map_find_value(async_load, "status") == false
      @@ -65,7 +71,7 @@

      Extended Example:

              show_debug_message("Load failed!");
          }
      }

      -

      The above code will first check the ID of the DS map that has been created, then check the status of the callback, posting a debug message if there has been any issues.

      +

      The above code will first check the ID of the DS map that has been created, then check the status of the callback, posting a debug message if there have been any issues.

       

       

      -
      © Copyright YoYo Games Ltd. 2022 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved
      -

      buffer_load_ext

      -

      This function will load the buffer data that was previously saved using the buffer_save() functions into an existing buffer. You give the ID of the previously created buffer to load into, then the saved buffer file to load, and finally the offset from the start of the buffer (in bytes) that you wish to load the data to.

      -

      Please read the buffer_load() page for platform-specific notes.

      +

      buffer_load_ext

      +

      This function loads the buffer data that was previously saved using the buffer_save function and related functions into an existing buffer.

      +

      You pass the previously created buffer to load into, then the saved buffer file to load, and finally the offset from the start of the buffer (in bytes) that you wish to load the data to.

      +

      Please read the buffer_load page for platform-specific notes.

       

      Syntax:

      -

      buffer_load_ext(buffer, filename, offset);

      +

      buffer_load_ext(buffer, filename, offset);

      - + + - + - - - + + + + - + + - + - + + - +
      ArgumentTypeArgumentType Description
      bufferThe index of the buffer to load into.
      bufferBufferThe buffer to load into.
      filenamefilenameString The name of the file to load from.
      offsetoffsetReal The offset within the buffer to load to (in bytes).

       

      Returns:

      -

      +

      N/A

       

      Example:

      -

      var pos = buffer_seek(player_buffer, buffer_seek_end, 0);
      - buffer_load(player_buffer, "Data_Save.sav", pos);

      -

      The above code will first get the position of the end of the buffer indexed in the variable "player_buffer" and then loads the data from the given into that position (note that this example will only work with "grow" or "wrap" buffer types).

      -

       

      +

      var _pos = buffer_seek(player_buffer, buffer_seek_end, 0);
      + buffer_load_ext(player_buffer, "Data_Save.sav", _pos); +

      +

      The above code firsts get the position of the end of the buffer stored in the variable player_buffer and then loads the data from the given file into that position (note that this example will only work with "grow" or "wrap" buffer types).

       

       

      -
      © Copyright YoYo Games Ltd. 2022 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved
      -

      buffer_load_partial

      -

      This function will load some of the buffer data that was previously saved using the buffer_save() functions into an existing buffer. You give the id of the previously created buffer to load into, then the saved buffer file to load, and then the offset from the start of the buffer (in bytes) that you wish to load the data from. The following arguments are for setting the length of the buffer data (in bytes) from the initial offset point that you wish to load and the offset point to load the data to in the buffer (again, in bytes).

      -

      Please read the buffer_load() page for platform-specific notes.

      +

      buffer_load_partial

      +

      This function loads some of the buffer data that was previously saved using the buffer_save functions into an existing buffer.

      +

      You provide the previously created buffer to load into, the path to the file to load and the offset from the start of the buffer (in bytes) that you wish to start writing the data. The following arguments are for setting the length of the buffer data (in bytes) from the initial offset point that you wish to load and the offset point to load the data to in the buffer (again, in bytes).

      +

      Please read the buffer_load page for platform-specific notes.

       

      Syntax:

      -

      buffer_load_partial(buffer, filename, offset, src_len, dest_offset);

      +

      buffer_load_partial(buffer, filename, offset, src_len, dest_offset);

      - + + - + - - - + + + + - + + - + - + + - + - + + - + - + + - +
      ArgumentTypeArgumentType Description
      bufferThe index of the buffer to load into (destination).
      bufferBufferThe buffer to load into (destination).
      filenamefilenameString The name of the file to load from (source).
      offsetoffsetReal The offset within the destination buffer to load to (in bytes).
      src_lensrc_lenReal The length of the part of the source buffer to load (in bytes).
      dest_offsetdest_offsetReal The offset where to start putting the partial data in the destination buffer (in bytes).

       

      @@ -57,8 +64,9 @@

      Example:

      var _file = "save.dat";
      var _so = 6;
      var _sl = 5;
      - var _do= 0;
      - buffer_load_partial(buff, _file, _so, _sl, _do);

      + var _do = 0;
      + buffer_load_partial(buff, _file, _so, _sl, _do); +

      The above code will create a new "grow" buffer and then load in a part of the data saved in the file "save.dat" to it.

       

       

      @@ -69,7 +77,7 @@

      Example:

      -
      © Copyright YoYo Games Ltd. 2022 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved
      -

      buffer_md5

      -

      In cryptography, MD5 (Message-Digest algorithm 5) is a widely used cryptographic hashing function with a 128-bit hash value and has been employed in a wide variety of security applications. It is also commonly used to check the integrity of data. This function will take the input data from a given buffer (or part of the buffer) and return the 32-character hexadecimal MD5 hash that is unique to that data. In this way you can generate a secure key which can be stored and used to check the integrity of the information being sent to (or received from) an external server (for example). When applying this to buffers using this function you must specify the buffer id of the buffer to use, then an offset value (in bytes) for where to begin, and then a size (again in bytes) for the region to be hashed.

      +

      buffer_md5

      +

      This function takes the input data from a given buffer (or part of the buffer) and return the 32-character hexadecimal MD5 hash that is unique to that data. In this way you can generate a secure key which can be stored and used to check the integrity of the information being sent to (or received from) an external server (for example).

      +

      In cryptography, MD5 (Message-Digest algorithm 5) is a widely used cryptographic hashing function with a 128-bit hash value which has been employed in a wide variety of security applications. It is also commonly used to check the integrity of data.

      +

      When applying this to buffers using this function you must specify the buffer to use, then an offset value (in bytes) for where to begin, and then a size (again in bytes) for the region to be hashed.

      MD5 is not completely secure and can be broken. See this page for more info.

       

      Syntax:

      -

      buffer_md5(buffer, offset, size);

      +

      buffer_md5(buffer, offset, size);

      @@ -30,29 +32,28 @@

      Syntax:

      - - + + - + - +
      bufferBuffer IDThe index of the buffer to use.BufferThe buffer to use.
      offsetRealReal The data offset value.
      sizeRealReal The size of the buffer.

       

      Returns:

      -

      String

      +

      String

       

      Example:

      check_string = buffer_md5(buff, 0, buffer_get_size(buff));

      -

      The above code will create an md5 hash for the full data stored in the buffer indexed by the variable "buff", and store the returned hash in the variable "check_string".

      -

       

      +

      The above code will create an MD5 hash for the full data stored in the buffer stored in the variable buff, and store the returned hash in the variable check_string.

       

       

      -

      buffer_resize

      -

      With this function you can resize a given buffer to be the size (in bytes) that you specify.

      +

      buffer_resize

      +

      This function resizes a given buffer to the size (in bytes) that you specify.

       

      Syntax:

      -

      buffer_resize(buffer, newsize);

      +

      buffer_resize(buffer, newsize);

      - + + - + - - - + + + + - + + - +
      ArgumentTypeArgumentType Description
      bufferThe index of the buffer to change the size of.
      bufferBufferThe buffer to change the size of.
      newsizenewsizeReal The new size of the buffer (in bytes).

       

      Returns:

      -

      +

      N/A

       

      Example:

      if (buffer_get_size(buff) < 16384)
      {
          buffer_resize(buff, 16384);
      }

      -

      The above code will check the size of the buffer indexed in the variable "buff" and if it is less than the given value, the buffer is resized.

      -

       

      +

      The above code checks the size of the buffer stored in the variable buff. If it's less than the given value, the buffer is resized.

       

       

      -
      © Copyright YoYo Games Ltd. 2022 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved
      -

      buffer_save

      -

      With this function you can save the contents of a buffer to a file, ready to be read back into memory using the buffer_load() function.

      +

      buffer_save

      +

      This function saves the contents of a buffer to a file, ready to be read back into memory using the buffer_load function.

       On HTML5 the contents of the buffer will be saved as base64 encoded strings when using this function.

       

      Syntax:

      -

      buffer_save(buffer, filename);

      +

      buffer_save(buffer, filename);

      @@ -29,12 +29,12 @@

      Syntax:

      - - + + - + @@ -45,8 +45,7 @@

      Returns:

       

      Example:

      buffer_save(buff, "Player_Save.sav");

      -

      Saves the current contents of the buffer with the id stored in the variable "buff" to a file.

      -

       

      +

      The above code saves the current contents of the buffer stored in the variable buff to a file.

       

       

      bufferBuffer IDThe index of the buffer to save.BufferThe buffer to save.
      filenameStringString The name of the file to save as.
      @@ -36,34 +41,34 @@

      Syntax:

      - - + + - + - + - +
      bufferBuffer IDThe index of the buffer to save.BufferThe buffer to save.
      filenameStringString The name of the file to save as.
      offsetRealReal The offset within the buffer to save from (in bytes).
      sizeRealReal The size of the buffer area to save (in bytes).

       

      Returns:

      -

      Async Request ID

      +

      Async Request ID

       

      -

      Extended Example:

      -

      The buffer_save_async() function can be called from any event, and since it is asynchronous the callback can be almost instantaneous or could take several seconds. Calling the function is simple and would look something like this:

      +

      Example:

      +

      The buffer_save_async function can be called from any event, and since it is asynchronous the callback can be almost instantaneous or could take several seconds. Calling the function is simple and would look something like this:

      saveid = buffer_save_async(buff, "Player_Save.sav", 0, 16384);

      -

      The above code saves the contents of the buffer "buff" to the given save file, storing the ID of the function call in the variable "saveid". When the save is complete, the asynchronous Save/Load event will be triggered and you can parse the async_load map for the correct ID of the function, like this:

      +

      The above code saves the contents of the buffer buff to the given save file, storing the ID of the function call in a variable saveid. When the save is complete, the asynchronous Save / Load event will be triggered and you can parse the async_load map for the correct ID of the function, like this:

      if ds_map_find_value(async_load, "id") == saveid
      {
          if ds_map_find_value(async_load, "status") == false
      @@ -71,8 +76,7 @@

      Extended Example:

              show_debug_message("Save failed!");
          }
      }

      -

      The above code will first check the id of the DS map that has been created, then check the status of the callback, posting a debug message if there has been any issues.

      -

       

      +

      The above code will first check the ID of the DS map that has been created, then check the status of the callback, posting a debug message if there have been any issues.

       

       

      -
      © Copyright YoYo Games Ltd. 2021 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved
      -

      buffer_set_surface

      -

      With this function you can write information from a buffer to a given surface.

      +

      buffer_set_surface

      +

      This function writes information from a buffer to a given surface.

      Both the buffer and the surface must have been created previously, and the buffer's size must be equal to or greater than the surface's size. If the buffer is smaller than the surface, the function will silently fail.

      The surface you are writing to must have the same format as the surface that was written into the buffer. Keep in mind that it can't be guaranteed that a surface saved into a buffer on one platform will be read correctly on another platform, even if both surfaces use the same format.

      You can provide an offset into the buffer to start reading from. Reading will always start at the beginning of the buffer plus the offset value and not at the current seek position plus the offset value.

       

      Syntax:

      -

      buffer_set_surface(buffer, surface, offset);

      +

      buffer_set_surface(buffer, surface, offset);

      @@ -31,13 +31,13 @@

      Syntax:

      - - + + - - + + @@ -51,9 +51,8 @@

      Returns:

      N/A

       

      Example:

      -

      buffer_set_surface(buff, application_surface, 0);

      -

      The above code will copy all the data stored in the buffer indexed in the variable "buff" to the application surface with no offset.

      -

       

      +

      buffer_set_surface(buff, application_surface, 0);

      +

      The above code will copy all the data stored in the buffer indexed in the variable buff to the application surface with no offset.

       

       

      bufferBuffer IDThe index of the buffer to use.BufferThe buffer to use.
      surfaceSurface IDThe index of the surface to use.SurfaceThe surface to use.
      offset
      @@ -29,8 +29,8 @@

      Syntax:

      - - + + @@ -50,7 +50,7 @@

      Example:


      buffer_set_used_size(_bufferAddress, 4);

      -

      The above functions would be called in an extension to write some data to a GameMaker buffer (through its memory address), and then set the number of bytes that were written to it so the engine can read that data.

      +

      The above functions would be called in an extension to write some data to a GameMaker buffer (through its memory address), and then set the number of bytes that were written to it so the engine can read that data.

       

       

      bufferBuffer IDThe index of the buffer to use.BufferThe buffer to use.
      size
      @@ -30,29 +32,28 @@

      Syntax:

      - - + + - + - +
      bufferBuffer IDThe index of the buffer to use.BufferThe buffer to use.
      offsetRealReal The data offset value.
      sizeRealReal The size of the buffer.

       

      Returns:

      -

      String

      +

      String

       

      Example:

      check_string = buffer_sha1(buff, 0, buffer_get_size(buff));

      -

      The above code will create a sha1 hash for the full data stored in the buffer indexed by the variable "buff", and store the returned hash in the variable "check_string".

      -

       

      +

      The above code creates an SHA-1 hash for the full data stored in the buffer stored in the variable buff, and stores the returned hash in the variable check_string.

       

       

      view_surface_id

      -

      With this variable you can set the contents of a given view port to draw to a surface, or get the current surface id if one has been assigned to a view port. When working with surfaces, it is often required that you capture the whole visible region of the screen to the surface, and so you would assign it to a view port using this variable. This means that everything that is shown in the chosen view will now be drawn to the assigned surface. The view will now not be drawn to the screen, meaning that you will need to either:

      +

      With this variable you can set the contents of a given view port to draw to a surface, or get a reference to the current surface if one has been assigned to a view port. When working with surfaces, it is often required that you capture the whole visible region of the screen to the surface, and so you would assign it to a view port using this variable. This means that everything that is shown in the chosen view will now be drawn to the assigned surface. The view will now not be drawn to the screen, meaning that you will need to either:

      • Enable a new view and draw the surface only in that view (using view_current to check which view is being drawn)
      • Draw the surface in the Draw GUI or Post Draw event of an instance, since these events are independent of views.
      -

      You can also read this variable to get the index of the surface that has been assigned to the chosen view or it will return -1 if no surface has been assigned, and generally the surface used for this function should be the size of the view camera itself (not the view port). The extended example below shows a basic setup for capturing a view and drawing it in the Draw GUI event, and for more information on surfaces see the section Surfaces.

      +

      You can also read this variable to get the surface that has been assigned to the chosen view or it will return -1 if no surface has been assigned, and generally the surface used for this function should be the size of the view camera itself (not the view port). The extended example below shows a basic setup for capturing a view and drawing it in the Draw GUI event, and for more information on surfaces see the section Surfaces.

      Note that you can also set a view port to a surface using the function view_set_surface_id().

       

      @@ -28,7 +28,7 @@

      Syntax:

      view_surface_id[0...7];

       

      Returns:

      -

      Surface ID or -1 (if no surface has been assigned)

      +

      Surface or -1 (if no surface has been assigned)

       

      Extended Example:

      In this extended example, we will create a surface and assign it to view port[0] so it captures the camera view assigned to that port, then draw that to the screen in the Draw GUI event. To start with we need to initialise our surface variable in the Create Event of a controller instance:

      @@ -53,7 +53,7 @@

      Extended Example:

      -
      © Copyright YoYo Games Ltd. 2022 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2023 All Rights Reserved

      gif_add_surface

      -

      With this function you can save a frame to a GIF file from a surface. You supply the GIF file ID (as returned by the function gif_open()) and a surface ID (as returned by the function surface_create()), as well as a delay time between frames. The delay time is calculated in 1/100ths of a second, but note that once the GIF has been created, if you use it for promotional purposes for example, different browsers may interpret the frame delay slightly differently - see here for more details. You may (optionally) supply X and Y offset values for the surface being used to add to the GIF, in which case the part drawn to the GIF will begin from the offset and not the default (0,0) position, permitting you to select only a section of the surface to add. You can also supply a quantization value, which is an integer between 0 and 3, where 0 is full quantization and 3 is zero quantization (lower values will have a subsequent degradation in quality, but create a smaller GIF). Note that there isn't much difference between the default quality of 2, and the highest of 3, and using 3 will significantly slow down the creation of the GIF so care should be taken when using the maximum value.

      +

      This function saves a frame to a GIF file from a surface.

      +

      You supply the GIF file ID (as returned by the function gif_open) and a surface (as returned by the function surface_create), as well as a delay time between frames. The delay time is calculated in 1/100ths of a second, but note that once the GIF has been created, if you use it for promotional purposes for example, different browsers may interpret the frame delay slightly differently - see here for more details. You may (optionally) supply X and Y offset values for the surface being used to add to the GIF, in which case the part drawn to the GIF will begin from the offset and not the default (0, 0) position, permitting you to select only a section of the surface to add. You can also supply a quantization value, which is an integer between 0 and 3, where 0 is full quantization and 3 is zero quantization (lower values will have a subsequent degradation in quality, but create a smaller GIF). Note that there isn't much difference between the default quality of 2, and the highest of 3, and using 3 will significantly slow down the creation of the GIF so care should be taken when using the maximum value.

      Note that there are no built-in limits on number of frames or on the size of those frames in your GIF, but if you use too much memory then the function will fail and return -1, otherwise it will return 0.

       

      @@ -31,12 +32,12 @@

      Syntax:

      gif_index GIF ID - The ID of gif to add the surface data to + The ID of the GIF to add the surface data to surface - Surface ID - The ID of the surface to use as the added frame + Surface + The surface to use as the added frame delay_time @@ -86,7 +87,6 @@

      Example:

      The above code will create a GIF image file with 30 frames taken from the application surface and then save it.

       

       

      -

       

      ds_map_secure_save_buffer

      -

      This function will save a previously created DS map to a buffer. You supply the DS map ID value (as returned by the function ds_map_create) and the ID of the buffer to write to (as returned by the function buffer_create). Note that if the DS map being saved contains an array, this will be converted into a DS list instead when saved.

      +

      This function will save a previously created DS map to a buffer. You supply the DS map ID value (as returned by the function ds_map_create) and the buffer to write to (as returned by the function buffer_create). Note that if the DS map being saved contains an array, this will be converted into a DS list instead when saved.

       This function is not supported on HTML5.

      Usage Notes

        @@ -34,12 +34,12 @@

        Syntax:

        id - DS Map ID + DS Map The DS map ID value. buffer - Buffer ID + Buffer The buffer to save to. @@ -66,7 +66,7 @@

        Example:

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        vertex_argb

        -

        This function will set the ARGB values for the vertex currently being defined for the custom primitive. You supply the buffer to write the data into as well as the red, green, blue and alpha values that you wish to use as a single 32-bit unsigned integer - alpha sample in the highest 8 bits, followed by the red sample, green sample and finally the blue sample in the lowest 8 bits. You can use hex notation ($AARRGGBB) a real number or use any of the make_colour_*() functions to define the colour value.

        +

        vertex_argb

        +

        This function sets the ARGB values for the vertex currently being defined for the custom primitive.

        +

        You supply the vertex buffer to write the data into as well as the red, green, blue and alpha values that you wish to use as a single 32-bit unsigned integer - alpha sample in the highest 8 bits, followed by the red sample, green sample and finally the blue sample in the lowest 8 bits. You can use hex notation ($AARRGGBB), a real number or use any of the make_colour_* functions to define the colour value.

         

        Syntax:

        -

        vertex_argb(buffer, argb);

        +

        vertex_argb(buffer, argb);

        @@ -28,12 +29,12 @@

        Syntax:

        - - + + - + @@ -43,9 +44,8 @@

        Returns:

        N/A

         

        Example:

        -

        vertex_argb(buff, $FFFFFFFF);

        -

        The above code will set the ARGB values of the vertex being defined to white.

        -

         

        +

        vertex_argb(buff, $FFFFFFFF);

        +

        The above code sets the ARGB values of the vertex being defined to white.

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved

        vertex_begin

        -

        This function starts the definition of a custom primitive. You assign a vertex buffer to write the primitive to, and the vertex format to use (previously defined using the vertex format functions). You would then define the necessary points for each vertex of the primitive before calling vertex_end to finalise the primitive creation.

        +

        This function starts the definition of a custom primitive.

        +

        You assign a vertex buffer to write the primitive to, and the vertex format to use (previously defined using the vertex format functions). You would then define the necessary points for each vertex of the primitive before calling vertex_end to finalise the primitive creation.

         

        Syntax:

        vertex_begin(buffer, format);

        @@ -28,12 +29,12 @@

        Syntax:

        - + - + @@ -50,7 +51,7 @@

        Example:

        v_format = vertex_format_end();
        v_buff = vertex_create_buffer();
        vertex_begin(v_buff, v_format);

        -

        The above code will define a new vertex format, create a new buffer and start the definition process of a new primitive.

        +

        The above code defines a new vertex format, creates a new buffer and start the definition process of a new primitive.

         

         

        bufferVertex Buffer IDThe buffer to write the information to.Vertex BufferThe vertex buffer to write the information to.
        argbColourColour The ARGB value to set.
        bufferVertex Buffer IDVertex Buffer The vertex buffer to be written to.
        formatVertex Format IDVertex Format The vertex format to use.
        @@ -28,17 +29,17 @@

        Syntax:

        - - + + - + - + @@ -48,9 +49,8 @@

        Returns:

        N/A

         

        Example:

        -

        vertex_colour(b, c_white, 1);

        -

        The above code will set the vertex being defined to be white with an alpha value of 1.

        -

         

        +

        vertex_colour(b, c_white, 1);

        +

        The above code will set the colour of the current vertex being defined to white with an alpha value of 1.

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        vertex_create_buffer

        -

        With this function you can create a new vertex buffer. This is a special grow buffer created by GameMaker which is pre-formatted for use when building primitives (for use with shaders, for example). The function will return an index for the buffer which should then be used in all further calls to it.

        -

        When using a vertex buffer created with this function you simply call vertex_begin() to start assigning vertex data to it to start to define your custom primitive, which will then be held in the buffer ready for submission to the shader. The buffer can be re-used when necessary (unless you have used the vertex_freeze() function), with each call of vertex_begin() wiping the previous buffer data ready to accept the new data.

        +

        vertex_create_buffer

        +

        This function creates a new vertex buffer. This is a special grow buffer created by GameMaker which is pre-formatted for use when building primitives (for use with shaders, for example).

        +

        The function will return a handle to the buffer which should then be used in all further calls to it.

        +

        When using a vertex buffer created with this function you simply call vertex_begin to start assigning vertex data to it to start to define your custom primitive, which will then be held in the buffer ready for submission to the shader. The buffer can be re-used when necessary (unless you have used the vertex_freeze function), with each call to vertex_begin wiping the previous buffer data ready to accept the new data.

         

        Syntax:

        -

        vertex_create_buffer();

        +

        vertex_create_buffer();

         

        Returns:

        -

        Vertex Buffer ID

        +

        Vertex Buffer

         

        Example:

        -

        v_buff = vertex_create_buffer();

        -

        The above code will create a new a new vertex buffer and store its handle in the variable "v_buff".

        -

         

        +

        v_buff = vertex_create_buffer();

        +

        The above code creates a new vertex buffer and store its handle in the variable v_buff.

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        vertex_create_buffer_ext

        -

        As with the function vertex_create_buffer(), this function will create a new vertex buffer. This is a special grow buffer created by GameMaker which is pre-formatted for use when building primitives for use with shaders. You can specify an initial starting size for the buffer (in bytes) and it will return an index for the buffer which should then be used in all further calls to the buffer.

        +

        vertex_create_buffer_ext

        +

        This function creates a new vertex buffer and sets its initial size in bytes.

        +

        This is a special grow buffer created by GameMaker which is pre-formatted for use when building primitives for use with shaders. You can specify an initial starting size for the buffer (in bytes) and it will return an index for the buffer which should then be used in all further calls to the buffer.

         

        Syntax:

        -

        vertex_create_buffer_ext(size);

        +

        vertex_create_buffer_ext(size);

        bufferVertex Buffer IDThe buffer to write the information to.Vertex BufferThe vertex buffer to write the information to.
        colourColourColour The colour for this vertex (can be a constant or a hex value).
        alphaRealReal The alpha value for the vertex (from 0 to 1).
        - + + - + - + + - +
        ArgumentTypeArgumentType Description
        sizesizeReal The initial size of the buffer (in bytes).

         

        Returns:

        -

        Vertex Buffer ID

        +

        Vertex Buffer

         

        Example:

        -

        v_buff = vertex_create_buffer_ext(1024 * 1024);

        -

        The above code will create a new vertex buffer, initially 1MB in size, and store its handle in the variable "v_buff".

        -

         

        +

        v_buff = vertex_create_buffer_ext(1024 * 1024);

        +

        The above code creates a new vertex buffer, initially 1MB in size, and store it in the variable v_buff.

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved

        vertex_create_buffer_from_buffer

        -

        This function creates a new vertex buffer by copying the data from the buffer that is specified as the source.

        -

        The buffer created is a special grow buffer which is pre-formatted with the vertex format for building primitives for use with (for example) shaders. This function requires that you supply the pointer to a previously created regular buffer, and a vertex format that should be applied to the copied data.

        +

        This function creates a new vertex buffer by copying the data from the specified source buffer.

        +

        The data in the source buffer must be pre-formatted according to the vertex format for building primitives for use with (for example) shaders.

         

        Syntax:

        vertex_create_buffer_from_buffer(buffer, format);

        @@ -30,28 +30,28 @@

        Syntax:

        buffer - Buffer ID + Buffer The buffer to create the vertex buffer from. format - Primitive Type Constant - The primitive vertex format to use. + Vertex Format + The vertex format to use.

         

        Returns:

        -

        Vertex Buffer ID

        +

        Vertex Buffer

         

        Example:

        vertex_format_begin();
        vertex_format_add_position_3d();
        vertex_format_add_colour();
        vertex_format_add_texcoord();
        - var my_format = vertex_format_end();
        - v_buff = vertex_create_buffer_from_buffer(global.modelBuff, myFormat);

        -

        The above code will create a new vertex format then create a new vertex buffer from a previously created regular buffer, applying the custom vertex format to it.

        + var _my_format = vertex_format_end();
        + v_buff = vertex_create_buffer_from_buffer(global.modelBuff, _my_format);

        +

        The above code first creates a new vertex format and then creates a new vertex buffer from a previously created regular buffer, applying the custom vertex format to it.

         

         

        -

        surface_get_depth_disable

        -

        This function checks to see if the automatic depth buffer generation for surfaces is enabled. Normally all surfaces have depth buffers so if you draw 3D objects to them then it'll sort them properly by depth, however allocating depth buffers essentially doubles the size of surfaces, which could be an excessive and unnecessary overhead especially if your game is very memory intensive or predominantly 2D. In these cases you can check this using this function and disable the depth buffer for surfaces if required using the function surface_depth_disable().

        +

        surface_get_depth_disable

        +

        This function checks to see if the automatic depth buffer generation for surfaces is enabled.

        +

        Normally all surfaces have depth buffers so if you draw 3D objects to them then it'll sort them properly by depth, however allocating depth buffers essentially doubles the size of surfaces, which could be an excessive and unnecessary overhead especially if your game is very memory intensive or predominantly 2D. In these cases you can check this using this function and disable the depth buffer for surfaces if required using the function surface_depth_disable.

         

        Syntax:

        -

        surface_get_depth_disable();

        +

        surface_get_depth_disable();

         

        Returns:

        -

        +

        Boolean

         

        Example:

        if (!surface_exists(surf))
        {
        -     if surface_get_depth_disable() == false
        +     if surface_get_depth_disable() == false
            {
                surface_depth_disable(true);
            }
        @@ -36,7 +37,6 @@

        Example:

        The above code will check to see if the given surface exists, and if it does not, then it checks the current state of the surface depth buffer and if it is enabled, it will disable it instead, before finally creating the surface.

         

         

        -

         

        surface_get_format

        -

        This function returns the format of the given surface. All formats are listed here.

        +

        This function returns the format of the given surface. All formats are listed here.

         

        Syntax:

        -

        surface_get_format(surface_id);

        +

        surface_get_format(surface_id);

        @@ -29,17 +29,17 @@

        Syntax:

        - - + +
        surface_idSurface IDThe ID of the surface to get the format ofSurfaceThe surface to get the format of

         

        Returns:

        -

        Surface Format Type Constant

        +

        Surface Format Constant

         

        Example:

        -

        var _format = surface_get_format(my_surf);
        +

        var _format = surface_get_format(my_surf);
        if (_format == surface_rgba8unorm)
        {
            var _buffer = buffer_create(1, buffer_grow, 1);
        diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Surfaces/surface_get_height.htm b/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Surfaces/surface_get_height.htm index 993fab920..7d83e5ddc 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Surfaces/surface_get_height.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Surfaces/surface_get_height.htm @@ -4,7 +4,7 @@ surface_get_height - + @@ -15,32 +15,34 @@ -

        surface_get_height

        -

        This function simply returns the height, in pixels, of the indexed surface. It should be noted that if you call this to check the application_surface immediately after having changed its size using surface_resize() it will not return the new value as the change needs a step or two to be fully processed. After waiting a step it should return the new size correctly.

        -

        NOTE: When working with surfaces there is the possibility that they can cease to exist at any time due to them being stored in texture memory. You should ALWAYS check that a surface exists using surface_exists() before referencing them directly.

        +

        surface_get_height

        +

        This function simply returns the height, in pixels, of the given surface.

        +

        It should be noted that if you call this to check the application_surface immediately after having changed its size using surface_resize, it will not return the new value as the change needs a step or two to be fully processed. After waiting a step it should return the new size correctly.

        +

         

        Syntax:

        -

        surface_get_height(surface_id);

        +

        surface_get_height(surface_id);

        - + + - + - - - + + + +
        ArgumentTypeArgumentType Description
        surface_idThe ID of the surface to get the height of.
        surface_idSurfaceThe surface to get the height of.

         

        Returns:

        -

        +

        Real

         

        Example:

        -

        sh = surface_get_height(surf);

        -

        The above code will store the height of the surface indexed in the variable "surf" in the variable "sh".

        -

         

        +

        sh = surface_get_height(surf);

        +

        The above code will store the height of the surface indexed in the variable surf in the variable sh.

         

         

        -
        © Copyright YoYo Games Ltd. 2021 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        surface_get_target

        -

        With this function you can get the ID of the current surface being targeted for drawing to. If you created that surface using surface_create(), then this will be the positive integer which is the unique ID for that surface

        -

        If no custom surface is set, but the default application_surface is still enabled, then the function will typically return 0. However, if you have been manipulating the application_surface previously you might wish to check that the ID you got does not match the current value of the application_surface variable, in case this is no longer 0.

        -

        If no custom surface is set and the default application_surface has also been disabled, then the function will return -1.

        +

        surface_get_target

        +

        This function gets the surface that's currently set as the drawing target.

        +

        A couple of values can be returned: 

        +
          +
        • If you created that surface using surface_create, then that surface will be returned.
        • +
        • If no custom surface is set, but the default application surface is still enabled, then the function will return the application surface. However, if you've been manipulating the application surface previously you might wish to if this still matches the current value of the application_surface variable.
        • +
        • If no custom surface is set and the default application surface has also been disabled, then the function will return -1.
        • +

         

        Syntax:

        -

        surface_get_target();

        +

        surface_get_target();

         

        Returns:

        -

        Surface ID or -1 (if no target surface is set)

        +

        Surface or -1 (if no target surface is set)

         

        Example:

        -

        if surface_get_target() != -1
        +

        if surface_get_target() != -1
        {
            surface_reset_target();
        }
        draw_surface(surf, 0, 0);

        -

        The above code will check to see if the current render target is a surface or not, and if it is, it resets the target then draws a surface.

        -

         

        +

        The above code checks to see if the current render target is a surface or not, resetting the drawing target if it is. The surface stored in the variable surf is then drawn.

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        surface_get_target_ext

        -

        This function will retrieve the surface ID assigned to one of the 4 render targets available to surfaces. You supply the index of the render target to check, and the function will return -1 if no surface is assigned, or an integer value >= 0, representing the ID of the surface assigned (as returned by the function surface_create()).

        +

        surface_get_target_ext

        +

        This function retrieves the surface assigned to one of the 4 render targets available to surfaces.

        +

        You supply the index of the render target to check, and the function will return -1 if no surface is assigned, or an integer value >= 0, representing the surface assigned (as returned by the functions surface_create / surface_create_ext).

         

        Syntax:

        -

        surface_get_target_ext(index);

        +

        surface_get_target_ext(index);

        - + + - + - + + - +
        ArgumentTypeArgumentType Description
        indexindexReal The render target index to check (from 0 to 3).

         

        Returns:

        -

        Surface ID or -1 (if no target surface is set)

        +

        Surface or -1 (if no target surface is set)

         

        Example:

        -

        if surface_get_target_ext(0) == -1
        +

        if surface_get_target_ext(0) == -1
        {
            surface_set_target_ext(0, global.Surf);
        }

        -

        The above code will first check and see if the shader render target 0 has been set to a surface, and if not, then one is assigned.

        -

         

        +

        The above code first checks if the shader render target 0 has been set to a surface. If not, then one is assigned.

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        surface_get_width

        -

        This function simply returns the width, in pixels, of the indexed surface. It should be noted that if you call this to check the application_surface immediately after having changed its size using surface_resize() it will not return the new value as the change needs a step or two to be fully processed. After waiting a step it should return the new size correctly.

        -

        NOTE: When working with surfaces there is the possibility that they can cease to exist at any time due to them being stored in texture memory. You should ALWAYS check that a surface exists using surface_exists() before referencing them directly.

        +

        surface_get_width

        +

        This function simply returns the width, in pixels, of the given surface.

        +

        It should be noted that if you call this to check the application_surface immediately after having changed its size using surface_resize, it will not return the new value as the change needs a step or two to be fully processed. After waiting a step it should return the new size correctly.

        +

         

        Syntax:

        -

        surface_get_width(surface_id);

        +

        surface_get_width(surface_id);

        - + + - + - - - + + + +
        ArgumentTypeArgumentType Description
        surface_idThe ID of the surface to get the width of.
        surface_idSurfaceThe surface to get the width of.

         

        Returns:

        -

        +

        Real

         

        Example:

        -

        sw = surface_get_width(surf);

        -

        The above code will store the width of the surface indexed in the variable "surf" in the variable "sw".

        -

         

        +

        sw = surface_get_width(surf);

        +

        The above code will store the width of the surface indexed in the variable surf in the variable sw.

         

         

        -
        © Copyright YoYo Games Ltd. 2021 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        surface_getpixel

        -

        This function can be used to get the colour of a specific pixel from a surface, using the local coordinates of the surface where (0,0) is the top left corner. This function should not be used very often as it is extremely slow and may cause a pause in your game.

        +

        surface_getpixel

        +

        This function can be used to get the colour of a specific pixel from a surface, using the local coordinates of the surface where (0, 0) is the top left corner. This function should not be used very often as it is extremely slow and may cause a pause in your game.

        The data type returned by this function will depend on the format of the given surface:

        @@ -48,10 +48,10 @@

        surface_getpixel

        -

         When working with surfaces there is the possibility that they can cease to exist at any time due to them being stored in texture memory. You should ALWAYS check that a surface exists using surface_exists() before referencing them directly.

        +

         

        Syntax:

        -

        surface_getpixel(surface_id, x, y);

        +

        surface_getpixel(surface_id, x, y);

        @@ -61,18 +61,18 @@

        Syntax:

        - - + + - + - +
        surface_idSurface IDThe ID of the surface.SurfaceThe surface.
        x RealThe x position on the surface from which to get the pixel.The x position on the surface to get the pixel from.
        y RealThe y position on the surface from which to get the pixel.The y position on the surface to get the pixel from.
        @@ -81,9 +81,8 @@

        Returns:

        Colour or Array

         

        Example:

        -

        col = surface_getpixel(surf, 56, 78);

        -

        This will return the colour of the pixel at coordinates (56,78) of the surface indexed in the variable surf.

        -

         

        +

        col = surface_getpixel(surf, 56, 78);

        +

        This will return the colour of the pixel at coordinates (56, 78) of the surface stored in the variable surf.

         

         

        -
        © Copyright YoYo Games Ltd. 2021 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        surface_save

        -

        This function will save a surface to disc using the given filename. The surface must be saved as a *.png format file.

        +

        surface_save

        +

        This function will save a surface to disc using the given filename.

        +

        The surface must be saved as a *.png format file.

         

        Syntax:

        -

        surface_save(surface_id, fname);

        +

        surface_save(surface_id, fname);

        @@ -29,8 +30,8 @@

        Syntax:

        - - + + @@ -44,12 +45,11 @@

        Returns:

        N/A

         

        Example:

        -

        if keyboard_check_pressed(ord("S")
        +

        if keyboard_check_pressed(ord("S"))
        {
        -     surface_save(surf, "test.png");
        +     surface_save(surf, "test.png");
        }

        -

        The above code will check to see if the user presses the "S" key on the keyboard and if they do it will save the surface indexed in the variable "surf" to disc.

        -

         

        +

        The above code will check to see if the user presses the "S" key on the keyboard and if they do it will save the surface indexed in the variable surf to disc.

         

         

        surface_idSurface IDThe ID of the surface to set as the drawing target.SurfaceThe surface to set as the drawing target.
        fname
        @@ -29,8 +30,8 @@

        Syntax:

        - - + + @@ -64,12 +65,11 @@

        Returns:

        N/A

         

        Example:

        -

        if keyboard_check_pressed(ord("S")
        +

        if keyboard_check_pressed(ord("S"))
        {
        -     surface_save_part(surf, "test.png", 0, 0, 100, 100);
        +     surface_save_part(surf, "test.png", 0, 0, 100, 100);
        }

        -

        The above code will check to see if the user presses the "S" key on the keyboard and if they do it will save a part of the surface indexed in the variable "surf" to disc.

        -

         

        +

        The above code will check to see if the user presses the "S" key on the keyboard and if they do it will save a part of the surface indexed in the variable surf to disc.

         

         

        - - + +
        surface_idSurface IDThe ID of the surface to set as the drawing target.SurfaceThe surface to set as the drawing target.
        fname
        surface_idSurface IDThe ID of the surface to set as the drawing target.SurfaceThe surface to set as the drawing target.

         

        Returns:

        -

        Boolean Whether the render target was set successfully

        +

        Boolean Whether the render target was set successfully

         

        Example:

        -

        if view_current = 0
        +

        if view_current == 0
        {
            surface_set_target(surf);
            with (obj_Effect)
        @@ -73,7 +84,7 @@

        Example:

        {
            draw_surface(surf, 0, 0);
        }

        -

        The above code will check to see which view is currently being drawn, and if it is view[0] it sets the draw target to a surface and draws all instances of the object "obj_Effect" before resetting the draw target again. If the view is not view[0] the surface is drawn to the screen.

        +

        The above code checks to see which view is currently being drawn, and if it is view[0] it sets the draw target to a surface and draws all instances of the object obj_Effect before resetting the draw target again. If the view is not view[0] the surface is drawn to the screen.

         

         

        -

        program_directory

        -

        This will return the directory where the game executable is stored. However this may not always be useful, particularly as some devices run the exe from a *.zip file, so this would return the same no matter where the game is actually running from.

        -

        WARNING! This function may not work as you expect due to GameMaker being sandboxed! Please see the section on the File System for more information.

        -

        NOTE: If you disable the sandbox then you still will not be able to write to this directory to prevent any possible issue with deleting required game files.

        +

        program_directory

        +

        This function returns the directory where the game executable is stored. However, this may not always be useful, particularly as some devices run the exe from a *.zip file, so this would return the same no matter where the game is actually running from.

        +

         This function may not work as you expect due to GameMaker being sandboxed! Please see the section on The File System for more information.

        +

         GameMaker doesn't limit writing to this directory so whether this is possible depends on OS permissions. It is however discouraged that you write to program_directory, as it is possible to damage the game installation this way.

         

        Syntax:

        -

        program_directory

        +

        program_directory

         

        Returns:

        -

        +

        String

         

        Example:

        -

        dir = program_directory;

        +

        dir = program_directory;

        This will store the directory where the executable is stored in a variable.

         

         

        -

         

        -

        temp_directory

        -

        This can be used to return the temporary directory created for your game each time it is run (the root does not contain the final "\"). This directory will hold files and can be accessed while the game is running, but it will be removed (along - with all files that it contains) when the game is closed.

        -

        WARNING! This function may not work as you expect due to GameMaker being sandboxed! Please see the section on the File System for more information.

        +

        temp_directory

        +

        This can be used to return the temporary directory created for your game each time it is run (the root does not contain the final "\"). This directory will hold files and can be accessed while the game is running, but it will be removed (along with all files that it contains) when the game is closed.

        +

         

        Syntax:

        -

        temp_directory

        +

        temp_directory

         

        Returns:

        -

        +

        String

         

        Example:

        -

        ini_open(temp_directory + "\temp_ini.ini");

        -

        This will open an ini file in the temporary directory of the game (creating it if it does not already exist).

        -

         

        +

        ini_open(temp_directory + "\temp_ini.ini");

        +

        This will open an INI file in the temporary directory of the game (creating it if it does not already exist).

         

         

        -
        © Copyright YoYo Games Ltd. 2021 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        working_directory

        -

        Working_directory can actually return two different values depending on what you are using it for.

        -

        If you are writing a file to disk, working_directory points to the area of local storage that is reserved for your game on the target device (in Windows this is "%LOCALAPPDATA%/gamedir/" where the "gamedir" is the directory with the name of your game).

        -

        However, when reading from disk, working_directory can be either the local storage (game_save_idor the area where the Included Files are stored.

        -

        NOTE The working_directory variable will return the path including the final backslash.

        -

        For example, if you have a default *.txt file included with your game and read it into memory using working_directory, then that file will be taken from the area where the Included Files are stored. If you then choose to write that information to a text file using working_directory, this will write the file to the target platform's local storage, where it will be read from the next time unless you instruct GameMaker to delete the file, in which case working_directory will once more point to the area where the Included Files are stored.

        +

        working_directory

        +

        working_directory can actually return two different values depending on what you are using it for: 

        +
          +
        • If you are writing a file to disk, working_directory points to the area of local storage that is reserved for your game on the target device (in Windows this is "%LOCALAPPDATA%/gamedir/" where the "gamedir" is the directory with the name of your game).
        • +
        • However, when reading from disk, working_directory can be either the local storage (game_save_idor the area where the Included Files are stored.
        • +
        +

         The working_directory variable will return the path including the final backslash.

        +

        For example, if you have a default *.txt file included with your game and read it into memory using working_directory, then that file will be taken from the area where the Included Files are stored. If you then choose to write that information to a text file using working_directory, this will write the file to the target platform's local storage, where it will be read from the next time unless you instruct GameMaker to delete the file, in which case working_directory will once more point to the area where the Included Files are stored.

        It is worth noting that in general you do not need to use this and simply specify the file name itself (plus any additional path information), which is sufficient. For example, this:

        file_text_open_read(working_directory + "my_file.txt");

        would be better done as this:

        file_text_open_read("my_file.txt");

        -

        WARNING This function may not work as you expect due to GameMaker being sandboxed! Please see the section on the File System for more information.

        +

         

        Syntax:

        -

        working_directory

        +

        working_directory

         

        Returns:

        -

        String

        +

        String

         

        Example:

        ini_open(working_directory + "temp_ini.ini");

        -

        This will open an ini file from the working directory of the game (creating it if it does not already exist). This could be the local storage, or the area where the included files are depending on whether the file being looked for exists in either place.

        -

         

        +

        This will open an INI file from the working directory of the game (creating it if it does not already exist). This could be the local storage, or the area where the included files are depending on whether the file being looked for exists in either place.

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved

        file_delete

        This function will delete the specified file from the system. It should be noted that this function will only delete those files that GameMaker is able to create and parse: ini files, text files and binary files, or those files made to store game created resources like sprites or surfaces. However, it will not delete any other file. The function will also return true if the file has successfully been removed, or false in any other circumstances.

        -

        WARNING! This function may not work as you expect due to GameMaker being sandboxed! Please see the section on File System Limits for more information.

        +

         

        Syntax:

        file_delete(fname);

        - + + - + - + + - +
        ArgumentTypeArgumentType Description
        fnamefnameString The name of the file to delete.

         

        Returns:

        -

        +

        Boolean

         

        Example:

        if file_exists("level.txt")
        @@ -52,7 +54,7 @@

        Example:

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved

        file_find_next

        -

        This function returns the name of the next file that satisfies the previously given mask and the attributes (defined by file_find_first()). If no such file exists, the empty string is returned.

        -

        WARNING This function may not work as you expect due to GameMaker being sandboxed! Please see the section on the File System for more information.

        -

        NOTE This function works on all the C++ target platforms (Windows, Mac, iOS, Android), BUT the filter flags only work on Windows.

        +

        This function returns the name of the next file that satisfies the previously given mask and the attributes (defined by file_find_first()). If no such file exists, the empty string is returned.

        +
        +

         This function works on all the C++ target platforms (Windows, Mac, iOS, Android), BUT the filter flags only work on Windows.

         

        Syntax:

        file_find_next();

         

        Returns:

        -

        +

        String

         

        Example:

        if directory_exists("\User Content")
        @@ -58,7 +58,7 @@

        Example:

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved

        file_rename

        -

        This function will rename the specified file with the specified name. The function will return true if the file has successfully been renamed, or false in any other circumstances.

        -

        WARNING! This function may not work as you expect due to GameMaker being sandboxed! Please see the section on the File System for more information.

        +

        This function will rename the specified file with the specified name. The function will return true if the file has successfully been renamed, or false in any other circumstances.

        +

         

        Syntax:

        file_rename(oldname, newname);

        - + + - + - + + - + - + + - +
        ArgumentTypeArgumentType Description
        oldnameoldnameString The name of the file to change.
        newnamenewnameString The new name to give the file.

         

        Returns:

        -

        +

        Boolean

         

        Example:

        if file_exists("level1.txt")
        @@ -56,7 +59,7 @@

        Example:

        Next: file_copy
        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved

        ini_open

        -

        This opens an ini_file for reading and/writing. If the ini_file does not exist at the location you are checking, GameMaker may create one, but only if you write data to it. If you have only read information from the ini file, then the - default values for the read function will be returned, but the ini file will not actually be created.

        -

        Please note that you can only have one ini file open at any one time and remember to use ini_close() once you're finished reading/writing from the .ini file as the information is not actually stored to - disk until then (it is also stored in memory until the file is closed).

        -

        WARNING! This function may not work as you expect due to GameMaker being sandboxed! Please see the section on the File System for more information.

        +

        This opens an ini_file for reading and/writing. If the ini_file does not exist at the location you are checking, GameMaker may create one, but only if you write data to it. If you have only read information from the ini file, then the default values for the read function will be returned, but the ini file will not actually be created.

        +

        Please note that you can only have one ini file open at any one time and remember to use ini_close() once you're finished reading/writing from the .ini file as the information is not actually stored to disk until then (it is also stored in memory until the file is closed).

        +

         

        Syntax:

        ini_open(name);

        - + + - + - + + - +
        ArgumentTypeArgumentType Description
        namenameString The filename for the .ini file.

         

        Returns:

        -

        +

        N/A

         

        Example:

        -

        ini_open("Settings/savedata.ini");
        score = ini_read_real("save1", "score", 0);
        ini_close(); -

        -

        This will open 'savedata.ini' and read the score value under the section "save1" with the key "score" in it, then close the .ini again. Should there be no value under "save1", "score" or there is no "savedata.ini" - file present, score will be set to 0 (the default value). Note that the ini file has been placed in the sub-directory "Settings", which is the folder that holds the ini file in the Asset Browser included files.

        +

        ini_open("Settings/savedata.ini");
        + score = ini_read_real("save1", "score", 0);
        + ini_close();

        +

        This will open 'savedata.ini' and read the score value under the section "save1" with the key "score" in it, then close the .ini again. Should there be no value under "save1", "score" or there is no "savedata.ini" file present, score will be set to 0 (the default value). Note that the ini file has been placed in the sub-directory "Settings", which is the folder that holds the ini file in the Asset Browser included files.

         

         

         

        @@ -54,7 +54,7 @@

        Example:

        Next: ini_close
        -
        © Copyright YoYo Games Ltd. 2021 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved

        file_text_open_from_string

        This function will create a text file from a string and open it for reading, returning the file "handle" that should be used in all further file function calls to read from this file. Note that this file is temporary and read only, and as such it will be removed from memory the moment it is closed.

        -

        NOTE: You can only have a maximum of 32 files open at any one time. You should also always close files when finished as this writes the information and frees the memory associated with the file.

        -

        WARNING! This function may not work as you expect due to GameMaker being sandboxed! Please see the section on the File System for more information.

        +

         You can only have a maximum of 32 files open at any one time. You should also always close files when finished as this writes the information and frees the memory associated with the file.

        +

         

        Syntax:

        file_text_open_from_string(string);

        - + + - + - + + - +
        ArgumentTypeArgumentType Description
        stringstringString The string to create the file from.

         

        Returns:

        -

        File ID or -1

        +

        Text File ID or -1

         

        Example:

        file = file_text_open_from_string(reset_str);

        @@ -50,7 +53,7 @@

        Example:

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        - - \ No newline at end of file + + \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/File_Handling/Text_Files/file_text_open_read.htm b/Manual/contents/GameMaker_Language/GML_Reference/File_Handling/Text_Files/file_text_open_read.htm index 2bbc82fd1..b75d97c8d 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/File_Handling/Text_Files/file_text_open_read.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/File_Handling/Text_Files/file_text_open_read.htm @@ -4,7 +4,7 @@ file_text_open_read - + @@ -17,26 +17,28 @@

        file_text_open_read

        This function opens the text file with the indicated filename for reading only, returning the unique id of the file that which should be stored in a variable as it will be used for all further actions to do with that file. If the file does not exists then the function will return the value -1.

        -

        NOTE: You can only have a maximum of 32 files open at any one time. You should also always close files when finished as this writes the information and frees the memory associated with the file.

        -

        WARNING! This function may not work as you expect due to GameMaker being sandboxed! Please see the section on the File System for more information.

        +

         You can only have a maximum of 32 files open at any one time. You should also always close files when finished as this writes the information and frees the memory associated with the file.

        +

         

        Syntax:

        file_text_open_read(fname);

        - + + - + - + + - +
        ArgumentTypeArgumentType Description
        fnamefnameString The name of the file to read from.

         

        Returns:

        -

        Text File ID or -1

        +

        Text File ID or -1

         

        Example:

        file = file_text_open_read(working_directory + "level.txt");

        @@ -51,7 +53,7 @@

        Example:

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        game_set_speed

        +

        game_set_speed

        This function can be used to set the game speed. You can set this in one of two ways - as either game frames per second (FPS) or as microseconds per game frame (MPF) - using one of the following two constants:

        @@ -32,13 +32,14 @@

        game_set_speed

        -

        So, for example, a game speed of 30 frames per second would be 33333 microseconds per game game frame, which would then be expressed by this function as either:

        -

        game_set_speed(30, gamespeed_fps);

        +

        So, for example, a game speed of 30 frames per second would be 33333 microseconds per game frame, which would then be expressed by this function as either:

        +

        game_set_speed(30, gamespeed_fps);

        or:

        -

        game_set_speed(33333, gamespeed_microseconds);

        +

        game_set_speed(33333, gamespeed_microseconds);

        +

         On Android, if the device's refresh rate cannot be set to the requested game speed, GameMaker will set it to an integer multiple of the requested game speed. If no multiple is available the highest refresh rate available is used and frames are skipped.

         

        Syntax:

        -

        game_set_speed(speed, type);

        +

        game_set_speed(speed, type);

        @@ -48,12 +49,12 @@

        Syntax:

        - + - + @@ -65,24 +66,23 @@

        Returns:

        Example:

        if os_browser == browser_not_a_browser
        {
        -     game_set_speed(60, gamespeed_fps);
        +     game_set_speed(60, gamespeed_fps);
        }
        else
        {
        -     game_set_speed(30, gamespeed_fps);
        +     game_set_speed(30, gamespeed_fps);
        }

        The above code checks to see if the game is running in a browser and sets the game speed accordingly as an FPS value.

         

         

        -

         

        -

        sprite_flush

        -

        With this function you can remove the texture page for the given sprite from texture memory (VRAM). The texture will stay in RAM after being flushed.

        -

        You supply the sprite index (as defined when creating the sprite resource) and the texture page it is assigned to will be removed from texture memory. Note that if the texture page is used elsewhere in the room (by another instance sprite or a background, etc...) you may get a minor performance hit as the page is immediately reloaded, so care should be taken when using this function. Note that the function will return -1 if flush is not supported for the chosen resource, or it will return 0 if all worked correctly.

        +

        sprite_flush

        +

        This function removes the texture page for the given sprite from texture memory (VRAM). The texture will stay in RAM after being flushed.

        +

        You supply the sprite (as defined when creating the sprite) and the texture page it is assigned to will be removed from texture memory. The function will return -1 if flush is not supported for the chosen asset, or it will return 0 if all worked correctly.

        +

         If the texture page is used elsewhere in the room (by another instance sprite, a background, etc.) you may get a minor performance hit as the page is immediately reloaded, so care should be taken when using this function.

         

        Syntax:

        -

        sprite_flush(ind)

        +

        sprite_flush(ind)

        speedRealReal The new game speed (as either FPS or MPF).
        typeGame Speed ConstantGame Speed Constant The type of method used to set the game speed (see the constants above).
        @@ -29,19 +30,18 @@

        Syntax:

        - - + +
        indSprite AssetThe index (resource name) of the sprite asset to flushSprite AssetThe sprite asset to flush

         

        Returns:

        -

        Real (-1 or 0)

        +

        Real (-1 or 0)

         

        Example:

        -

        sprite_flush(spr_Player_Aura);

        -

        The above code flushes the sprite "spr_Player_Aura" from memory.

        -

         

        +

        sprite_flush(spr_Player_Aura);

        +

        The above code flushes the sprite spr_Player_Aura from memory.

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        sprite_flush_multi

        -

        With this function you can remove the any number of texture pages for the given sprites from texture memory. You supply the sprite indices as an array and the texture pages they are assigned to will be removed from texture memory. Note that if one of - the texture pages is used elsewhere in the room (by another instance sprite or a background, etc...) you may get a minor performance hit as the page is immediately reloaded back into memory again, so care should be taken when using this function. - Note that the function will return -1 if flush is not supported for the chosen resources, or it will return 0 if all worked correctly.

        +

        sprite_flush_multi

        +

        This function removes any number of texture pages for the given sprites from texture memory (VRAM).

        +

        You supply the sprites as an array and the texture pages they are assigned to will be removed from texture memory. The function will return -1 if flush is not supported for the chosen assets, or it will return 0 if all worked correctly.

        +

         If one of the texture pages is used elsewhere in the room (by another instance sprite, background, etc.) you may get a minor performance hit as the page is immediately reloaded back into memory again, so care should be taken when using this function.

         

        Syntax:

        -

        sprite_flush_multi(array);

        +

        sprite_flush_multi(array);

        - + + - + - - - + + + +
        ArgumentTypeArgumentType Description
        arrayArray with the sprite indices to flush
        arrayArrayArray with the sprites to flush

         

        Returns:

        -

        (-1 or 0)

        +

        Real (-1 or 0)

         

        Example:

        -

        spr_a[0] = spr_Player_Aura1;
        spr_a[1] = spr_Player_Aura2;
        spr_a[2] = spr_Player_Aura3;
        spr_a[3] = spr_Player_Aura4;
        sprite_flush_multi(spr_a); +

        spr_a[0] = spr_Player_Aura1;
        + spr_a[1] = spr_Player_Aura2;
        + spr_a[2] = spr_Player_Aura3;
        + spr_a[3] = spr_Player_Aura4;
        + sprite_flush_multi(spr_a);

        -

        The above code creates an array where each element holds a sprite index. This array is then used to clear those sprite textures from memory.

        -

         

        +

        The above code creates an array where each element holds a sprite index. This array is then used to clear those sprites' textures from memory.

         

         

        -
        © Copyright YoYo Games Ltd. 2021 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        -

        display_get_timing_method

        -

        This function can be used to retrieve the timing method to be used for rendering your game. The method can be one of the constants listed below.

        -

        For more information on the different timing methods, please see display_set_timing_method().

        +

        display_get_timing_method

        +

        This function returns the timing method to be used for rendering your game.

        +

        The method can be one of the constants listed below:

        +
        +

        For more information on the different timing methods, please see display_set_timing_method.

         

        Syntax:

        -

        display_get_timing_method();

        +

        display_get_timing_method();

         

        Returns:

        -

        Display Timing Method Constant

        - - - - - - - - - - - - - - - - - - - - - - -
        Display Timing Method Constant
        ConstantDescription
        tm_sleepThe sleep margin value is the main timing method
        tm_countvsyncsVsync timing is the main timing method (default for all supported platforms)
        +

        Display Timing Method Constant

         

        Example:

        if display_get_timing_method() != tm_sleep
        @@ -57,18 +36,17 @@

        Example:

                display_set_sleep_margin(20);
            }
        }

        -

        The above code will check the timing method and then if it's not set to tm_sleep it will be set to that and the sleep margin set to 20.

        -

         

        +

        The above code will check the timing method and if it's not set to tm_sleep it will be set to that and the sleep margin set to 20.

         

         

        -

        display_set_timing_method

        -

        This function can be used to set the timing method to be used for rendering your game. The method can be one of the following constants:

        - - - - - - - - - - - - - - - -
        ConstantDescription
        tm_sleepUse the sleep margin value as the main timing method
        tm_countvsyncsUse vsync timing as the main timing method (default for all supported platforms)
        -

        The vsync timing method uses the target platforms support for vertical synchronisation to provide an anchor for the games render timing calculations, while setting the mode to sleep margin will just try to ensure that each frame lasts for the correct amount of time (say 1/30th or 1/60th of a second) by waiting or sleeping. In general the default vsync timing will give the smoothest results, but note that when using the vsync method, the sleep margin values are still relevant, although it will have a reduced impact and we recommend keeping it at its default value when using this method.

        +

        display_set_timing_method

        +

        This function sets the timing method to be used for rendering your game.

        +

        The method can be one of the following constants:

        +
        +

        The vsync timing method uses the target platform's support for vertical synchronisation to provide an anchor for the game's render timing calculations, while setting the mode to sleep margin will just try to ensure that each frame lasts for the correct amount of time (say 1/30th or 1/60th of a second) by waiting or sleeping. In general the default vsync timing will give the smoothest results, but note that when using the vsync method, the sleep margin values are still relevant, although it will have a reduced impact and we recommend keeping it at its default value when using this method.

        By default on all platforms except PS4, Ubuntu and HTML5, GameMaker will use the vsync timing method, while on the unsupported platforms, only sleep margin timing can be used.

        -

        If you wish to set the sleep margin you can do so using the function display_set_sleep_margin() and you can find which timing method is currently being used with the function display_get_timing_method().

        +

        On certain devices that make use of specific framerates (e.g. some Android devices) you may want to use the system timing method. This method removes all of GameMaker's sleeps and game speed control and allows the game speed to be set by the system.

        +

        If you wish to set the sleep margin you can do so using the function display_set_sleep_margin and you can find which timing method is currently being used with the function display_get_timing_method.

         

        Syntax:

        -

        display_set_timing_method(method);

        +

        display_set_timing_method(method);

        @@ -48,7 +35,7 @@

        Syntax:

        - + @@ -60,24 +47,23 @@

        Returns:

        Example:

        if display_get_timing_method() != tm_sleep
        {
        -     display_set_timing_method(tm_sleep);
        +     display_set_timing_method(tm_sleep);
            if display_get_sleep_margin() != 20
            {
                display_set_sleep_margin(20);
            }
        }

        -

        The above code will check the timing method and then if it's not set to tm_sleep it will be set to that and the sleep margin set to 20.

        -

         

        +

        The above code will check the timing method and if it's not set to tm_sleep it will be set to that and the sleep margin set to 20.

         

         

        -

        Global Variables

        -

        A basic description of a global variable is one that, once declared, it belongs to no instance in particular and yet can be accessed by all. Just like local variables, global variables must be declared using an identifier, but unlike a local variable, a global variable remains in memory until the end of the game. So, you can create a global variable to keep track of (for example) the number of bullets that the player has and then just update this variable at different points in the game, form any instance or function and at any time. Essentially, a global variable does not belong to any specific instance and can be accessed, changed and used by all instances, and any changes made to the variable are "global", in that all instances using the variable will be affected by the change. Let's have a look at an example:

        +

        Global Variables

        +

        global variable is one that, once declared, belongs to no instance in particular and yet can be accessed by all. Just like Local Variables, global variables must be declared using an identifier, but unlike a local variable, a global variable remains in memory until the end of the game. So, you can create a global variable to keep track of (for example) the number of bullets that the player has and then just update this variable at different points in the game, from any place in your code and at any time. Any changes made to the variable are "global", in that all instances using the variable will be affected by the change. Let's have a look at an example:

        global.food = 5;

        -

        We declare the "food" variable by first writing "global" and then a "." to tell GameMaker that this variable is now global scope. We will need to use this form from now on any time we are required to access or to change this variable in any way. So, we have created a new variable called "food" and we have declared it as global. Now, any instance or function can use and change this variable in any way and all other instances will "see" this. For example we could have a different food object that the player collides with and in the collision event we have:

        +

        We declare the food variable by first writing the global keyword and then a dot . to tell GameMaker that this variable is global in scope. We will need to use this form from now on any time we are required to access or to change this variable in any way. So, we have created a new variable called food and we have declared it as global. Now, any instance, struct or function can use and change this variable in any way and all other instances will "see" this. For example we could have a different food object that the player collides with and in the collision event we have:

        global.food +=1;

        We also have another object that draws this value like this:

        draw_text(32, 32, "food = " + string(global.food));

        With global variables we can change values and see those changes reflected in all instances of the objects that reference this variable. As with local variables you have to take care not to name your global variables the same as any instance variables as that may cause you problems and make bugs creep into your games due to variable overlap, which can be a difficult issue to debug sometimes. In general you should have a single object that declares all your global variables at the very start of the game (for example, in the Room Start Event of the first object instance placed in the first room of the game) or a single script function that declares them all together, as this gives you a handy place to go back and reference everything at once should you need to check a variable name or edit a value.

        -

        GameMaker has a collection of "built in" global variables too, so you should be aware of them as you may name one of your instance variables the same or wish to have your own global variable with the same name and wonder why you are getting errors! They are easy to spot, however, as they are shown in a different colour in the code editor and also come up in the auto-complete bar at the bottom. The majority of built-in global variables have very specific uses are listed in the appropriate sections of the manual - however there are two important ones that are used frequently and aren't listed elsewhere:

        +

         Inside the Script Editor you're in global scope, so the global. prefix can be omitted. For clarity's sake it can, however, be good to include it anyway.

        +

        The Global Struct

        +

        Global variables are stored in a struct, which you can access like any other struct. To refer to this struct you use the global keyword.

        +

        For example, to show all global variables and script functions that you defined you can use the following code: 

        +

        show_debug_message(global);

        +

        Built-in Global Variables

        +

        GameMaker has a collection of "built-in" global variables too, so you should be aware of them as you may name one of your instance variables the same or wish to have your own global variable with the same name and wonder why you are getting errors! They are easy to spot, however, as they are shown in a different colour in the code editor and also come up in the auto-complete bar at the bottom. The majority of built-in global variables have very specific uses and are listed in the appropriate sections of the manual - however there are two important ones that are used frequently and aren't listed elsewhere:

        -

        There are also three deprecated built in global variables which you should be aware of (these variables are only designed to support legacy projects from previous versions of GameMaker and should not be used in new projects):

        +

        There are also three deprecated built in global variables which you should be aware of (these variables are only designed to support legacy projects from previous versions of GameMaker and should not be used in new projects):

        -

        Finally, there are two variables that can be used for script functions and methods:

        +

        Finally, there are two variables that can be used in script functions and methods:

        -

        The following form can also be used to declare global variables, but it is only included for backwards compatibility, and it is not recommended that you use this form for new projects as future versions of GameMaker may not support it.

        -

        The second form for creating global variables is to declare them as such using the globalvar declaration, much as you would a local variable using the var declaration.

        -

         The globalvar declaration is deprecated and only supported for legacy purposes. You should always use the global. identifier to mark global variables.

        +

        globalvar

        +

         The globalvar declaration is deprecated and only supported for legacy purposes. You should always explicitly refer to global scope using the global. prefix.

        +

        The second form for creating global variables is to declare them as such using the globalvar declaration, much as you would a local variable using the var declaration.

        This (deprecated) declaration would be used as follows:

        globalvar food;
        food = 5;

        -

        Once declared in this way that variable "food" is now considered global and requires no global. prefix - which also means that it's a lot harder to identify global variables in your code and it's also much easier to get variable overlap as you use the same variable name in different objects or from extensions that you've installed. Once declared in this way the global variable is accessed as follows:

        +

        Once declared in this way the variable food is now considered global and requires global. prefix - which also means that it's a lot harder to identify global variables in your code and it's also much easier to get variable overlap as you use the same variable name in different objects or from extensions that you've installed. Once declared in this way the global variable is accessed as follows:

        food += 2;

        or:

        draw_text(32, 32, "food = " + string(food));

        As you can see, with nothing to show that the variable is global in scope you are potentially setting yourself up for many subtle problems to arise in your game, which is why this declaration should be avoided.

        There are a few functions designed to help you when dealing with global variables, which you can find on the following page:

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        + + + \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_exists.htm b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_exists.htm index d4e1652ea..67ff16043 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_exists.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_exists.htm @@ -29,19 +29,19 @@

        Syntax:

        - + - +
        methodDisplay Timing Method ConstantDisplay Timing Method Constant The timing method to use (see the list of constants, above)
        structStructStruct The struct reference to check
        nameStringString The name of the struct variable to check for (as a string)

         

        Returns:

        -

        Boolean

        +

        Boolean

         

        Example:

        if !struct_exists(mystruct, "shields")
        @@ -62,9 +62,11 @@

        © Copyright YoYo Games Ltd. 2023 All R \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_get.htm b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_get.htm index b4c0029f5..7f9c2e930 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_get.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_get.htm @@ -31,19 +31,19 @@

        Syntax:

        struct - Struct + Struct The struct reference to use name - String + String The name of the variable to get (as a string)

         

        Returns:

        -

        Any (any data type) or undefined (if the named variable does not exist)

        +

        Any (any data type) or undefined (if the named variable does not exist)

         

        Example:

        if struct_exists(mystruct, "shields")
        @@ -68,9 +68,11 @@

        © Copyright YoYo Games Ltd. 2023 All R \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_get_names.htm b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_get_names.htm index 58018e6d8..f44f2726b 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_get_names.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_get_names.htm @@ -17,7 +17,7 @@

        struct_get_names

        This function returns an array with the variable names from a struct.

        -

        You pass in the struct reference to check, and each entry in the array will be a String of the variable names that the struct contains.

        +

        You pass in the struct reference to check, and each entry in the array will be a String of the variable names that the struct contains.

         This function doesn't return the static variables of the struct. These belong to its Static Struct, that you can get using static_get.

         

        Syntax:

        @@ -31,14 +31,14 @@

        Syntax:

        struct - Struct + Struct The struct reference to check.

         

        Returns:

        -

        Array (each entry is a String)

        +

        Array (each entry is a String)

         

        Example 1: Basic Use

        var _my_struct = {a: 7, str: "a string"};
        @@ -95,9 +95,11 @@

        © Copyright YoYo Games Ltd. 2023 All R \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_names_count.htm b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_names_count.htm index 67a44db52..d7cd90721 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_names_count.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_names_count.htm @@ -30,14 +30,14 @@

        Syntax:

        struct_id - Struct + Struct The unique ID value of the struct to check.

         

        Returns:

        -

        Real

        +

        Real

         

        Example:

        var _num = struct_names_count(mystruct);
        @@ -56,9 +56,11 @@

        © Copyright YoYo Games Ltd. 2023 All R \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_remove.htm b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_remove.htm index c5043cc04..dd8edfb3c 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_remove.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_remove.htm @@ -4,7 +4,7 @@ struct_remove - + @@ -28,12 +28,12 @@

        Syntax:

        struct - Struct + Struct The struct reference to remove the variable from name - String + String The name of the variable to remove (as a string) @@ -54,16 +54,18 @@

        Example:

        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_set.htm b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_set.htm index c954c4c82..7c852b42d 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_set.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Variable_Functions/variable_struct_set.htm @@ -28,17 +28,17 @@

        Syntax:

        struct - Struct + Struct The struct reference to set name - String + String The name of the variable to set (as a string) val - Any + Any The value to set the variable to @@ -66,9 +66,11 @@
        © Copyright YoYo Games Ltd. 2023 All R \ No newline at end of file diff --git a/Manual/contents/The_Asset_Editors/Object_Properties/Other_Events.htm b/Manual/contents/The_Asset_Editors/Object_Properties/Other_Events.htm index 0fa4c29f7..783c7b4e6 100644 --- a/Manual/contents/The_Asset_Editors/Object_Properties/Other_Events.htm +++ b/Manual/contents/The_Asset_Editors/Object_Properties/Other_Events.htm @@ -4,7 +4,7 @@ Other Events - + @@ -108,9 +108,9 @@

        The Other Events

        This event is triggered whenever a sprite or a sequence generates a broadcast message string. For more information please see the page on Broadcast Messages.

        -

        Wallpaper Config

        +

        Wallpaper Events

        -

        This event is triggered by the Wallpaper Companion App. For more information, see the page on the Wallpaper Config Event.

        +

        Wallpaper events are triggered by the Wallpaper Companion App. For more information, see the page on the Wallpaper Config Event.

         

        This event list also contains the Rollback Events.

        diff --git a/Manual/contents/The_Asset_Editors/Object_Properties/Wallpaper_Config_Event.htm b/Manual/contents/The_Asset_Editors/Object_Properties/Wallpaper_Config_Event.htm index 5447e73d1..07d0d08ce 100644 --- a/Manual/contents/The_Asset_Editors/Object_Properties/Wallpaper_Config_Event.htm +++ b/Manual/contents/The_Asset_Editors/Object_Properties/Wallpaper_Config_Event.htm @@ -3,21 +3,24 @@ - - Wallpaper Config Event + + Wallpaper Events - - + + -

        Wallpaper Config Event

        -

        This event is used with the Live Wallpaper functionality, and runs whenever a setting for the wallpaper is changed in the companion app.

        -

        You get the updated wallpaper settings in the wallpaper_config variable.

        -

        wallpaper_config

        +

        Wallpaper Events

        +

        There are two events used for making Live Wallpapers.

        +

        +

        Wallpaper Config

        +

        This event runs whenever a setting for the wallpaper is changed in the companion app.

        +

        You get the updated wallpaper settings in the wallpaper_config variable.

        +

        wallpaper_config

        This variable is a struct containing your sections. Each section is a struct containing the options and sections within that section.

        To access an option from this struct, you would use this syntax: 

        wallpaper_config.section_name.option_name

        @@ -26,6 +29,8 @@

        wallpaper_config

        Here is an example using the same settings defined on the wallpaper_set_config page: 

        var _new_colour = wallpaper_config.colours.blendColor;
        obj_clock.colour = _new_colour;

        +

        Wallpaper Subscription Data

        +

        This event is triggered when information is received on a metric that you are subscribed to. For details on what is included in this event, see Receiving Metrics.

         

         

        © Copyright YoYo Games Ltd. 2023 All Rights Reserved
        + + \ No newline at end of file diff --git a/Manual/contents/assets/Images/Asset_Editors/Editor_Objects_OtherEvents.png b/Manual/contents/assets/Images/Asset_Editors/Editor_Objects_OtherEvents.png index 333af9162be40e2a463ead650619fe802934418d..0f7e8fc4649559fb3382dbb4600204692993622d 100644 GIT binary patch literal 70385 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 literal 56528 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%0D(V-o`BzuJtLmZs=0HY@s!7tST8P}86WDS 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 LNkvXXu0mjf+aU_h literal 16054 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 diff --git a/Manual/contents/assets/scripts/gml.js b/Manual/contents/assets/scripts/gml.js index f9b690e69..e18bca6fa 100644 --- a/Manual/contents/assets/scripts/gml.js +++ b/Manual/contents/assets/scripts/gml.js @@ -137,6 +137,7 @@ export default function(hljs) { "variable_get_hash", "variable_clone", "wallpaper_set_config", + "wallpaper_set_subscriptions", "ds_grid_to_mp_grid", "game_change", "camera_copy_transforms", @@ -2736,6 +2737,7 @@ export default function(hljs) { const SYMBOLS = [ "audio_bus_main", "wallpaper_config", + "wallpaper_subscription_data", "argument_relative", "argument", "argument0", diff --git a/Manual/contents/assets/snippets/Example_wallpaper_set_subscriptions.hts b/Manual/contents/assets/snippets/Example_wallpaper_set_subscriptions.hts new file mode 100644 index 000000000..8a44dc48b --- /dev/null +++ b/Manual/contents/assets/snippets/Example_wallpaper_set_subscriptions.hts @@ -0,0 +1,48 @@ + + + + + + + + Example_wallpaper_set_subscriptions + + + +

        // Create Event
        + wallpaper_set_subscriptions(["desktop_mouse", "cpu"]);
        +
        +
        + // Wallpaper Subscription Data Event
        + var _info = wallpaper_subscription_data;
        + var _cpus = _info.cpu.devices;
        +
        + file = file_text_open_append("sysinfo.txt");
        + file_text_writeln(file);
        + file_text_write_string(file, string(date_current_datetime()));
        + file_text_write_string(file, $"\nCPU count: {_info.cpu.num_devices}");
        +
        + array_foreach(_cpus, function(_cpu, _num)
        + {
        +     if (!struct_exists(_cpu, "usage_pct")) return;
        +     var _str = $"\nCPU {_num} load: {_cpu.usage_pct}%";
        +     file_text_write_string(file, _str);
        + });
        +
        + file_text_close(file); +

        +

        The first line, run in the Create event, enables mouse input and subscribes to CPU metrics.

        +

        In the Wallpaper Subscription Data event, it gets the devices array for the CPU, and opens a text file to write metrics to.

        +

        In that file, it writes the current datetime, CPU count, and then proceeds to write the load percentage of each CPU device in the array.

        +

        This code generates the following text in the sysinfo.txt file, found in the working directory:

        +

        45245.33
        + CPU count: 1
        + CPU 0 load: 3%
        + 45245.33
        + CPU count: 1
        + CPU 0 load: 3%
        + 45245.33
        + CPU count: 1
        + CPU 0 load: 3%

        + + \ No newline at end of file diff --git a/Manual/toc/Default.toc b/Manual/toc/Default.toc index 16b63cef1..006a06bb1 100644 --- a/Manual/toc/Default.toc +++ b/Manual/toc/Default.toc @@ -3096,6 +3096,7 @@ + From aec2500134a0b0be7124e44df757bc30d73f3544 Mon Sep 17 00:00:00 2001 From: suchitra Date: Thu, 16 Nov 2023 13:05:41 +0000 Subject: [PATCH 85/97] fixes for localisation --- .github/workflows/sync.yml | 60 ++++++++++--------- .../trigger-all-localisation-builds.yml | 26 ++++---- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 71a62bbc2..8fe9e49a5 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -7,30 +7,36 @@ on: jobs: - sync_latest_from_upstream: - runs-on: ubuntu-latest - name: Sync latest commits from upstream repo - steps: - - name: Checkout target repo - uses: actions/checkout@v2 - with: - ref: main - token: ${{ secrets.GH_TOKEN }} - persist-credentials: false - - name: repo-sync-develop - uses: repo-sync/github-sync@v2 - with: - source_repo: "https://${{ secrets.GH_TOKEN }}@github.com//YoYoGames/GameMaker-Manual.git" - source_branch: "develop" - destination_branch: "develop" - github_token: ${{ secrets.GH_TOKEN }} - sync_tags: "true" - - name: repo-sync-lts-2022-r1 - uses: repo-sync/github-sync@v2 - with: - source_repo: "https://${{ secrets.GH_TOKEN }}@github.com//YoYoGames/GameMaker-Manual.git" - source_branch: "main-lts" - destination_branch: "main-lts" - github_token: ${{ secrets.GH_TOKEN }} - sync_tags: "true" - + sync_latest_from_upstream: + runs-on: ubuntu-latest + name: Sync latest commits from upstream repo + steps: + - name: Checkout target repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GH_TOKEN }} + persist-credentials: false + - name: Sync upstream changes + id: sync + uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 + with: + target_sync_branch: develop + # REQUIRED 'target_repo_token' exactly like this! + target_repo_token: ${{ secrets.GH_TOKEN }} + upstream_sync_branch: develop + upstream_sync_repo: YoYoGames/GameMaker-Manual + upstream_repo_access_token: ${{ secrets.GH_TOKEN }} + git_config_user: ksuchitra532 + git_config_email: null + git_config_pull_rebase: true + - name: Sync upstream changes + id: sync-lts + uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 + with: + target_sync_branch: main-lts + # REQUIRED 'target_repo_token' exactly like this! + target_repo_token: ${{ secrets.GH_TOKEN }} + upstream_sync_branch: main-lts + upstream_sync_repo: YoYoGames/GameMaker-Manual + upstream_repo_access_token: ${{ secrets.GH_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/trigger-all-localisation-builds.yml b/.github/workflows/trigger-all-localisation-builds.yml index 6b6b542bc..49e7ebe86 100644 --- a/.github/workflows/trigger-all-localisation-builds.yml +++ b/.github/workflows/trigger-all-localisation-builds.yml @@ -9,10 +9,14 @@ on: type: choice options: - ALL - Preset: + - ONE + BUILT_TYPE: description: "Select individual language to build" required: true - type: string + type: choice + options: + - main + - lts jobs: @@ -24,21 +28,21 @@ jobs: matrix: language: [PT-BR, DE, ES, FR, IT, JA, KO, PL, RU, ZH] steps: - - name: Invoke workflow Brazilian in repo - if: ${{ github.event.inputs.Language }} + - name: Invoke Localisation Workflows + if: ${{ github.event.inputs.Language }} == 'ALL' uses: benc-uk/workflow-dispatch@v1 with: - workflow: build.yml + workflow: ${{ github.event.inputs.Language }}.yml repo: YoYoGames/GameMaker-Manual-${{ matrix.language }} - token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + token: ${{ secrets.GH_TOKEN }} continue-on-error: false - - name: Invoke workflow Brazilian in repo - if: ${{ github.event.inputs.Preset }} == '' + - name: Invoke Localisation Workflows + if: ${{ github.event.inputs.Language }} == 'ONE' uses: benc-uk/workflow-dispatch@v1 with: - workflow: build.yml - repo: YoYoGames/GameMaker-Manual-${{ github.event.inputs.Preset }} - token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + workflow: ${{ github.event.inputs.Language }}.yml + repo: YoYoGames/GameMaker-Manual-${{ matrix.language }} + token: ${{ secrets.GH_TOKEN }} continue-on-error: false From 953dda928cde73a1b9832480256c67cee466c899 Mon Sep 17 00:00:00 2001 From: suchitra Date: Thu, 16 Nov 2023 13:10:11 +0000 Subject: [PATCH 86/97] fixes for localisation --- .github/workflows/trigger-all-localisation-builds.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/trigger-all-localisation-builds.yml b/.github/workflows/trigger-all-localisation-builds.yml index 49e7ebe86..85078197f 100644 --- a/.github/workflows/trigger-all-localisation-builds.yml +++ b/.github/workflows/trigger-all-localisation-builds.yml @@ -10,7 +10,7 @@ on: options: - ALL - ONE - BUILT_TYPE: + BUILD_TYPE: description: "Select individual language to build" required: true type: choice @@ -32,7 +32,7 @@ jobs: if: ${{ github.event.inputs.Language }} == 'ALL' uses: benc-uk/workflow-dispatch@v1 with: - workflow: ${{ github.event.inputs.Language }}.yml + workflow: ${{ github.event.inputs.BUILD_TYPE }}.yml repo: YoYoGames/GameMaker-Manual-${{ matrix.language }} token: ${{ secrets.GH_TOKEN }} continue-on-error: false @@ -40,7 +40,7 @@ jobs: if: ${{ github.event.inputs.Language }} == 'ONE' uses: benc-uk/workflow-dispatch@v1 with: - workflow: ${{ github.event.inputs.Language }}.yml + workflow: ${{ github.event.inputs.BUILD_TYPE }}.yml repo: YoYoGames/GameMaker-Manual-${{ matrix.language }} token: ${{ secrets.GH_TOKEN }} continue-on-error: false From 12345135393346a7df1b982f3952936267044801 Mon Sep 17 00:00:00 2001 From: suchitra Date: Thu, 16 Nov 2023 13:11:23 +0000 Subject: [PATCH 87/97] fixes for localisation --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0792870e1..c645e4dc3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: pull_request: paths-ignore: - - ./github/workflows/** + - ./.github/workflows/** branches: - develop From eaa1c6a15d8d46fa8e5c614d095414d031a61b0a Mon Sep 17 00:00:00 2001 From: suchitra Date: Thu, 16 Nov 2023 14:07:29 +0000 Subject: [PATCH 88/97] fixes for localisation --- .github/workflows/trigger-all-localisation-builds.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/trigger-all-localisation-builds.yml b/.github/workflows/trigger-all-localisation-builds.yml index 85078197f..7ff7a6099 100644 --- a/.github/workflows/trigger-all-localisation-builds.yml +++ b/.github/workflows/trigger-all-localisation-builds.yml @@ -5,11 +5,10 @@ on: inputs: Language: description: "Select All languages to build" - required: true + required: false type: choice options: - ALL - - ONE BUILD_TYPE: description: "Select individual language to build" required: true @@ -36,14 +35,6 @@ jobs: repo: YoYoGames/GameMaker-Manual-${{ matrix.language }} token: ${{ secrets.GH_TOKEN }} continue-on-error: false - - name: Invoke Localisation Workflows - if: ${{ github.event.inputs.Language }} == 'ONE' - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: ${{ github.event.inputs.BUILD_TYPE }}.yml - repo: YoYoGames/GameMaker-Manual-${{ matrix.language }} - token: ${{ secrets.GH_TOKEN }} - continue-on-error: false \ No newline at end of file From eb76e50d6f29f6b002398f166275abb201ba2e46 Mon Sep 17 00:00:00 2001 From: suchitra Date: Thu, 16 Nov 2023 14:09:45 +0000 Subject: [PATCH 89/97] ignoring path for changes made in worklfows not to run CI --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c645e4dc3..50f6de742 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: pull_request: paths-ignore: - - ./.github/workflows/** + - '.github/workflows/**' branches: - develop From 31c84697568588f215e61b0a97d906815803c09f Mon Sep 17 00:00:00 2001 From: YYBartT Date: Thu, 16 Nov 2023 17:33:58 +0100 Subject: [PATCH 90/97] [General]audio_play_sound/at/on/ext() documentation should introduce users to the behaviour covered in the Audio Properties Overview YoYoGames/GameMaker-Bugs#2193 YoYoGames/GameMaker-Bugs#2190 * Rewrote Volume & Playback a bit on The Sound Editor page * Moved note about asset-level gain being value of the sound volume slider to a snippet and linked * Added extra info to Optional Properties snippet, including a link to the main Audio page and the Audio Properties Overview page * Added third example on audio_play_sound page to clarify the basics of gain and offset properties * Linked a "Note" snippet that refers to the Audio Playback Ended event, inserted on audio_play_sound_* pages and main Audio page * Added a bit of extra info and the default parameter values to the tables on the audio_play_sound_* pages * audio_sound_get_track_position: added sound asset as a valid parameter type, rewrote the description to explain which value is returned * Minor changes and typo fixes on some pages --- .../Asset_Management/Audio/Audio.htm | 14 ++++--- .../Audio_Emitters/audio_play_sound_on.htm | 33 ++++++++------- .../Audio/Audio_Properties.htm | 12 +++--- .../Audio/audio_play_sound.htm | 42 ++++++++++++------- .../Audio/audio_play_sound_at.htm | 37 ++++++++-------- .../Audio/audio_play_sound_ext.htm | 41 +++++++++--------- .../Audio/audio_sound_gain.htm | 11 +++-- .../Audio/audio_sound_get_track_position.htm | 21 ++++++---- .../Audio/audio_sound_set_track_position.htm | 10 ++--- .../Audio/audio_stop_sound.htm | 5 +-- Manual/contents/The_Asset_Editors/Sounds.htm | 14 +++---- ...Note_Sound_Editor_Volume_Is_Asset_Gain.hts | 15 +++++++ .../Note_Triggers_Audio_Playback_Event.hts | 14 +++++++ .../audio_play_sound_last_arguments.hts | 7 ++-- 14 files changed, 161 insertions(+), 115 deletions(-) create mode 100644 Manual/contents/assets/snippets/Note_Sound_Editor_Volume_Is_Asset_Gain.hts create mode 100644 Manual/contents/assets/snippets/Note_Triggers_Audio_Playback_Event.hts diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio.htm b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio.htm index c02cc7d3c..44b1a6e9b 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio.htm @@ -4,7 +4,7 @@ Audio - + @@ -29,10 +29,11 @@

        Using Audio

        Playing Sounds

        The most straightforward way to play a sound is using audio_play_sound

        audio_play_sound(snd_Explode, 10, false);

        -

        At a minimum you have to provide the Sound Asset, a priority for the new sound instance and whether the sound should loop.

        -

        Another way to play sounds is using audio_play_sound_ext. This function is identical to audio_play_sound but allows you to pass various audio parameters in a struct. Using this function, you only need to provide a Sound Asset through the "sound" key of the struct: 

        +

        At a minimum you have to provide the Sound Asset, a priority for the new sound instance and whether the sound should loop.

        +

        Another way to play sounds is using audio_play_sound_ext. This function is identical to audio_play_sound but allows you to pass various audio parameters in a struct. Using this function, you only need to provide a Sound Asset through the "sound" key of the struct: 

        audio_play_sound_ext({ sound: snd_Explode });

        Here the priority will default to 0 and the sound will not be looped. You can supply additional keys in the struct to change the properties of the sound.

        +

        Sound Instances (Voices)

        The functions audio_play_sound and audio_play_sound_ext create a new instance of a sound (also called a "voice") and return its ID: 

        ins_sound = audio_play_sound(snd_Explode, 10, false);

        @@ -40,18 +41,19 @@

        Sound Instances (Voices)

        In case you pass a sound asset ID to the functions, the audio property at the asset level will be set to the given value.

         audio_play_sound_at and audio_play_sound_on work in the same way and also return the ID of the sound instance they create.

         The maximum number of sound instances/voices is 128 by default. This can be changed using the function audio_channel_num.

        -

        Audio Properties

        +

        Audio Properties

        Every sound has basic properties that are applied on different "levels". Depending on the property, it either acts as a multiplier, or overrides the value set at a previous level.

        These audio properties are: 

          -
        • Gain: This is a multiplier for the volume. The default value for gain on the asset level is the value of the "Volume" slider in the Sound Editor. The default value on all other levels is 1. Gain can also be added using Audio Effects.
        • +
        • Gain: This is a multiplier for the volume. The default value for gain on the asset level is the value of the "Volume" slider in The Sound Editor. The default value on all other levels is 1. Gain can also be added using Audio Effects.
        • Pitch: This is a multiplier for the sound's pitch. The default value for pitch on all levels is set to 1.
        • Offset/Track Position: This is the offset from the start of the audio track where it starts playing. If this value is set at the instance level, it overrides the value set at the asset level. By default this is 0 (i.e. no offset).
        • Listener Mask: This is a bitmask value that determines the listeners that audio is heard on. The default value is 1 (or 0x01), which stands for the default listener.

        For an overview of all audio properties, levels and how their values are calculated, see Audio Properties Overview.

        +

         The optional parameters that you can pass to the audio_play_sound_* functions set the instance-level value of the property.

        Audio Looping

        -

        A sound can be looped by setting it to loop. This can either be done when playing the sound using any of the audio_play_sound_ functions: 

        +

        A sound can be looped by setting it to loop. This can either be done when playing the sound using any of the audio_play_sound_* functions: 

        ins_sound = audio_play_sound(snd_Engine, 100, true);

        or afterwards, when the sound is already playing, using the function audio_sound_loop

        audio_sound_loop(ins_sound, true);

        diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio_Emitters/audio_play_sound_on.htm b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio_Emitters/audio_play_sound_on.htm index 576a6156b..fac3955d7 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio_Emitters/audio_play_sound_on.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio_Emitters/audio_play_sound_on.htm @@ -4,7 +4,7 @@ audio_play_sound_on - + @@ -15,8 +15,9 @@

        audio_play_sound_on

        -

        With this function you can play any sound resource through an emitter, with any changes to the emitter's gain, position, pitch or velocity affecting how the user hears the final sound being played.

        -

        You provide the emitter index to use, the sound index of the sound to be played and then specify whether the sound is to loop or not. Next you can assign a priority, which is then used to determine how sounds are dealt with when the number of sounds playing is over the limit set by the function audio_channel_num(). Lower priority sounds will be stopped in favour of higher priority sounds, and the priority value can be any real number (the actual value is arbitrary, and can be from 0 to 1 or 0 to 100, as GameMaker will prioritise them the same). Note that when dealing with priority, the higher the number the higher the priority, such that a sound with priority 100 will be favoured over a sound with priority 1.

        +

        This function plays any sound asset through an emitter, with any changes to the emitter's gain, position, pitch or velocity affecting how the user hears the final sound being played.

        +
        +

        You provide the emitter index to use, the Sound Asset to be played and then specify whether the sound is to loop or not. Next you can assign a priority, which is then used to determine how sounds are dealt with when the number of sounds playing is over the limit set by the function audio_channel_num(). Lower priority sounds will be stopped in favour of higher priority sounds, and the priority value can be any real number (the actual value is arbitrary, and can be from 0 to 1 or 0 to 100, as GameMaker will prioritise them the same). Note that when dealing with priority, the higher the number the higher the priority, such that a sound with priority 100 will be favoured over a sound with priority 1.

        This function will also return a unique index for the sound being played, which can be stored in a variable so you can later pause it or stop it. This means that if you have multiple instances of the same sound playing at any one time, you can target just one instance of that sound using the audio functions.

         

        @@ -31,49 +32,49 @@

        Syntax:

        emitter - Audio Emitter ID + Audio Emitter ID The index of the emitter to use. sound - Sound Asset + Sound Asset The index of the sound to use. loop - Boolean + Boolean Flags the sound as looping or not. priority - Real + Real Set the channel priority for the sound. gain - Real -  Value for the gain. + Real +  The gain of the sound instance (defaults to 1). offset - Real -  The time (in seconds) to set the start point to. Values beyond the end of the sound are clamped to its length. + Real +  The time (in seconds) to start playing. Values beyond the end of the sound are clamped to its length. The default value is the asset-level offset, this value overrides it when provided. pitch - Real -  The pitch multiplier (default 1). + Real +  The pitch multiplier (defaults to 1). listener_mask - Real + Real  The bitmask data to set for the sound. On the HTML5 target  this will have no effect as the target does not support more than one listener.

         

        Returns:

        -

        Sound Instance ID

        +

        Sound Instance ID

         

        Example 1:

        if global.SFX
        @@ -95,7 +96,7 @@

        Example 2:

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved

        audio_play_sound

        -

        With this function you can play any Sound Asset in your game.

        +

        This function plays any Sound Asset in your game.

        +

        You provide the sound asset and assign it a priority, which is then used to determine how sounds are dealt with when the number of sounds playing is over the limit set by the function audio_channel_num(). Lower priority sounds will be stopped in favour of higher priority sounds, and the priority value can be any real number (the actual value is arbitrary, and can be from 0 to 1 or 0 to 100, as GameMaker will prioritise them the same). The higher the number the higher the priority, so a sound with priority 100 will be favoured over a sound with priority 1.

        The third argument is for making the sound loop and setting it to true will make the sound repeat until it's stopped manually, and setting it to false will play the sound once only.

        This function will also return a unique index for the sound being played, which can be stored in a variable so you can later pause it or stop it. This means that if you have multiple instances of the same sound playing at any one time, you can target just one instance of that sound using the audio functions.

        @@ -32,58 +33,67 @@

        Syntax:

        index - Sound Asset or Audio Queue ID + Sound Asset or Audio Queue ID The index of the sound to play. priority - Real + Real Set the channel priority for the sound. loop - Boolean + Boolean Sets the sound to loop or not. gain - Real - OPTIONAL Value for the gain. + Real +  The gain of the sound instance (defaults to 1). offset - Real - OPTIONAL The time (in seconds) to set the start point to. Values beyond the end of the sound are clamped to its length. + Real +  The time (in seconds) to start playing. Values beyond the end of the sound are clamped to its length. The default value is the asset-level offset, this value overrides it when provided. pitch - Real - OPTIONAL The pitch multiplier (default 1). + Real +  The pitch multiplier (defaults to 1). listener_mask - Real - OPTIONAL The bitmask data to set for the sound. On the HTML5 target  this will have no effect as the target does not support more than one listener. + Real +  The bitmask data to set for the sound. On the HTML5 target  this will have no effect as the target does not support more than one listener.

         

        Returns:

        -

        Sound Instance ID

        +

        Sound Instance ID

         

        -

        Example 1:

        +

        Example 1: Basic Use

        if health <= 0
        {
            lives -= 1;
        -     audio_play_sound(snd_PlayerDead, 10, false);
        +     audio_play_sound(snd_PlayerDead, 10, false);
        }

        The above code checks the "health" global variable and if it is less than or equal to 0, it will remove 1 from the "lives" global variable and play a sound.

        -

        Example 2:

        +

        Example 2: Optional Properties

        if bbox_left > room_width
        {
            audio_play_sound(snd_Goodbye, 10, false, 1.1, 0, 2);
        }

        The above code checks if the instance is past the right bound of the room and plays a sound with a gain of 1.1 and a pitch of 2 (twice the normal pitch).

        +

        Example 3: Asset & Instance Properties

        +

        audio_sound_gain(snd_Explosion, 0.7);
        + audio_sound_set_track_position(snd_Explosion, 2);
        + audio_play_sound(snd_Explosion, 10, false, 0.5);
        + audio_play_sound(snd_Explosion, 20, false, 1, 0); +

        +

        The above code plays the same sound multiple times.

        +

        First, the gain for the sound asset snd_Explosion is set to 0.7. Next, its track position (the position from which to start playing) is set to 2 seconds.

        +

        After that, two instances of the sound are played. The first gets an instance-level gain of 0.5 and no offset. This sound instance starts playing at 2 seconds and will be heard with a gain of 0.5 * 0.7 = 0.35. The second instance keeps the instance-level gain at 1 and will be heard with a gain of 0.7 * 1 = 0.7. Its offset is provided, which overrides the 2-second offset set for the asset. This instance plays from the start.

         

         

        -
        © Copyright YoYo Games Ltd. 2022 All Rights Reserved
        +
        © Copyright YoYo Games Ltd. 2023 All Rights Reserved

        audio_sound_set_track_position

        This function will set the position (in seconds) for the given sound ID or asset.

        -

        The supplied "index" can either be a single instance of a sound (as returned from audio_play_sound()) or a sound asset (e.g. one added via the Asset Browser). The behaviour of this function will differ depending on the kind of index you have specified:

        +

        The supplied "index" can either be a single instance of a sound (as returned from audio_play_sound()) or a sound asset (e.g. one added via The Asset Browser). The behaviour of this function will differ depending on the kind of index you have specified:

        • If it's a unique sound ID that you use, which is already playing, then its position will immediately change to the given time.
        • If it's a sound asset, then all further plays of the given sound asset will start at the new time.
        • @@ -34,12 +34,12 @@

          Syntax:

          index - Sound Asset or Sound Instance ID + Sound Asset or Sound Instance ID The index of the sound to change. time - Real + Real The time (in seconds) to set the start point to. Values beyond the end of the sound are clamped to its length. @@ -62,7 +62,7 @@

          Example:

          -
          © Copyright YoYo Games Ltd. 2022 All Rights Reserved
          +
          © Copyright YoYo Games Ltd. 2023 All Rights Reserved

          If Gamepad Button Down Icon If Gamepad Button Down

          -

          With this action you can poll a gamepad to see if a given button is currently being held down. The action will return true every step that the button is being held down, or false otherwise, although if you click the not modifier - you can then check to see if the button is not being held, ie: the action will return true while no button is down and false if there is. If you only need to check for a single button press then use the action If Gamepad Button Pressed.

          +

          With this action you can poll a gamepad to see if a given button is currently being held down. The action will return true every step that the button is being held down, or false otherwise, although if you click the not modifier you can then check to see if the button is not being held, i.e.: the action will return true while no button is down and false if there is. If you only need to check for a single button press then use the action If Gamepad Button Pressed.

          If the button being checked is an analogue button, then it will not be considered held down until the button value has gone above the threshold set using the action Set Gamepad Button Threshold.

          Note that to add actions into the "if" block, they should be dropped to the side of the action, as shown in the image below:

          -

          If Gamepad Button Down drop actionsThese actions will now be run if the "if" evaluates to true, - while any actions dropped elsewhere will be performed after the "if" block.

          +

          If Gamepad Button Down drop actionsThese actions will now be run if the "if" evaluates to true, while any actions dropped elsewhere will be performed after the "if" block.

           

          Action Syntax:

          If Gamepad Button Down

          @@ -47,9 +45,7 @@

          Arguments:

           

          Example:

          -

          If Gamepad Button Down ExampleThe above action block code polls the button state of gamepad 0 every step and if - a button is being held down it checks for the initial button down press. If the check is true on the initial down press, a sound is played, then, while the button is held down, the instance speed is set to 10. If the button is not being held - down, a check is done on the button release to reset the speed to 0 again.

          +

          If Gamepad Button Down ExampleThe above action block code polls the button state of gamepad 0 every step and if a button is being held down it checks for the initial button down press. If the check is true on the initial down press, a sound is played, then, while the button is held down, the instance speed is set to 10. If the button is not being held down, a check is done on the button release to reset the speed to 0 again.

           

           

           

          @@ -60,7 +56,7 @@

          Example:

          -
          © Copyright YoYo Games Ltd. 2021 All Rights Reserved
          +
          © Copyright YoYo Games Ltd. 2023 All Rights Reserved

          If Gamepad Button Pressed Icon If Gamepad Button Pressed

          -

          With this action you can poll the gamepad to see if any button is currently being pressed. The action will return true every step that the gamepad button is being pressed (and held) down, or false otherwise, although if you click the - not modifier you can then check to see if the button is not being pressed, ie: the action will return true while no button is pressed and false if there is. If you only need to check for a single button press then - use the action if gamepad button down.

          +

          With this action you can poll a gamepad to see if any button is currently being pressed. The action will only return true during the step that the gamepad button is pressed down, and false afterwards, until the button is released and pressed again. If you click the not modifier you can then check to see if the button is not being pressed. If you need to check for a button being held down, then use the action If Gamepad Button Down.

          If the button being checked is an analogue button, then the press will not be detected until the button value has gone above the threshold set using the action Set Gamepad Button Threshold.

          Note that to add actions into the "if" block, they should be dropped to the side of the action, as shown in the image below:

          -

          If Gamepad Button Pressed drop actionsThese actions will now be run if the - "if" evaluates to true, while any actions dropped elsewhere will be performed after the "if" block.

          +

          If Gamepad Button Pressed drop actionsThese actions will now be run if the "if" evaluates to true, while any actions dropped elsewhere will be performed after the "if" block.

           

          Action Syntax:

          If Gamepad Button Pressed Action

          @@ -48,9 +45,7 @@

          Arguments:

           

          Example:

          -

          If Gamepad Button Pressed ExampleThe above action block code polls the button state of gamepad 0 every step and - if a button is being held down it checks for the initial button down press. If the check is true on the initial down press, a sound is played, then, while the button is held down, the instance speed is set to 10. If the button is not being - held down, a check is done on the button release to reset the speed to 0 again.

          +

          If Gamepad Button Pressed ExampleThe above action block code polls the button state of gamepad 0 every step and if a button is being held down it checks for the initial button down press. If the check is true on the initial down press, a sound is played, then, while the button is held down, the instance speed is set to 10. If the button is not being held down, a check is done on the button release to reset the speed to 0 again.

           

           

           

          @@ -61,7 +56,7 @@

          Example:

          -
          © Copyright YoYo Games Ltd. 2021 All Rights Reserved
          +
          © Copyright YoYo Games Ltd. 2023 All Rights Reserved

          display_get_gui_height

          This function gets the height (in pixels) of the GUI as used in the Draw GUI Event.

          +

           

          Syntax:

          display_get_gui_height();

           

          Returns:

          -

          Real

          +

          Real

           

          Example:

          Draw GUI Event

          @@ -44,10 +45,10 @@

          Example:

          © Copyright YoYo Games Ltd. 2023 All Rights Reserved
          \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Cameras_And_Display/display_get_gui_width.htm b/Manual/contents/GameMaker_Language/GML_Reference/Cameras_And_Display/display_get_gui_width.htm index e89e26ecb..be969c059 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Cameras_And_Display/display_get_gui_width.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Cameras_And_Display/display_get_gui_width.htm @@ -4,7 +4,7 @@ display_get_gui_width - + @@ -16,12 +16,13 @@

          display_get_gui_width

          This function gets the width (in pixels) of the GUI as used in the Draw GUI Event.

          +

           

          Syntax:

          display_get_gui_width();

           

          Returns:

          -

          Real

          +

          Real

           

          Example:

          Draw GUI Event

          diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Cameras_And_Display/display_get_height.htm b/Manual/contents/GameMaker_Language/GML_Reference/Cameras_And_Display/display_get_height.htm index c917f8c49..e22208b1f 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Cameras_And_Display/display_get_height.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Cameras_And_Display/display_get_height.htm @@ -4,7 +4,7 @@ display_get_height - + @@ -22,7 +22,7 @@

          Syntax:

          display_get_height();

           

          Returns:

          -

          +

          Real

           

          Example:

          myheight = display_get_height();

          @@ -37,7 +37,7 @@

          Example:

          -
          © Copyright YoYo Games Ltd. 2021 All Rights Reserved
          +
          © Copyright YoYo Games Ltd. 2023 All Rights Reserved