diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d0ac7fd51..3fedb7348 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: env: LANGUAGE: ${{ vars.LANGUAGE }} steps: - - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v6 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -29,7 +29,7 @@ jobs: - name: Enable git long paths to bypass path limit on Windows run: git config --system core.longpaths true - name: Check out the GMS2_Documentation repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: path: Manual token: ${{ secrets.GH_TOKEN }} @@ -41,8 +41,36 @@ jobs: shell: cmd working-directory: Manual - name: Upload robohelp zip file - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: YoYoStudioRoboHelp path: output\RoboHelp\*.zip if-no-files-found: error + + Slack-Notification: + name: "Slack Notification" + if: github.event_name == 'workflow_dispatch' + runs-on: ubuntu-24.04 + needs: RoboHelp + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + steps: + - name: Send Slack Notification Triggered while Nightly Build + run: | + set -euo pipefail + + ARTIFACT_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}#artifacts" + + if [[ "${{ job.status }}" == "success" ]]; then + MSG="📘 English Manual build completed successfully + *Artifacts*: ${ARTIFACT_URL}" + else + MSG="⚠️ English Manual build failed + *Check logs*: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + fi + + curl -X POST -H 'Content-type: application/json' \ + --data "{\"text\":\"$MSG\"}" \ + "$SLACK_WEBHOOK_URL" + + diff --git a/Manual/contents/Additional_Information/Additional_Information.htm b/Manual/contents/Additional_Information/Additional_Information.htm index 769e9fccf..d3a1cd528 100644 --- a/Manual/contents/Additional_Information/Additional_Information.htm +++ b/Manual/contents/Additional_Information/Additional_Information.htm @@ -23,7 +23,6 @@

Additional Information
  • Guide To Primitives And Vertex Building
  • Guide To Using Blendmodes
  • Guide To Using JSON
  • -
  • Project Format
  • Compatibility Functions
  • Compatibility Scripts
  • Obsolete Functions
  • @@ -38,7 +37,7 @@

    Additional Information
    Next: GameMaker Language
    -

    © Copyright YoYo Games Ltd. 2024 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2026 All Rights Reserved
    @@ -40,7 +29,7 @@

    Guide To Using ParticlesCreate Particle System

     The layer name supplied must be a valid layer in the room where the system will be used, otherwise no particles will be visible. Also note that we set the persistent flag (both in GML Code and in GML Visual) to false. A persistent particle system is one that will "persist" across rooms without the need to destroy and re-create it for each room. However, to keep things simple for this guide, we'll not be using persistence.

    So that's the system created, but what about the particles? We have to define them too or the system is useless and does nothing.

    -

    If you already have a Particle System Asset, you can create it using the above function/action by passing the asset into the partsys/"System" argument.

    +

    If you already have a Particle System Asset, you can create it using the above function/action by passing the asset into the partsys/"System" argument.

     

    Defining A Particle Type

    @@ -171,7 +160,7 @@

    Guide To Using ParticlesNext: Guide To Using Shaders -
    © Copyright YoYo Games Ltd. 2025 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2026 All Rights Reserved

    Guide To Using Shaders

    Shaders are often used to create beautiful graphical effects in games. They are also among the most advanced features offered by GameMaker, so it is necessary that you have a basic understanding of programming and how GameMaker works before getting started with them.

    -

    So, what is a shader? Initially they were created to provide shading for lighting (hence the name), but they are now used to produce a huge variety of effects. Shader code is similar to regular code, but it is (almost always) executed by the GPU, not the CPU. This difference comes with its own set of rules and limitations, but we’ll cover those later.

    -

    Each shader is made up of two separate components: a vertex shader and a fragment shader (also referred to as pixel shader). Let’s start with the vertex shader. Each sprite is formed by a rectangle, but computers like to draw triangles, so those rectangles are split into two triangles (sometimes called a quad). This leaves us with six vertices (corners) per sprite, but two of those are the same one, so we should only worry about four. Now, imagine we have a for loop that goes over every vertex and executes the code inside the vertex shader for each. This allows us to change the vertex position and color before passing it over to the fragment shader since the vertex shader is executed earlier.

    -

    Here’s how that would look:

    -

    Shader VerticesFor the fragment shader, you can imagine the same loop as before, but this time it goes over every single pixel in your sprite, giving you information such as location and color of that pixel. In your fragment shader code, you perform operations and calculations to determine the color of that pixel to get the effect you want. For example, if you want a shader to make your sprite be black and white, then you’d calculate which shade of grey each pixel needs to be to create the effect.

    +

    So, what is a shader? Initially they were created to provide shading for lighting (hence the name), but they are now used to produce a huge variety of effects. Shader code is similar to regular code, but it is (almost always) executed by the GPU, not the CPU. This difference comes with its own set of rules and limitations, but we'll cover those later.

    +

    Each shader is made up of two separate components: a vertex shader and a fragment shader (also referred to as pixel shader). Let's start with the vertex shader. Each sprite is formed by a rectangle, but computers like to draw triangles, so those rectangles are split into two triangles (sometimes called a quad). This leaves us with six vertices (corners) per sprite, but two of those are the same one, so we should only worry about four. Now, imagine we have a for loop that goes over every vertex and executes the code inside the vertex shader for each. This allows us to change the vertex position and color before passing it over to the fragment shader since the vertex shader is executed earlier.

    +

    Here's how that would look:

    +

    Shader VerticesFor the fragment shader, you can imagine the same loop as before, but this time it goes over every single pixel in your sprite, giving you information such as location and color of that pixel. In your fragment shader code, you perform operations and calculations to determine the color of that pixel to get the effect you want. For example, if you want a shader to make your sprite be black and white, then you'd calculate which shade of grey each pixel needs to be to create the effect.

    It would look something like this:

    -

    Shader FragmentsThe reason shader code is usually executed by the GPU is that it is more efficient at it. Modern CPUs typically have between two to eight cores. Each core can perform one task at a time, so by taking advantage of multiple cores, we can perform that many tasks simultaneously. In contrast, modern GPUs can perform thousands, and even tens of thousands, of tasks running at the same time. This is helpful for shaders because we can execute the shader code of thousands of pixels concurrently. The limitation is that we only have access to the initial state of the sprite, so we don’t know about any modifications done to other pixels since we can’t know for sure the code has run on them yet.

    -

     GameMaker allows users to write shaders in GLSL (OpenGL Shader Language), HLSL (High-level Shader Language, used when working with DirectX), and GLSL ES (a subset of GLSL which is common in mobile devices). Here we are using GLSL ES as the shader language since it’s the one that provides the best compatibility across target platforms. Generally this is the one you always want to use unless you have very specific needs and understand the limitation of the other shader languages. The math and techniques should be similar between all three languages however, save for a few syntax differences here and there.

    -

    The vertex shader is executed first, and as we explained above, it deals with vertices. It is used to calculate positions, normals, and texture coordinates. These shaders are not particularly useful in 2D, since every sprite is usually a square, but it can be used to do some skewing, scaling, etc... It becomes much more useful in 3D for lighting calculations and mesh deformations. Fragment shaders are much more interesting and are what will be covered mostly here, since the fragment shader is where we get information about our textures and can tweak the final color of each pixel in our image.

    +

    Shader FragmentsThe reason shader code is usually executed by the GPU is that it is more efficient at it. Modern CPUs typically have between two to eight cores. Each core can perform one task at a time, so by taking advantage of multiple cores, we can perform that many tasks simultaneously. In contrast, modern GPUs can perform thousands, and even tens of thousands, of tasks running at the same time. This is helpful for shaders because we can execute the shader code of thousands of pixels concurrently. The limitation is that we only have access to the initial state of the sprite, so we don't know about any modifications done to other pixels since we can't know for sure the code has run on them yet.

    +

     GameMaker allows users to write shaders in GLSL (OpenGL Shader Language), HLSL (High-level Shader Language, used when working with DirectX), and GLSL ES (a subset of GLSL which is common in mobile devices). Here we are using GLSL ES as the shader language since it's the one that provides the best compatibility across target platforms. Generally, this is the one you always want to use unless you have very specific needs and understand the limitation of the other shader languages. The math and techniques should be similar between all three languages however, save for a few syntax differences here and there.

    +

    The vertex shader is executed first, and as we explained above, it deals with vertices. It is used to calculate positions, normals, and texture coordinates. These shaders are not particularly useful in 2D, since every sprite is usually a square, but it can be used to do some skewing, scaling, etc. It becomes much more useful in 3D for lighting calculations and mesh deformations. Fragment shaders are much more interesting and are what will be covered mostly here, since the fragment shader is where we get information about our textures and can tweak the final color of each pixel in our image.

     

    Shader Variables

    -

    If you have created a shader in GameMaker, you might have noticed the following keywords in the default pass-through shader. These keywords help the shader understand the purpose and scope of each variable:

    +

    If you have created a shader in GameMaker, you might have noticed the following keywords in the default passthrough shader. These keywords help the shader understand the purpose and scope of each variable:

    • Attribute: These are variables passed in by OpenGL to the vertex shader. These can change per vertex and are read-only. These include information such as vertex position, texture coordinates, vertex color, and vertex normal.
    • Varying: These are variables used to pass data between the vertex and fragment shaders. These are available for writing in the vertex shader, but are read-only in the fragment shader.
    • Uniform: These are variables that change per object and are passed by the user to the shader. These can be used in both the vertex and fragment shaders, but are read-only.
    -

    You'll also see the use of vec as a keyword. This is used to identify a vector variable in the shader and you'll soon see that vectors are very important when working with shaders. That is why they are implemented as a base type in GLSL. If you are unfamiliar with them, they are a mathematical term represented as a matrix with only one column. In programming, we usually represent them as an array where the number of components corresponds to the dimension. Two and three-dimensional vectors are often used for positions, texture coordinates, or colors without an alpha channel, while four-dimensional ones are used for colors with an alpha channel. We can also specify if they hold booleans, integers, or floating point values. The syntax to declare a vector is this:

    -

    vec2 firstVec;  // Two-dimensional vector of floats
    +

    You'll also see the use of vec as a keyword. This is used to identify a vector variable in the shader and you'll soon see that vectors are very important when working with shaders. That is why they are implemented as a base type in GLSL. If you are unfamiliar with them, they are a mathematical term represented as a matrix with only one column. In programming, we usually represent them as an array where the number of components corresponds to the dimension. Two and three-dimensional vectors are often used for positions, texture coordinates, or colors without an alpha channel, while four-dimensional ones are used for colors with an alpha channel. We can also specify if they hold booleans, integers, or floating point values. The syntax to declare a vector is this:

    +

    vec2 firstVec;  // Two-dimensional vector of floats
    vec3 secondVec; // Three-dimensional vector of floats
    vec4 thirdVec;  // Four-dimensional vector of floats

    @@ -41,43 +41,43 @@

    Shader Variables

    ivec4 intVec;   // Four-dimensional vector of integers

    To initialize them, we can use the constructor to create the vector. You need to provide the same number of values as the length of the vector, but you can mix and match scalars and smaller vectors to reach the target length. Here are some examples of this:

    -

    // Simple 2D vector with 2 scalar values
    +

    // Simple 2D vector with 2 scalar values
    vec2 firstVec  = vec2(2.0, 1.0);
    // A 4D vector using 2 scalars and a vec2 create the 4 values
    vec4 secondVec = vec4(1.0, firstVec, 0.0);
    // A 3D vector using 1 component of a vec4 plus a vec2 to create the 3 values
    vec3 thirdVec  = vec3(secondVec.x, firstVec);

    We can also assign them another vector of the same length (or swizzle the vector until it has the proper length, but we'll explain that in a moment):

    -

    vec4 firstVec = vec4(0.0, 1.0, 2.0, 3.0);
    +

    vec4 firstVec = vec4(0.0, 1.0, 2.0, 3.0);
    vec4 secondVec = firstVec;
    vec3 thirdVec  = secondVec.xyz;
    vec2 fourthVec = thirdVec.zx;

    When accessing vector components in GLSL, we have a few options. The most basic one is to treat the vector as an array and access the components using square brackets, like this:

    -

    vec4 myVec;
    +

    vec4 myVec;
    myVec[0] = 0.0;
    myVec[1] = 1.0;
    myVec[2] = 2.0;
    myVec[3] = 3.0;

    However, there is another way to access the components with the following syntax:

    -

    vec4 myVec;
    +

    vec4 myVec;
    myVec.x = 0.0;
    myVec.y = 1.0;

    -

    This uses the component names inside the vector to access them. You can use x, y, z, or w, to get the first, second, third, or fourth components, respectively. We refer to this method as swizzling because the following syntax is also valid:

    -

    vec4 firstVec;
    +

    This uses the component names inside the vector to access them. You can use x, y, z, or w, to get the first, second, third, or fourth components, respectively. We refer to this method as swizzling because the following syntax is also valid:

    +

    vec4 firstVec;
    vec3 secondVec = firstVec.xyz;
    vec2 thirdVec  = secondVec.zy;
    vec4 fourthVec = thirdVec.yxxy;

    -

    As you can see, we can use any combination of up to four letters to create a vector of that length. We cannot attempt to access a component that would be out of bounds (for example, trying to access w in secondVec or thirdVec, since they don’t have a fourth component). Also, we can repeat letters and use them in any order, as long as the vector variable it’s being assigned to is the same size as the number of letters used.

    -

    For obvious reasons, when using swizzle to set component values, you can’t use the same component twice. For example, the below is not valid as you are trying to set the same component to two different values:

    -

    myVec.xx = vec2(2.0, 3.0);

    -

    Last, we have been using xyzw as our swizzle mask, which is usually the case when dealing with positions. There are two more sets of masks you can use: rgba (used for colors), or stpq (used for texture coordinates). Internally, there is no difference between these masks, and we only use them to make the code clearer as to what the vector represents in that instance. Also, we can’t combine swizzle masks in the same operation, so this is invalid:

    -

    myVec = otherVec.ybp;

    +

    As you can see, we can use any combination of up to four letters to create a vector of that length. We cannot attempt to access a component that would be out of bounds (for example, trying to access w in secondVec or thirdVec, since they don't have a fourth component). Also, we can repeat letters and use them in any order, as long as the vector variable it's being assigned to is the same size as the number of letters used.

    +

    For obvious reasons, when using swizzle to set component values, you can't use the same component twice. For example, the below is not valid as you are trying to set the same component to two different values:

    +

    myVec.xx = vec2(2.0, 3.0);

    +

    Last, we have been using xyzw as our swizzle mask, which is usually the case when dealing with positions. There are two more sets of masks you can use: rgba (used for colors), or stpq (used for texture coordinates). Internally, there is no difference between these masks, and we only use them to make the code clearer as to what the vector represents in that instance. Also, we can't combine swizzle masks in the same operation, so this is invalid:

    +

    myVec = otherVec.ybp;

    Those were a lot of definitions and information, but knowing these things is necessary to understand shaders themselves.

     

    Creating A Shader

    -

    When you create a shader in GameMaker, it will open two files for you: a vertex shader (.vsh) and a fragment shader (.fsh). This is the most basic shader you can make, which takes a sprite, reads the texture, and colors each pixel with that color. If you specify vertex colors when drawing, those colors will blend with the texture.

    -

    Let’s go through the code for a newly created shader asset and analyze it, starting with the vertex shader.

    -

    // Passthrough Vertex Shader
    +

    When you create a shader in GameMaker, it will open two files for you: a vertex shader (.vsh) and a fragment shader (.fsh). This is the most basic shader you can make, which takes a sprite, reads the texture, and colors each pixel with that color. If you specify vertex colors when drawing, those colors will blend with the texture.

    +

    Let's go through the code for a newly created shader asset and analyze it, starting with the vertex shader.

    +

    // Passthrough Vertex Shader
    attribute vec3 in_Position;                  // (x,y,z)
    //attribute vec3 in_Normal;                  // (x,y,z)     unused in this shader.
    attribute vec4 in_Colour;                    // (r,g,b,a)
    @@ -95,15 +95,15 @@

    Creating A Shader

        v_vTexcoord = in_TextureCoord;
    }

    -

    Outside of the main function, we see some variable declarations and their qualifiers. The attributes are given to us by GameMaker. The varying ones are created by the user to pass that information over to the fragment shader. Inside the main function, we have the calculations to find the screen position of the vertex:

    +

    Outside of the main function, we see some variable declarations and their qualifiers. The attributes are given to us by GameMaker. The varying ones are created by the user to pass that information over to the fragment shader. Inside the main function, we have the calculations to find the screen position of the vertex:

      -
    • First, we create a vec4 and initialize it with the components of the position, adding one as the fourth component. In linear algebra, the convention is that we add a one to the fourth component if the vector is representing a point, or a zero if it represents an actual vector.
    • -
    • Next, we need to add this fourth component to multiply it with the MATRIX_WORLD_VIEW_PROJECTION matrix, which is a 4x4 matrix. This multiplication will project the world position of the vertex into screen coordinates.
    • -
    • Finally we pass the vertex color and texture coordinate to the fragment shader through our varying variables.
    • +
    • First, we create a vec4 and initialize it with the components of the position, adding one as the fourth component. In linear algebra, the convention is that we add a one to the fourth component if the vector is representing a point, or a zero if it represents an actual vector.
    • +
    • Next, we need to add this fourth component to multiply it with the MATRIX_WORLD_VIEW_PROJECTION matrix, which is a 4x4 matrix. This multiplication will project the local position of the vertex into screen coordinates.
    • +
    • Finally, we pass the vertex color and texture coordinate to the fragment shader through our varying variables.

    This shader should be left alone if you are not planning to play with vertex positions and it will not be used in any of the examples given below because all the effects shown will be created using the fragment shader.

    -

    Let’s take a quick look at the fragment shader now:

    -

    // Passthrough Fragment Shader
    +

    Let's take a quick look at the fragment shader now:

    +

    // Passthrough Fragment Shader
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;

    @@ -112,29 +112,29 @@

    Creating A Shader

        gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
    }

    -

    As explained before, the idea behind a fragment shader is to return the color of the current pixel. This is done by assigning the variable gl_FragColor the final color value. The texture2D function takes a texture and a vec2 with the UV coordinates you want to check in that texture, which returns a vec4 with the color. In the pass through shader, all we are doing is grabbing the color of the texture in the coordinate of this pixel and multiplying it by the color of the vertex associated with this pixel.

    +

    As explained before, the idea behind a fragment shader is to return the color of the current pixel. This is done by assigning the variable gl_FragColor the final color value. The texture2D function takes a texture and a vec2 with the UV coordinates you want to check in that texture, which returns a vec4 with the color. In the passthrough shader, all we are doing is grabbing the color of the texture at the coordinate of this pixel and multiplying it by the color of the vertex associated with this pixel.

    Now that we have our first shader, all we have to do to test it is create an object and assign it a sprite, then in the Draw Event of the object you set the shader like this:

    // Draw Event
    shader_set(shdrColorOverlay);
    draw_self();
    shader_reset();

    -

    Every draw call we make between shader_set() and shader_reset() will have the shader applied to it. Here, we are drawing the object sprite with our passthrough shader:

    -

    Drawing Sprite Using Passthough ShaderAs you might have guessed, this does not visually changing anything, as this is a simple pass-through shader. However the sections below outline some simple steps you can take to modify this and change the way the sprite will be drawn. Each of the section shows a different shader that you can create and use in your projects, explaining the steps required to create them and why we are doing things the way we are.

    +

    Every draw call we make between shader_set and shader_reset will have the shader applied to it. Here, we are drawing the object sprite with our passthrough shader:

    +

    Drawing Sprite Using Passthough ShaderAs you might have guessed, this does not visually changing anything, as this is a simple passthrough shader. However, the sections below outline some simple steps you can take to modify this and change the way the sprite will be drawn. Each of the sections shows a different shader that you can create and use in your projects, explaining the steps required to create them and why we are doing things the way we are.

     

    Colour Overlay Shader

    -

    We can edit the base shader now to do something different. We'll not be touching the vertex shader part, and only editing the fragment shader, and to start with we'll do a very simple operation, which is to make the shader draw the sprite using the colour red. We'll do this by simply changing the gl_FragColor to be red., like this:

    -

    // Color Overlay Fragment Shader
    +

    We can edit the base shader now to do something different. We'll not be touching the vertex shader part, and only editing the fragment shader, and to start with we'll do a very simple operation, which is to make the shader draw the sprite using the colour red. We'll do this by simply changing the gl_FragColor to be red, like this:

    +

    // Color Overlay Fragment Shader
    void main()
    {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }

    This will give us the following result:

    -

    Initial Colour Overlay BlockNot exactly what we expected! What we need to remember is that every sprite is ultimately a rectangle, so unless we consider transparency - which we haven't - this is the result we’ll get.

    -

     In the image above, the rectangle changes size because the base sprite has had the "empty" space around it cropped automatically when it was placed on the texture page by GameMaker, so each animation frame the triangles that make it up are different sizes to fit the cropped size of the frame. If you disable this option, then you'd simply have a motionless red square on the screen.

    -

    Above we mentioned the texture2D function, and we'll use that to grab the color at the pixel we are working on and get the transparency from it. The return value of is texture2D is a vec4, where the components are the red, green, blue, and alpha, in that order. We can access the alpha channel either by putting a period followed by an a or a w after the variable name. This corresponds to RGBA and XYZW, respectively.

    -

    Here’s the updated code:

    -

    // Color Overlay Fragment Shader
    +

    Initial Colour Overlay BlockNot exactly what we expected! What we need to remember is that every sprite is ultimately a rectangle, so unless we consider transparency - which we haven't - this is the result we'll get.

    +

     In the image above, the rectangle changes size because the base sprite has had the "empty" space around it cropped automatically when it was placed on the texture page by GameMaker, so each animation frame the triangles that make it up are different sizes to fit the cropped size of the frame. If you disable this option, then you'd simply have a motionless red square on the screen.

    +

    Above we mentioned the texture2D function, and we'll use that to grab the color at the pixel we are working on and get the transparency from it. The return value of texture2D is a vec4, where the components are the red, green, blue, and alpha, in that order. We can access the alpha channel either by putting a period followed by an a or a w after the variable name. This corresponds to RGBA and XYZW, respectively.

    +

    Here's the updated code:

    +

    // Color Overlay Fragment Shader
    varying vec2 v_vTexcoord;

    void main()
    @@ -143,21 +143,21 @@

    Creating A Shader

        gl_FragColor = vec4(1.0, 0.0, 0.0, texColor.a);
    }

    -

    We are now assigning a new vec4 to gl_FragColor, where the red channel is maxed, the green, and blue channels are zero, and the alpha channel is the same as the original texture. The output looks like this:

    -

    Overlay Shader Making Sprite RedNow that’s what we were after! We have replaced the color of every pixel with red, but have kept the alpha channel intact.

    -

    Having to change the shader each time we want to use a different color isn’t a good idea, especially since we’d need to have a separate shader for each color we want. Instead, we will pass the color information to the shader using a uniform. To do this, we first need to get a pointer to the uniform. We will do this in the Create Event of our object that has the sprite by adding:

    +

    We are now assigning a new vec4 to gl_FragColor, where the red channel is maxed, the green and blue channels are zero, and the alpha channel is the same as the original texture. The output looks like this:

    +

    Overlay Shader Making Sprite RedNow that's what we were after! We have replaced the color of every pixel with red, but have kept the alpha channel intact.

    +

    Having to change the shader each time we want to use a different color isn't a good idea, especially since we'd need to have a separate shader for each color we want. Instead, we will pass the color information to the shader using a uniform. To do this, we first need to get a pointer to the uniform. We will do this in the Create Event of our object that has the sprite by adding:

    // Create Event
    _uniColor = shader_get_uniform(shdrColorOverlay, "u_colour");
    _color    = [1.0, 1.0, 0.0, 1.0];

    -

    All we need to do is call shader_get_uniform() to get a pointer to the uniform. The parameters we need to pass are the shader asset name (without quotation because we want to pass the ID that GameMaker generates for us) and the name of the uniform variable inside of the shader, this time as a string. This name needs to match exactly the one inside the shader code for it to work. We have also added a colour variable so we can change it at runtime and have it remember our changes.

    -

    Now the code in our draw event will change slightly to pass the uniform variable.

    +

    All we need to do is call shader_get_uniform to get a pointer to the uniform. The parameters we need to pass are the shader asset name (without quotation because we want to pass the ID that GameMaker generates for us) and the name of the uniform variable inside of the shader, this time as a string. This name needs to match exactly the one inside the shader code for it to work. We have also added a colour variable so we can change it at runtime and have it remember our changes.

    +

    Now the code in our Draw event will change slightly to pass the uniform variable.

    // Draw Event
    shader_set(shdrColorOverlay);
    shader_set_uniform_f_array(_uniColor, _color);
    draw_self();
    shader_reset();

    -

    It’s the same code as before, but before we draw anything, we need to pass all the uniform values to the shader. In this case, we are passing the color as an array of floats. As for the shader, we will change it to include the uniform and use it, so it becomes:

    -

    // Color Overlay Fragment Shader
    +

    It's the same code as before, but before we draw anything, we need to pass all the uniform values to the shader. In this case, we are passing the color as an array of floats. As for the shader, we will change it to include the uniform and use it, so it becomes:

    +

    // Color Overlay Fragment Shader
    varying vec2 v_vTexcoord;
    uniform vec4 u_colour;
    void main()
    @@ -165,15 +165,15 @@

    Creating A Shader

        vec4 texColor = texture2D(gm_BaseTexture, v_vTexcoord);
        gl_FragColor = vec4(u_colour.rgb, texColor.a);
    }

    -

    We declare a variable with the same name as in the create shader (u_colour) and we pass it as the first three components of the gl_FragColor vector, taking advantage of swizzling. If we compile again, we should see this:

    -

    Overlay Shader Making Sprite YellowNow the shader is much more useful and reusable. It’s up to you to add more functionality if you need it to set the color (using the variable _color) during runtime.

    +

    We declare a variable with the same name as in the create shader (u_colour) and we pass it as the first three components of the gl_FragColor vector, taking advantage of swizzling. If we compile again, we should see this:

    +

    Overlay Shader Making Sprite YellowNow the shader is much more useful and reusable. It's up to you to add more functionality if you need it to set the color (using the variable _color) during runtime.

     

    Black And White Shader

    Making a black and white shader is a great way to learn more about how shaders work, and a lot of beginners start by trying to do this, since conceptually it's quite simple: get every pixel and assign it a shade of gray. But is it simple? Not quite...

    -

    When using RGB colour, if all three components are the same value, then we get a gray tone. The naïve approach to creating a shader to use this idea would be to add all three color channels (red, green, and blue) and then divide it by three. After that you'd assigned the value to all three channels, thus creating a gray tone. Here’s what that fragment shader looks like:

    -

    // Black and white fragment shader
    +

    When using RGB colour, if all three components are the same value, then we get a gray tone. The naïve approach to creating a shader to use this idea would be to add all three color channels (red, green, and blue) and then divide it by three. After that you'd assigned the value to all three channels, thus creating a gray tone. Here's what that fragment shader looks like:

    +

    // Black and white fragment shader
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;

    @@ -184,15 +184,15 @@

    Creating A Shader

        gl_FragColor = v_vColour * vec4(gray, gray, gray, texColor.a);
    }

    -

    One thing you might have noticed is that in the gl_FragColor code, we're multiplying the vec4 with something called v_vColour. This is a variable passed by the vertex shader which tells us the color of the vertex associated with this pixel. It’s always a good idea to multiply your final calculated color with the vertex color. In most cases, it won’t do anything, but if you changed the vertex color in GML, this will reflect that (by using functions such as draw_sprite_ext() or draw_sprite_general() to change the image_blend).

    -

    As for the draw event, it’s quite simple since we don’t have a uniform to pass in:

    +

    One thing you might have noticed is that in the gl_FragColor code, we're multiplying the vec4 with something called v_vColour. This is a variable passed by the vertex shader which tells us the color of the vertex associated with this pixel. It's always a good idea to multiply your final calculated color with the vertex color. In most cases, it won't do anything, but if you changed the vertex color in GML, this will reflect that (by using functions such as draw_sprite_ext or draw_sprite_general to change the image_blend).

    +

    As for the Draw event, it's quite simple since we don't have a uniform to pass in:

    // Draw Event
    shader_set(shdrBlackAndWhite);
    draw_self();
    shader_reset();

    -

    Let’s compile and see what we got.

    -

    Black And White ShaderThis looks great already, right? Well, yes and no... there is a solution that is more “correct”, since instead of adding the components and dividing by three, we multiply each component by the standard NTSC values for black and white. Here’s the modified fragment shader code:

    -

    // Black and white fragment shader
    +

    Let's compile and see what we got.

    +

    Black And White ShaderThis looks great already, right? Well, yes and no... there is a solution that is more "correct", since instead of adding the components and dividing by three, we multiply each component by the standard NTSC values for black and white. Here's the modified fragment shader code:

    +

    // Black and white fragment shader
    varying vec2 v_vTexcoord;

    void main()
    @@ -202,18 +202,18 @@

    Creating A Shader

        gl_FragColor = vec4(gray, gray, gray, texColor.a);
    }

    -

    We use the dot product as a shorthand for multiplying each component of texColor with the correct weights and then add them together. If you are unfamiliar with the dot product, this is essentially what’s happening:

    -

    float gray = (texColor.r * 0.299) + (texColor.g * 0.587) + (texColor.b * 0.114);

    -

    In the end, it looks very similar, but it’s technically more correct.

    +

    We use the dot product as a shorthand for multiplying each component of texColor with the correct weights and then add them together. If you are unfamiliar with the dot product, this is essentially what's happening:

    +

    float gray = (texColor.r * 0.299) + (texColor.g * 0.587) + (texColor.b * 0.114);

    +

    In the end, it looks very similar, but it's technically more correct.

    Corrected Black And White Shader

     

    Rainbow Shader

    Our final shader example is a fun one and can be used to add life to text and buttons and other things. We'll start simple and add functionality gradually since this shader is highly customizable. There's quite a lot to cover for this one, so if you feel a bit lost or confused, please go back and re-read some of the sections above.

    -

    The first thing we want to do is color pixels with every hue, depending on the pixel’s horizontal position. The way to do this is to set the x position to be the hue and then convert from HSV (hue, saturation, brightness) format to RGB (red, green, and blue) format. For this, we will need to write a helper function in our fragment shader that takes HSV values and returns an RGB vector. We will use a single function which does this without the need for any if statements, as using conditionals in shader code makes shaders very slow, and should be avoided.

    -

    Here’s what the shader looks like at this stage:

    -

    // Fragment Shader
    +

    The first thing we want to do is color pixels with every hue, depending on the pixel's horizontal position. The way to do this is to set the x position to be the hue and then convert from HSV (hue, saturation, brightness) format to RGB (red, green, and blue) format. For this, we will need to write a helper function in our fragment shader that takes HSV values and returns an RGB vector. We will use a single function which does this without the need for any if statements, as using conditionals in shader code makes shaders very slow, and should be avoided.

    +

    Here's what the shader looks like at this stage:

    +

    // Fragment Shader
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;

    @@ -231,26 +231,26 @@

    Creating A Shader

        gl_FragColor = v_vColour * vec4(hsv2rgb(col), alpha);
    }

    -

    There's a bit more going on here than in the previous examples, but most of it should be fairly obvious to you now. First, there’s our hsv2rgb function, which takes a vec3 with our HSV colour and returns another vec3 with our RGB conversion. In the main function, we start by creating our HSV colour, where the hue is our x position, and we’ll leave the saturation and brightness as 1.0 for now. Then, we get the alpha from the texture so it only colors our sprite character and not the entire sprite rectangle (as we did in the colour overlay example, above). Lastly, we set our Fragment color to be our HSV color converted to RGB with the alpha, multiplied by the vertex color (good practice to do this always).

    +

    There's a bit more going on here than in the previous examples, but most of it should be fairly obvious to you now. First, there's our hsv2rgb function, which takes a vec3 with our HSV colour and returns another vec3 with our RGB conversion. In the main function, we start by creating our HSV colour, where the hue is our x position, and we'll leave the saturation and brightness as 1.0 for now. Then, we get the alpha from the texture so it only colors our sprite character and not the entire sprite rectangle (as we did in the colour overlay example, above). Lastly, we set our Fragment color to be our HSV color converted to RGB with the alpha, multiplied by the vertex color (good practice to do this always).

    As for our draw code, it is trivial at the moment:

    // Draw Event
    shader_set(shdrRainbow);
    draw_self();
    shader_reset();

    -

    Let’s check out what we got:

    -

    Initial Rainbow ShaderWe are close to what we want, but there’s an issue: we are not seeing all the colors at once in every frame of the animation, and the colors seem to change randomly. The reason is that we assumed that v_vTexcoord gave us the coordinates of the sprite, starting at the top-left corner (0,0) and ending in the bottom right corner (1,1), which is standard in shaders. However, for optimization, GameMaker stuffs as many textures together as it can fit in what is called a texture page, and because of that, this is how our texture actually looks:

    -

    As explained above, v_vTexcoord gives us the absolute coordinates of the sprite within this entire texture page, but what we want is a value from 0.0 to 1.0 that only covers our current sprite. This process is called normalizing (getting a value and translating it to a 0 to 1 range). To normalize our horizontal values, we need to know the values of x0 and x1 in the picture above. Luckily, GameMaker has a function that gives us the location of every corner in our sprite within the texture page. First, we need to go to the Create Event and create a uniform to pass this data over to the shader:

    +

    Let's check out what we got:

    +

    Initial Rainbow ShaderWe are close to what we want, but there's an issue: we are not seeing all the colors at once in every frame of the animation, and the colors seem to change randomly. The reason is that we assumed that v_vTexcoord gave us the coordinates of the sprite, starting at the top-left corner (0, 0) and ending in the bottom-right corner (1, 1), which is standard in shaders. However, for optimization, GameMaker stuffs as many textures together as it can fit in what is called a texture page, and because of that, this is how our texture actually looks:

    +

    As explained above, v_vTexcoord gives us the absolute coordinates of the sprite within this entire texture page, but what we want is a value from 0.0 to 1.0 that only covers our current sprite. This process is called normalizing (getting a value and translating it to a 0 to 1 range). To normalize our horizontal values, we need to know the values of x0 and x1 in the picture above. Luckily, GameMaker has a function that gives us the location of every corner in our sprite within the texture page. First, we need to go to the Create Event and create a uniform to pass this data over to the shader:

    // Create Event
    _uniUV = shader_get_uniform(shdrRainbow, "u_uv");

    -

    And we modify the draw event to get the values and then pass them to the shader:

    +

    And we modify the Draw event to get the values and then pass them to the shader:

    // Draw Event
    shader_set(shdrRainbow);
    var uv = sprite_get_uvs(sprite_index, image_index);
    shader_set_uniform_f(_uniUV, uv[0], uv[2]);
    draw_self();
    shader_reset();

    -

    The function sprite_get_uvs() takes a sprite and an index, and it returns an array with tons of information, such as the coordinates for each corner, how many pixels were cropped to optimize it, etc. We are interested in two of those values: the left and right coordinates of the sprite, which are stored in uv[0] and uv[2] respectively. In the fragment shader, we will use those values now to calculate the normalized horizontal position like this:

    -

    // Fragment Shader
    +

    The function sprite_get_uvs takes a sprite and an index, and it returns an array with tons of information, such as the coordinates for each corner, how many pixels were cropped to optimize it, etc. We are interested in two of those values: the left and right coordinates of the sprite, which are stored in uv[0] and uv[2] respectively. In the fragment shader, we will use those values now to calculate the normalized horizontal position like this:

    +

    // Fragment Shader
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;

    @@ -271,7 +271,7 @@

    Creating A Shader

        gl_FragColor = v_vColour * vec4(hsv2rgb(col), alpha);
    }

    -

    Here we add the uniform variable at the top of the file with the same name we used in the Create Event. Next, we calculate the normalized horizontal position by translating our current x coordinate to the origin ( v_vTexcoord.x - u_uv[0]) and then we divide it by the width of the sprite to make the range from 0 to 1 (u_uv[1] - u_uv[0]).

    +

    Here we add the uniform variable at the top of the file with the same name we used in the Create Event. Next, we calculate the normalized horizontal position by translating our current x coordinate to the origin ( v_vTexcoord.x - u_uv[0]) and then we divide it by the width of the sprite to make the range from 0 to 1 (u_uv[1] - u_uv[0]).

    The result is:

    Rainbow Overlay Shader ImprovedThere we go! This is exactly what we wanted. We can see every color of the spectrum inside our sprite.

    You might be happy with that, but we can have some more fun with this shader. What if we added an offset to the colors based around time to produce movement? To do this, we will need two extra variables for speed and time. We will also need two more uniforms, one for each of the new variables, so the Create Event becomes:

    @@ -284,7 +284,7 @@

    Creating A Shader

    We also need to increase the time every frame, so in the Step Event we add:

    // Step Event
    _time += 1 / game_get_speed(gamespeed_fps);

    -

    Let’s go to the draw event now to send these uniforms to the shader:

    +

    Let's go to the Draw event now to send these uniforms to the shader:

    // Draw Event
    shader_set(shdrRainbow);
    var uv = sprite_get_uvs(sprite_index, image_index);
    @@ -294,7 +294,7 @@

    Creating A Shader

    draw_self();
    shader_reset();

    Finally, we'll go back to our shader to actually use these variables now. What we will do is multiply the speed with the time and add it to the position, like so:

    -

    // Fragment Shader
    +

    // Fragment Shader
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;

    @@ -305,7 +305,7 @@

    Creating A Shader

    vec3 hsv2rgb(vec3 c) 
    {
        vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    -   vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    +     vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
        return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
    }

    @@ -318,7 +318,7 @@

    Creating A Shader

    }

    If you did everything correctly, you should be seeing something like this:

    -

    Rainbow Shader Overlay Moving With TimeTo finish this shader, we will add a few more uniforms to customize it even further. The first two are to control the saturation and brightness. The next one we'll call "section" and its function is to allow the user to pass a number between zero and one to determine what percentage of the entire spectrum we see at a time. Last, we will add a variable called "mix", which will specify how much we want to mix our shader color with the original texture color (1.0 is all rainbow, 0.0 is all texture). As always, let’s start by adding the variables to the Create Event:

    +

    Rainbow Shader Overlay Moving With TimeTo finish this shader, we will add a few more uniforms to customize it even further. The first two are to control the saturation and brightness. The next one we'll call "section" and its function is to allow the user to pass a number between zero and one to determine what percentage of the entire spectrum we see at a time. Last, we will add a variable called _mix, which will specify how much we want to mix our shader color with the original texture color (1.0 is all rainbow, 0.0 is all texture). As always, let's start by adding the variables to the Create Event:

    // Create Event
    _uniUV         = shader_get_uniform(shdrRainbow, "u_uv");
    _uniTime       = shader_get_uniform(shdrRainbow, "u_time");
    @@ -335,7 +335,7 @@

    Creating A Shader

    _brightness = 0.8;
    _mix = 0.5;

    -

    Our draw event changes to include these uniforms like this:

    +

    Our Draw event changes to include these uniforms like this:

    // Draw Event
    shader_set(shdrRainbow);
    var uv = sprite_get_uvs(sprite_index, image_index);
    @@ -349,7 +349,7 @@

    Creating A Shader

    draw_self();
    shader_reset();

    As for the shader, we need to pass the saturation and brightness to the color, which will affect the color generated by our helper function. The section needs to be multiplied by our position to reduce the range. We will also grab the entire texture color, so we can calculate our final color by mixing the texture color with the RGB conversion of our color. The last parameter of the mix function determines how much of the second color we want to add. This is our final shader code:

    -

    // Fragment Shader
    +

    // Fragment Shader
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;

    @@ -359,7 +359,7 @@

    Creating A Shader

    uniform float u_saturation;
    uniform float u_brightness;
    uniform float u_section;
    - Uniform float u_mix;
    + uniform float u_mix;

    vec3 hsv2rgb(vec3 c) 
    {
    @@ -374,7 +374,7 @@

    Creating A Shader

        vec4 texColor = texture2D(gm_BaseTexture, v_vTexcoord);
        
        vec3 col = vec3(u_section * ((u_time * u_speed) + pos), u_saturation, u_brightness);
    -   vec4 finalCol = mix(texColor, vec4(hsv2rgb(col), texColor.a), u_mix);
    +     vec4 finalCol = mix(texColor, vec4(hsv2rgb(col), texColor.a), u_mix);
        
        gl_FragColor = v_vColour * finalCol;
    } @@ -384,17 +384,17 @@

    Creating A Shader

     

     

    -

    That's the end of this short guide and you should now have a better understanding of how shaders work and some of the uses they can be put to. You should take your time to play with the shaders you've created following this guide, and try to experiment with them do other things - how about creating a blur shader, or a shader that makes a gameboy-style monochrome screen? - since shaders are an incredibly powerful tool for adding visual complexity and style to your games.

    +

    That's the end of this short guide. You should now have a better understanding of how shaders work and some of the uses they can be put to. You should take your time to play with the shaders you've created following this guide, and try to experiment with them to do other things - how about creating a blur shader, or a shader that makes a Game Boy-style monochrome screen? - since shaders are an incredibly powerful tool for adding visual complexity and style to your games.

    We would like to thank Alejandro Hitti and Amazon for permitting us to reproduce this guide. You can find the original version on the Amazon Developer Blog.

     

    Welcome to the GameMaker user manual! This document is divided into three parts with the aim of getting you introduced to the interface and basic workings of GameMaker and general programming, before going on to more advanced usage and the functions available through our proprietary programming language GML (GameMaker Language).

    To ease you into things we have created a handy Quick Start Guide, and even if you are familiar with other game creation tools we recommend that you start there to get an overview of the way that GameMaker works. You'll find GameMaker to be easy and intuitive to use, and whatever your skill level, you will soon be making games you've always dreamt of.

    -

     Due to the modular nature of GameMaker there are certain things that are not included in this user manual, in particular those aspects of setting up and connecting the different devices that can be supported. For up-to-date information and troubleshooting hints and tips related to the different target platforms, please see the GameMaker Wiki and GameMaker Help Center (for legacy information).

    +

     Due to the modular nature of GameMaker there are certain things that are not included in this user manual, in particular those aspects of setting up and connecting the different devices that can be supported. For up-to-date information and troubleshooting hints and tips related to the different target platforms, please see the GameMaker Wiki and GameMaker Help Center (for legacy information and help articles).

     Returning to the manual? Here are some handy shortcuts:

      @@ -61,11 +62,11 @@

      Scripting Reference

      diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Assets_And_Tags/asset_get_index.htm b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Assets_And_Tags/asset_get_index.htm index f9f9e3d44..a6662dc52 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Assets_And_Tags/asset_get_index.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Assets_And_Tags/asset_get_index.htm @@ -16,8 +16,9 @@

      asset_get_index

      -

      This function gets the handle for a game asset from its name.

      -

      If the asset is not found, the function will return a value of -1, otherwise it will return the handle for the asset being checked. This handle can then be used in other functions as you would any other handle, like sprite_index or path_index, for example.

      +

      This function gets the handle for an Asset from its name.

      +

       If an Asset handle is passed, its index number is returned (similar to passing a handle into real). 

      +

      If the asset is not found, the function will return a value of -1. This handle can then be used in other functions as you would any other handle, like sprite_index or path_index, for example.

      Usage Notes

      • Although this function can be used to reference assets from strings (see the first example below), you should always make sure that the asset exists before using it. Otherwise, you may get errors that will crash your game.
      • @@ -35,7 +36,7 @@

        Syntax:

        name - String + String or Asset The name of the game asset to get the handle of (a string). @@ -73,7 +74,7 @@

        Example 2: "MarkTagAsUsed" pragma

    -
    © Copyright YoYo Games Ltd. 2025 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2026 All Rights Reserved
    + \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio_Emitters/audio_emitter_free.htm b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio_Emitters/audio_emitter_free.htm index 564a85b94..bafa048e8 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio_Emitters/audio_emitter_free.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Audio/Audio_Emitters/audio_emitter_free.htm @@ -4,7 +4,7 @@ audio_emitter_free - + @@ -15,7 +15,9 @@

    audio_emitter_free

    -

    With this function you can remove the given emitter from memory. This should always be done whenever the emitter is not going to be used further in the room or the game, ie: in the Destroy Event of the instance or in the Room End Event, otherwise you may end up with a memory leak that will slow down and eventually crash your game.

    +

    With this function you can remove the given emitter from memory. This should always be done whenever the emitter is not going to be used further in the room or the game, i.e.: in the Clean Up Event of the instance or in the Room End Event, otherwise you may end up with a memory leak that will slow down and eventually crash your game.

    +

    Sound instances currently being played on the emitter are force-stopped.

    +

     

    Syntax:

    audio_emitter_free(emitter)

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

    Syntax:

    emitter - Audio Emitter ID + Audio Emitter ID The index of the emitter to free. @@ -38,12 +40,12 @@

    Returns:

    N/A

     

    Example:

    -

    if (lives == 0)
    +

    if (lives == 0)
    {
        audio_emitter_free(s_emit);
    -     room_goto(rm_Menu);
    +     room_goto(rm_menu);
    }

    -

    The above code checks the value of the global variable "lives" and if it returns 0, it will destroy the emitter indexed in the variable "s_emit" and then go to the room indexed in the variable "rm_Menu".

    +

    The above code checks the value of the global variable "lives" and if it returns 0, it will destroy the emitter indexed in the variable "s_emit" and then go to the room indexed in the variable "rm_menu".

     

     

     

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

    Example:

    Next: audio_play_sound_on
    -
    © Copyright YoYo Games Ltd. 2022 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2026 All Rights Reserved
    \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Rooms/UI_Layers/layer_get_flexpanel_node.htm b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Rooms/UI_Layers/layer_get_flexpanel_node.htm index 55b985eba..ea4a14635 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Rooms/UI_Layers/layer_get_flexpanel_node.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Asset_Management/Rooms/UI_Layers/layer_get_flexpanel_node.htm @@ -15,11 +15,11 @@

    layer_get_flexpanel_node

    -

    This function takes a Layer handle or the name of a layer as a string. If the layer is a UI layer, it will return the Flex Panel Node for the root of the UI layer, otherwise it will return undefined.

    +

    This function takes the name of a layer as a string. If the layer is a UI layer, it will return the Flex Panel Node for the root of the UI layer, otherwise it will return undefined.

     Use flexpanel_node_get_struct to return the struct for a node. The contents of the returned struct are defined here: Flex Panel Struct Members

     

    Syntax:

    -

    layer_get_flexpanel_node(layer_id_or_name)

    +

    layer_get_flexpanel_node(layer_name)

    @@ -33,15 +33,15 @@

    Syntax:

    - - - + + +
    Description
    layer_id_or_nameLayer or StringThe layer to get the Flex Panel Node forlayer_nameStringThe name of the layer to get the Flex Panel Node for

     

    Returns:

    -

    Flex Panel Node or undefined

    +

    Flex Panel Node or undefined

     

    Example:

    var _ui_layer = layer_get_flexpanel_node("UILayer_1");
    @@ -60,7 +60,7 @@

    Example:

    Next: Layers
    -
    © Copyright YoYo Games Ltd. 2025 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2026 All Rights Reserved

    window_set_max_height

    -

    This function can be used to set a maximum window height for your game. If you enable the window resize option in the Game Options for the target platform, then the player can resize the game window to any size they wish, however by using this function you can limit the maximum height to the size you specify. If you wish to go back to the default behaviour (ie: no minimum), then use a value of -1.

    +

    This function can be used to set a maximum window height for your game. If you enable the window resize option in the Game Options for the target platform, then the player can resize the game window to any size they wish, however by using this function you can limit the maximum height to the size you specify. If you wish to go back to the default behaviour (i.e.: no minimum), then use a value of -1.

     

    Syntax:

    @@ -68,7 +55,7 @@

    Example:

    Next: window_minimise
    -
    © Copyright YoYo Games Ltd. 2024 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2026 All Rights Reserved

    DS Grids

    -

    A DS grid is a data structure that stores information across 2 dimensions. You define the grid by setting its integer width and height, which sets the total number of "cells" within the grid (the width and height multiplied). These cells are then used to hold different data values (real numbers or strings).

    +

    A DS grid is a data structure that stores information across 2 dimensions. You define the grid by setting its integer width and height, which sets the total number of "cells" within the grid (the width and height multiplied). These cells are then used to hold values which can be of any data type (e.g., real numbers or strings).

    DS Grid ExampleThis type of structure allows you to set and retrieve the value of cells in the grid by giving the x and y index of it (which starts with 0 for both the x and the y axis and goes up to the width - 1 and the height -1). But you can also set the value in specific grid regions, add single values, and retrieve the sum, maximum, minimum, and mean value over a given region, making this data structure the most versatile of all those available to you.

    When accessing DS grid data structures, you should always try to use integer values for the cell position, and all non-integer indices will be floored by GameMaker if you do not. If that is not what you require, then you will need to do the rounding yourself previously before passing the index that you wish to check.

    @@ -82,7 +82,7 @@

    MP Grid

    Next: DS Lists
    -
    © Copyright YoYo Games Ltd. 2024 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2026 All Rights Reserved
    -

    ds_grid_add_grid_region

    -

    This function can be used to add all the values of all the cells found within the source area of a grid to the values within the destination grid, as illustrated below:

    -

    DS grid add grid region

    -

    NOTE You can also use this function on the same grid to add values from one region of the grid to those stored in another (see code example below).

    -

    -

    Syntax:

    -

    ds_grid_add_grid_region(index, source, x1, y1, x2, y2, xpos, ypos)

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ArgumentTypeDescription
    indexThe handle of the destination grid.
    sourceThe handle of the source grid.
    x1The left position of the region of cells to copy from the source grid.
    y1The top position of the region of cells to copy from the source grid.
    x2The right position of the region of cells to copy from the source grid.
    y2The bottom position of the region of cells to copy from the source grid.
    xposThe x position on the destination grid to add the source region to.
    yposThe y position on the destination grid to add the source region to.
    -

    -

    Returns:

    -

    -

    -

    Example:

    -

    ds_grid_add_grid_region(grid, grid, 0, 0, 1, 5, 2, 0)

    -

    The above code would copy the region of cells from (0,0) to (1,5) of the DS grid indexed in the variable "grid" and add them to the cells from position (2,0) of the same DS grid .

    -

    -

    -

    - diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Debugging/dbg_text_separator.htm b/Manual/contents/GameMaker_Language/GML_Reference/Debugging/dbg_text_separator.htm index c6bb7345f..036d7d055 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Debugging/dbg_text_separator.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Debugging/dbg_text_separator.htm @@ -9,8 +9,8 @@ - - + + diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Colour_And_Alpha/make_colour_rgb.htm b/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Colour_And_Alpha/make_colour_rgb.htm index e494ee493..2dae07765 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Colour_And_Alpha/make_colour_rgb.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Colour_And_Alpha/make_colour_rgb.htm @@ -62,7 +62,7 @@

    Example:

    Next: merge_colour
    -
    © Copyright YoYo Games Ltd. 2025 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2026 All Rights Reserved
    \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Drawing/GPU_Control/gpu_get_stencil_read_mask.htm b/Manual/contents/GameMaker_Language/GML_Reference/Drawing/GPU_Control/gpu_get_stencil_read_mask.htm index 38c08227e..8083302b8 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Drawing/GPU_Control/gpu_get_stencil_read_mask.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Drawing/GPU_Control/gpu_get_stencil_read_mask.htm @@ -9,8 +9,8 @@ - - + + @@ -34,11 +34,11 @@

    Example:

    diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Textures/texturegroup_add.htm b/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Textures/texturegroup_add.htm index fde4f7b33..02caca295 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Textures/texturegroup_add.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Drawing/Textures/texturegroup_add.htm @@ -15,7 +15,8 @@

    texturegroup_add

    -

    This function adds a new Dynamic Texture Group to the game from the given image file(s) and/or buffer(s) and the sprite information given as a struct.

    +

    This function adds a new Dynamic Texture Group to the game from the given image file(s) and/or buffer(s), using the sprite information given as a struct.

    +

    Arguments

    The first argument is the name of the Texture Group to be created. If a Texture Group with the given name already exists, this will cause a fatal error.

    For the second argument, you may pass either a file name, a buffer or an array containing multiple of these (the array can contain a mix of both). The image file(s) can be any bitmap file format. For file access rules see: Accessing File Areas

    A buffer can contain any file format supported for texture groups: PNG, JPEG, GIF, QOIF, DDS, ASTC, etc., as well as a RAW texture format that can be used with Surfaces. Note that any GPU hardware-compressed texture must be supported on the target for it to work.

    @@ -31,6 +32,7 @@

    texturegroup_add

    +16                      ....               the RGBA data stored as byte per pixel R, G, B, A with row first, width*height pixels

    The image data from a surface can be copied to the buffer at an offset using buffer_get_surface.

    +

    Sprite Data Struct

    The last argument must be a struct or a JSON string providing information on the sprites contained in the new Texture Group. This struct or JSON object must have the following format:

    Struct Format

    @@ -64,16 +66,16 @@

    texturegroup_add

    • xoffset, yoffset: The x and y origin in pixels
    • bbox_left, bbox_right, bbox_top, bbox_bottom: Bounding box values in pixels
    • -
    • bbox_kind: The type of bounding box as a Bounding Box Kind (Shape) Constant
    • +
    • bbox_kind: The type of bounding box as a Bounding Box Kind (Shape) Constant
    • frame_speed: Animation speed
    • -
    • frame_type: Animation speed type of the sprite as a Sprite Speed Constant
    • +
    • frame_type: Animation speed type of the sprite as a Sprite Speed Constant
    • rotated_bounds: Boolean for whether the sprite supports a rotating rectangular collision mask
    • mask: An array of bits for the mask (single frame)
    • masks: An array of arrays containing bits for the masks (per frame)
    • nineslice: A struct describing the Nine Slice information for the sprite, containing the following members:
      • left, right, top, bottom: The edge positions within the sprite
      • -
      • tilemode_left, tilemode_right, tilemode_top, tilemode_bottom, tilemode_centre: The Tile Mode Constant for each edge and the centre
      • +
      • tilemode_left, tilemode_right, tilemode_top, tilemode_bottom, tilemode_centre: The Tile Mode Constant for each edge and the centre
    • messages: An array of structs describing the broadcast messages for this sprite. Each struct contains: @@ -95,7 +97,10 @@

      texturegroup_add

    -

    The Texture Group created can later be deleted using texturegroup_delete.

    +

    Overriding & Deletion

    +

    If any sprite names used in this struct already exist at the time of the call, the original sprites will be overridden.

    +

    The Texture Group can later be deleted using texturegroup_delete. If any sprites were overridden by this Texture Group, they will be restored.

    +

    Notes

     This function is not supported on HTML5.

     The texture will be unloaded after being created and can be loaded with texturegroup_load or when a sprite from it is first drawn.

     Buffers used by a texture group cannot be deleted while the texture group exists. You need to delete the buffers manually and the texture group must be deleted first.

    @@ -221,11 +226,11 @@

    Example 2: Multiple Textures, from Different Sources

    cache_directory

    -

    This function returns the cache directory for your game. Use this directory to store cached data that is not permanently needed for your game.

    +

    This variable holds the path to the cache directory for your game. Use this directory to store cached data that is not permanently needed for your game.

    On some consoles, certain options may need to be enabled for this to hold a valid path.

     

    @@ -26,18 +26,18 @@

    Returns:

    String

     

    Example:

    -

    ini_open(cache_directory + "\cache_ini.ini");

    -

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

    +

    ini_open(cache_directory + "cache_ini.ini");

    +

    This will open an INI file in the cache directory of the game (creating it if it doesn't already exist).

     

     

    program_directory

    -

    This function returns the directory where the game's runner (executable) is stored. However, this may not always be useful, particularly as some devices run the executable from a *.zip file, so this would return that location no matter where the extracted executable is actually running from.

    +

    This variable holds the path to the directory where the game's runner (executable) is stored. However, this may not always be useful, particularly as some devices run the executable from a *.zip file, so this would return that location no matter where the extracted executable is actually running from.

    This is different from working_directory, which stores where the game's files are stored, however by default they are in the same location.

    @@ -39,7 +39,7 @@

    Example:

    Next: cache_directory
    -
    © Copyright YoYo Games Ltd. 2024 All Rights Reserved
    +
    © Copyright YoYo Games Ltd. 2026 All Rights Reserved

    temp_directory

    -

    This function returns the temporary directory created for your game each time it is run.

    +

    This variable holds the path to the temporary directory created for your game each time it is run.

    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.

     

    @@ -26,18 +26,18 @@

    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 doesn't already exist).

     

     

    working_directory

    -

    This returns a path that points to where the game's files are stored.

    -

    In most cases, this is the same as the program_directory, which is the path to the game's runner (executable). However if the game's files happen to be in a different directory than the runner (say you use game_change to use a different working directory or use command line to run a runner in a different location), then this will point to where the game files are, not the runner.

    +

    This variable holds the path to the directory where the game's files are stored.

    +

    In most cases, this is the same as the program_directory, which is the path to the game's runner (executable). However, if the game's files happen to be in a different directory than the runner (say you use game_change to use a different working directory or use command line to run a runner in a different location), then this will point to where the game files are, not the runner.

    It may also be a different directory when testing your project through the IDE, as then the game files and the runner are in different locations as well.

    When using this directory to write out a file, GameMaker will redirect it to the game_save_id location if the file system sandbox does not allow writing to the working directory (this is the default behaviour, which can be disabled in the Game Options for Desktop targets only).

    @@ -31,17 +31,17 @@

    Returns:

     

    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 save area or the program directory depending on the sandbox level.

    +

    This will open an INI file from the working directory of the game (creating it if it doesn't already exist). This could be the save area or the program directory depending on the sandbox level.

     

     

    + + + \ No newline at end of file diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Live_Wallpapers/Live_Wallpapers.htm b/Manual/contents/GameMaker_Language/GML_Reference/Live_Wallpapers/Live_Wallpapers.htm index 140e090b1..53dbd703b 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Live_Wallpapers/Live_Wallpapers.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Live_Wallpapers/Live_Wallpapers.htm @@ -16,7 +16,7 @@

    Live Wallpapers

    This page lists functions for use with the Live Wallpaper functionality.

    -

    For information on how to set these up, see the helpdesk article on GX Live Wallpapers.

    +

    For information on how to set these up, see the helpdesk article on GX Live Wallpapers.

    Functions

    The following functions are given for Live Wallpapers:

      diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Live_Wallpapers/wallpaper_set_subscriptions.htm b/Manual/contents/GameMaker_Language/GML_Reference/Live_Wallpapers/wallpaper_set_subscriptions.htm index 5b6242322..4a9b66dc0 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Live_Wallpapers/wallpaper_set_subscriptions.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Live_Wallpapers/wallpaper_set_subscriptions.htm @@ -16,7 +16,7 @@

      wallpaper_set_subscriptions

      This function subscribes to the given metric(s) from the Companion app. This is used to get real-time system information, and enable mouse input, which is disabled for Live Wallpapers by default.

      -

       See this guide for making a basic Live Wallpaper and (optionally) setting up the Companion app on Windows.

      +

       See this guide for making a basic Live Wallpaper and (optionally) setting up the Companion app on Windows.

       Graphics drivers must be up-to-date on the target computer for GPU metrics to work correctly.

       Each call to this function cancels any previously active subscriptions, so only those included in the last call remain active.

      Arguments

      diff --git a/Manual/contents/GameMaker_Language/GML_Reference/Maths_And_Numbers/Number_Functions/random_set_seed.htm b/Manual/contents/GameMaker_Language/GML_Reference/Maths_And_Numbers/Number_Functions/random_set_seed.htm index fb5e5105b..9c6748c2f 100644 --- a/Manual/contents/GameMaker_Language/GML_Reference/Maths_And_Numbers/Number_Functions/random_set_seed.htm +++ b/Manual/contents/GameMaker_Language/GML_Reference/Maths_And_Numbers/Number_Functions/random_set_seed.htm @@ -17,10 +17,11 @@

      random_set_seed

      This function sets the seed used by GameMaker to generate random numbers.

      To generate a random number GameMaker starts with a random seed number. With this function you can set that seed to a known value and so "force" the outcome of all random events afterwards to be the same every time the program is run. For example, this function can be used in conjunction with random_get_seed to create procedurally generated content and save the results without having huge savegames (you save the seed only, no need for anything else). Should you need truly random results for everything, you should be using the randomise function.

      +

      You can specify any value into the optional second argument fix_range_bug, which uses an alternate function to set the seed that should ensure a higher range of the random state. This should be more accurate in setting the state as the previous behaviour was erroneous and is only kept for legacy purposes.

       While this seed will give consistent results on each target platform, results may vary between platforms due to the different way each target works.

       

      Syntax:

      -

      random_set_seed(val)

      +

      random_set_seed(val, [fix_range_bug])

      @@ -33,6 +34,11 @@

      Syntax:

      + + + + +
      Real The seed to set
      fix_range_bugBoolean  Specify any value to use alternate function to remove range limits

       

      @@ -42,9 +48,9 @@

      Returns:

      Example:

      if (debug)
      {
      -     random_set_seed(1);
      +     random_set_seed(1, true);
      }

      -

      The above code sets the random seed to 1 only if the variable debug is true.

      +

      The above code sets the random seed to 1 only if the variable debug is true, using the newer method to set the seed (by supplying a second argument).

       

       

      -
      © Copyright YoYo Games Ltd. 2025 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2026 All Rights Reserved

      physics_fixture_bind

      This function binds the given fixture to the given target object or instance and returns the ID of the bound fixture.

      -

      Once we have defined our fixture it has to be bound to an instance. This means that its properties are transferred to the selected instance, not the actual fixture itself, so that one fixture can be bound to multiple instances if all are to have the same properties. You can specify an object index for the target and all instances of that object present in the room at the time will receive that fixture's properties (but not any new instances of the object created later), or you can use the special keywords other and all. You can even specify a parent object and all children instances with that parent will also receive the fixture. Once the fixture has been bound to all the instances that you need, it can be deleted if no longer necessary and the instances with that fixture's properties will not be affected and maintain those properties.

      +

      Once we have defined our fixture it has to be bound to an instance. This means that its properties are transferred to the selected instance, not the actual fixture itself, so that one fixture can be bound to multiple instances if all are to have the same properties. You can specify an object index for the target and all instances of that object present in the room at the time will receive that fixture's properties (but not any new instances of the object created later), or you can use the special keywords other and all. You can even specify a parent object and all instances that are instances of children of that parent object will also receive the fixture. Once the fixture has been bound to all the instances that you need, it can be deleted if no longer necessary and the instances with that fixture's properties will not be affected and maintain those properties.

      The fixture will be bound to the instance with the centre of mass being positioned at the origin of the instance, and polygon fixtures are bound based on the position of the points relative to the origin. If you require your fixture to be bound to a point other than the origin then you should be using physics_fixture_bind_ext.

      -

      Physics fixture binding exampleThe function will also return a unique "id" value for the bound fixture (not the fixture itself) which can then be used to remove ("un-bind") the physics properties from the instance using the function physics_remove_fixture. This permits you to add and remove physical properties from an instance without destroying and re-creating objects.

      +

      Physics fixture binding exampleThe function will also return a unique "id" value for the bound fixture (not the fixture itself) which can then be used to remove ("un-bind") the physics properties from the instance using the function physics_remove_fixture. This permits you to add and remove physical properties from an instance without destroying and re-creating instances.

       Fixtures should be deleted when no longer needed as failure to do so may cause a memory leak which will slow down and eventually crash your game.

       

      Syntax:

      @@ -44,17 +44,20 @@

      Syntax:

       

      Returns:

      -

      Real

      +

      Physics Bound Fixture ID

       

      Example:

      -

      var _fix, _inst;
      - _fix = physics_fixture_create();
      +

      Create Event

      +

      var _fix = physics_fixture_create();
      physics_fixture_set_circle_shape(_fix, 16);
      physics_fixture_set_density(_fix, 1.0);
      - inst = instance_create_layer(x, y, "Instances", genericBodyObject);
      - my_fix = physics_fixture_bind(_fix, inst);
      + my_bound_fix = physics_fixture_bind(_fix, id);
      physics_fixture_delete(_fix);

      -

      The code above will create a fixture and assign its index to the temporary variable _fix. It then defines the shape and density of the fixture before binding it to the instance that was created with the index for the bound fixture stored in the variable my_fix. Finally, the fixture is deleted to prevent memory leaks as it is no longer needed.

      +

      Clean Up Event

      +

      physics_remove_fixture(id, my_bound_fix);

      +

      The code above shows how to bind a physics fixture to the instance executing the code and remove it afterwards.

      +

      In the Create event, a fixture is created and its index is assigned to a temporary variable _fix. The shape and density of the fixture are then defined and the fixture is bound to the calling instance with the index for the bound fixture stored in the instance variable my_bound_fix. Finally, the fixture is deleted to prevent memory leaks as it is no longer needed.

      +

      In the Clean Up event, the bound fixture is removed.

       

       

      -
      © Copyright YoYo Games Ltd. 2025 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2026 All Rights Reserved

      physics_remove_fixture

      -

      This function removes (or "un-binds") a fixture from an instance or instances.

      +

      This function removes (or "un-binds") a bound fixture from an instance or instances.

      It requires the unique "ID" of the bound fixture (as returned by the function physics_fixture_bind) and it will remove all the currently defined physics properties for the instance, permitting you to redefine a new fixture and bind that to the instance. In this way you can change the instance's physical properties without having to destroy and re-create it.

       

      Syntax:

      @@ -29,13 +29,13 @@

      Syntax:

      id - Object Instance - The ID of the instance to remove the fixture from + Object Instance or Object Asset + The ID of the instance, or an object ID to remove the fixture from all instances of that object fixture - Physics Fixture ID - The ID of the fixture that is to be removed from the instance + Physics Bound Fixture ID + The ID of the bound fixture that is to be removed @@ -44,18 +44,18 @@

      Returns:

      N/A

       

      Example:

      -

      physics_remove_fixture(id, my_fix);

      -

      The code above will remove the fixture with the ID stored in the variable my_fix from the instance.

      +

      physics_remove_fixture(id, my_bound_fix);

      +

      The code above will remove the fixture with the ID stored in the variable my_bound_fix from the instance.

       

       

      -

      Joints

      +

      Joints

      In the GameMaker physics world, joints are used to constrain instances to the world or to each other. Typical examples in games include ragdolls, teeters, and pulleys, but joints can be combined in many different ways to create interesting motions or add realism to your game world.

      -

      NOTE: A joint does not need to be deleted when you destroy an instance joined to another instance, nor does it need to be deleted at the end of a room. Except in very specific cases (see the gear joint) as this is dealt with automatically by GameMaker.

      +

       A joint does not need to be deleted when you destroy an instance joined to another instance, nor does it need to be deleted at the end of a room. Except in very specific cases (see the gear joint) as this is dealt with automatically by GameMaker.

      The following pages explain the available joints and how they can be created:

       

      Once a joint has been created, it can often be necessary to know its properties in order to change them at specific times in your game. The following functions (with their corresponding internal constants) are available to test and change joint values:

       

      Additionally, you can use a number of constants from within GameMaker functions to get (or set) different properties of certain joints. These constants can all be found in the following section:

       

       

      -

       

      -

      Physics Joint Constants

      +

      Physics Joint Constants

      There are a great number of constants included within the GameMaker GML that are specific to joints between fixtures in the physics world. These can be used in conjunction with many of the different joint functions to set or get information from them in real time while the physics simulation is running. You should be aware, however, that complex calculations are done when you call these, so they should be used with care and only when necessary and note that many are unique to a specific type of joint. Also note that while you can get all these values with the appropriate function, you can only set those that are marked as not being read-only.

      In general these constants would be used in conjunction with the following functions:

      -

       

      -

      +

      General

      The following constants can be applied to any of the available joint types:

      @@ -32,7 +31,7 @@

      - + @@ -76,14 +75,12 @@

      Physics Joint ConstantPhysics Joint Constant
      Constant
      -


      - -

      +

      Motors

      These constants are for those joints that have a motor attached to them (revolute, prismatic, wheel):

      - + @@ -117,9 +114,7 @@


      Physics Joint ConstantPhysics Joint Constant
      Constant
      -


      - -

      +

      Revolute Joints

      For a revolute joint you can use the following constant (as well as the motor constants if one has been added):

      @@ -129,7 +124,7 @@


      - + @@ -144,7 +139,7 @@


      - + @@ -159,14 +154,12 @@


      Physics Joint ConstantPhysics Joint Constant
      Constant
      phy_joint_angle_limitsEnable or disable angle limiting for the joint. Set the value to true to enable or false to disable.Enable or disable angle limiting for the joint. Set the value to true to enable or false to disable. No
      -


      - -

      +

      Prismatic Joints

      For a prismatic joint you can use the following constant:

      - + @@ -175,7 +168,7 @@


      - + @@ -185,9 +178,7 @@


      Physics Joint ConstantPhysics Joint Constant
      Constant
      phy_joint_translationGets the distance between the anchor x/y coordinates and the local x/y coordinates.The distance between the anchor x/y coordinates and the local x/y coordinates. Yes
      -


      - -

      +

      Distance Joints, Weld Joints and Wheel Joints

      For a distance, weld, and wheel joints you can use the following constants (as well as those for pulley joints):

      @@ -197,7 +188,7 @@


      - + @@ -211,7 +202,7 @@


      - + @@ -226,14 +217,12 @@


      Physics Joint ConstantPhysics Joint Constant
      Constant
      phy_joint_frequencyThis will return (or set) the oscillation frequency for the joint, in hertz, and typically the frequency should be less than a half the frequency of the time step, as set by the function physics_world_update_speed().This will return (or set) the oscillation frequency for the joint, in hertz, and typically the frequency should be less than a half the frequency of the time step, as set by the function physics_world_update_speed. No
      -


      - -

      +

      Friction Joints

      For a friction joint you can use the following constants:

      - + @@ -252,14 +241,12 @@


      Physics Joint ConstantPhysics Joint Constant
      Constant
      -


      - -

      +

      Rope Joints

      For a rope joint you can use the following constant:

      - + @@ -282,7 +269,7 @@


      Back: Joints
      -

      © Copyright YoYo Games Ltd. 2022 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2026 All Rights Reserved

      physics_joint_distance_create

      This function creates a distance joint between two physics instances.

      -

      One of the simplest joints is a distance joint which says that the distance between two points on two instances must be constant. When you specify a distance joint the two instances should already be created and have a fixture assigned, then you define the two anchor points in room coordinates. The first anchor point is connected to instance 1, the second anchor point is connected to instance 2 and the distance between these points imply the length of the distance constrain. The image below shows how this works:

      -

      Distance joint illustrationAs you can see, the anchor points are specified as room coordinates so care must be taken when defining them, especially if the instances are being created at the same time as the joints rather than being placed in the room through the room editor. You should also realise that the joints are created independently of the size of the sprite of the instances or the fixtures they have attached. So, if you create a distance joint somewhere other than the origin of the instance, it is still valid and will constrain the two instances relative to the position at which it was created. If you set the "col" value to true then the two instances can interact and collide with each other but only if they have collision events, however if it is set to false, they will not collide no matter what.

      +

      One of the simplest joints is a distance joint which says that the distance between two points on two instances must be constant. When you specify a distance joint the two instances should already be created and have a fixture assigned, then you define the two anchor points in room coordinates. The first anchor point is connected to instance 1, the second anchor point is connected to instance 2 and the distance between these points implies the length of the distance constraint. The image below shows how this works:

      +

      Distance joint illustrationAs you can see, the anchor points are specified as room coordinates so care must be taken when defining them, especially if the instances are being created at the same time as the joints rather than being placed in the room through the Room Editor. You should also realise that the joints are created independently of the size of the sprite of the instances or the fixtures they have attached. So, if you create a distance joint somewhere other than the origin of the instance, it is still valid and will constrain the two instances relative to the position at which it was created. If you set the col value to true then the two instances can interact and collide with each other but only if they have collision events. If it is set to false, however, they will not collide no matter what.

       

      Syntax:

      physics_joint_distance_create(inst1, inst2, w_anchor1_x, w_anchor1_y, w_anchor2_x, w_anchor2_y, col)

      @@ -57,12 +57,12 @@

      Syntax:

      - + - +
      Physics Joint ConstantPhysics Joint Constant
      Constant
      w_anchor2_y Realthe second y coordinate for the joint, within the game worldThe second y coordinate for the joint, within the game world
      col BooleanWhether the two instances can collide (true) or not (false)Whether the two instances can collide (true) or not (false)
      @@ -82,15 +82,14 @@

      Example:

      The above code creates and defines a new fixture and then creates an instance of "obj_Rudder". The fixture is then assigned to the instance that is running the code as well as the newly created one and a joint is created between them. Finally the fixture is deleted as it is no longer needed.

       

       

      -

       

      physics_joint_enable_motor

      This function sets whether to enable or disable the motor on a physics joint that has a motor.

      -

      When you have a joint with a motor (prismatic or revolute), you may want to be able to switch the motor on or off depending on variables and conditions within the game. For this, you need to have stored the index of the joint previously in a variable and then you can switch the motor on or off by using this function and setting the "motor" argument to true or false.

      +

      When you have a joint with a motor (prismatic or revolute), you may want to be able to switch the motor on or off depending on variables and conditions within the game. For this, you need to have stored the index of the joint previously in a variable and then you can switch the motor on or off by using this function and setting the "motor" argument to true or false.

       

      Syntax:

      physics_joint_enable_motor(joint, motor)

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

      Syntax:

      motor Boolean - Whether you wish to turn the motor on (true) or off (false) + Whether you wish to turn the motor on (true) or off (false) @@ -58,15 +58,14 @@

      Example:

      The above code creates and defines a new fixture and then creates an instance of "obj_Door", binding the created fixture to the two instances. They are then joined by a revolute joint with no motor and the angles limited to a +/- 90 degree swing, and we store the joint index in the variable "perma_joint". We then switch the motor on using this variable, before finally deleting the fixture from memory as it is no longer needed.

       

       

      -

       

      physics_joint_get_value

      This function returns the value of the joint property corresponding to the given joint constant.

      -

      By using a series of predefined constants, you can ask GameMaker to tell you a number of things about the state of any given joint. This is very useful as it gives you the ability to delete joints or change an instances behaviour depending on whatever your needs are at the time. There are a number of constants that can be used in this function and they can be found here: Physics Joint Constants, but be aware that complex calculations are done when you call these, so they should be used with care and only when necessary and note that many are unique to a specific type of joint.

      +

      By using a series of predefined constants, you can ask GameMaker to tell you a number of things about the state of any given joint. This is very useful as it gives you the ability to delete joints or change an instance's behaviour depending on whatever your needs are at the time. There are a number of constants that can be used in this function and they can be found here: Physics Joint Constants, but be aware that complex calculations are done when you call these, so they should be used with care and only when necessary. Also note that many are unique to a specific type of joint.

      If the property does not exist (if, for example, you check a pulley joint for prismatic translation) then 0 will be the return value.

       

      Syntax:

      @@ -60,15 +60,14 @@

      Example:

      The above code checks to see if the variable "shipJoint" holds a joint index and if it does, it then calculates the force being applied to that joint using the two constants. Finally, if the total force is greater than 2, the joint is deleted.

       

       

      -

       

      physics_joint_pulley_create

      This function creates a pulley joint between two physics instances.

      -

      The pulley joint is used to connect two instances within the physics world in such a way that moving one will directly influence the movement of the other. These joints are first anchored in the world space at two points, each one connected to an instance at its center of mass. This can be changed by setting the local anchor x/y coordinates relative to the origin of the instance, meaning that the actual connection from the instance to the physics world anchor point can be offset somewhere other than its origin. The following image illustrates this:

      -

      Pulley joint illustrationIf you look at inst2 you can see that its local anchor point has been offset 20 pixels to the "left" of its origin (Remember! The world anchor points are defined using the room coordinates, while the local anchor points are defined relative to the origin of the instance). You can also specify a ratio for the pulley joint, which tells one side or the other to move faster, with a value below 1 making the first instance move faster (E.G. 0.5 will make it move twice as fast) and a value above 1 making the second instance move faster (E.G. 2 will make it move twice as fast).

      -

      As with all the joints, if you set the "col" value to true then the two instances can interact and collide with each other but only if they have collision events, however if it is set to false, they will not collide no matter what.

      +

      The pulley joint is used to connect two instances within the physics world in such a way that moving one will directly influence the movement of the other. These joints are first anchored in the world space at two points, each one connected to an instance at its centre of mass. This can be changed by setting the local anchor x/y coordinates relative to the origin of the instance, meaning that the actual connection from the instance to the physics world anchor point can be offset somewhere other than its origin. The following image illustrates this:

      +

      Pulley joint illustrationIf you look at inst2 you can see that its local anchor point has been offset 20 pixels to the "left" of its origin (Remember! The world anchor points are defined using the room coordinates, while the local anchor points are defined relative to the origin of the instance). You can also specify a ratio for the pulley joint, which tells one side or the other to move faster, with a value below 1 making the first instance move faster (e.g. 0.5 will make it move twice as fast) and a value above 1 making the second instance move faster (e.g. 2 will make it move twice as fast).

      +

      As with all the joints, if you set the col value to true then the two instances can interact and collide with each other but only if they have collision events. If it is set to false, however, they will not collide no matter what.

       

      Syntax:

      physics_joint_pulley_create(inst1, inst2, w_anchor1_x, w_anchor1_y, w_anchor2_x, w_anchor2_y, l_anchor1_x, l_anchor1_y, l_anchor2_x, l_anchor2_y, ratio, col)

      @@ -88,7 +88,7 @@

      Syntax:

      col Boolean - Whether the two instances can collide (true) or not (false) + Whether the two instances can collide (true) or not (false) @@ -100,24 +100,23 @@

      Example:

      var t_fix, inst1, inst2;
      t_fix = physics_fixture_create();
      physics_fixture_set_circle_shape(t_fix, 20);
      - inst1 = instance_create_layer(150, room_height - 90, "Instances", obj_Block);
      + inst1 = instance_create_layer(150, room_height - 90, "Instances", obj_block);
      inst2 = instance_create_layer(300, room_height - 90, "Instances", obj_block);
      physics_fixture_bind(t_fix, inst1);
      physics_fixture_bind(t_fix, inst2);
      physics_joint_pulley_create(inst1, inst2, 150, room_height - 140, 300, room_height - 140, 0, 0, 0, 0, 2, 0);
      physics_fixture_delete(t_fix);

      -

      The above code creates and defines a new fixture, creates two instances of "obj_Block", and then binds this fixture two them. It then goes on to define a pulley joint between these instance, with no offset for the joints, a ratio of 2:1 (meaning that inst2 will move faster). No collisions occur between the two instances in the pulley.

      -

       

      +

      The above code creates and defines a new fixture, creates two instances of "obj_block", and then binds this fixture two them. It then goes on to define a pulley joint between these instance, with no offset for the joints, a ratio of 2:1 (meaning that inst2 will move faster). No collisions occur between the two instances in the pulley.

       

       

      physics_joint_rope_create

      This function creates a rope joint between two physics instances.

      -

      A rope joint is one which is used to join two instances that you want to keep a constant distance apart, no matter what other forces are acting on it. With a distance joint, you can get "joint stretching" where the two fixtures will separate and behave strangely should too much stress be put on the joint, however the rope joint does not do this and will not stretch any further than the maximum defined length. When you create a rope joint the two instances should already be created and have a fixture assigned, then you define the two anchor points in room coordinates. The first anchor point is connected to instance 1, the second anchor point is connected to instance 2 and the distance and the maxlength argument sets the maximum length constraint on the joint. The image below shows how this works:

      -

      Rope joint illustrationAs you can see, the anchor points are specified as room coordinates so care must be taken when defining them, especially if the instances are being created at the same time as the joints rather than being placed in the room through the room editor. You should also realise that the joints are created independently of the size of the sprite of the instances or the fixtures they have attached. So, if you create a rope joint somewhere other than the origin of the instance, it is still valid and will constrain the two instances relative to the position at which it was created. If you set the "col" value to true then the two instances can interact and collide with each other but only if they have collision events, however if it is set to false, they will not collide no matter what.

      +

      A rope joint is one which is used to join two instances that you want to keep a constant distance apart, no matter what other forces are acting on it. With a distance joint, you can get "joint stretching" where the two fixtures will separate and behave strangely should too much stress be put on the joint. The rope joint, however, does not do this and will not stretch any further than the maximum defined length. When you create a rope joint the two instances should already be created and have a fixture assigned, then you define the two anchor points in room coordinates. The first anchor point is connected to instance 1, the second anchor point is connected to instance 2 and the distance and the maxlength argument sets the maximum length constraint on the joint. The image below shows how this works:

      +

      Rope joint illustrationAs you can see, the anchor points are specified as room coordinates so care must be taken when defining them, especially if the instances are being created at the same time as the joints rather than being placed in the room through the Room Editor. You should also realise that the joints are created independently of the size of the sprite of the instances or the fixtures they have attached. So, if you create a rope joint somewhere other than the origin of the instance, it is still valid and will constrain the two instances relative to the position at which it was created. If you set the col value to true then the two instances can interact and collide with each other but only if they have collision events. If it is set to false, however, they will not collide no matter what.

       

      Syntax:

      physics_joint_rope_create(inst1, inst2, w_anchor1_x, w_anchor1_y, w_anchor2_x, w_anchor2_y, maxlength, col)

      @@ -67,7 +67,7 @@

      Syntax:

      col Boolean - Whether the two instances can collide (true) or not (false) + Whether the two instances can collide (true) or not (false) @@ -87,15 +87,14 @@

      Example:

      The above code creates and defines a new fixture and then creates an instance of "obj_Rudder". The fixture is then assigned to the instance that is running the code as well as the newly created one and a rope joint is created between them. Finally the fixture is deleted as it is no longer needed.

       

       

      -

       

      physics_joint_set_value

      This function sets the value of the joint property corresponding to the given joint constant to the given value.

      -

      Certain joint properties can be changed and set even after the creation of the joint. There are a number of constants that can be used in this function and they can be found here: Physics Joint Constants.

      +

      Certain joint properties can be changed and set even after the creation of the joint. There are a number of constants that can be used in this function and they can be found here: Physics Joint Constants.

       

      Syntax:

      physics_joint_set_value(joint, field, value)

      @@ -56,15 +56,14 @@

      Example:

      The above code checks to see if the joints maximum motor torque is set to less than 2 and if it is it then sets it to 2.

       

       

      -

       

      -

      Debugging

      +

      Debugging In GameMaker

      When programming your game, whether using GML Code or GML Visual, it can be very easy to make mistakes - using the wrong variables, passing the wrong arguments, or using the wrong functions are just some of the most common errors we all make - and these mistakes are not always detected by the syntax checker that is included with the script/action editor. That means that these mistakes will only become apparent when you actually run or compile your game, and even then it can sometimes be difficult to know exactly what is going wrong. It can therefore be of vital importance to know how your game is performing on the chosen device, as well as see what instances are in the room, what global variables have been created and a whole host of other details. Checking these things is called "debugging your code", and any errors or issues you may find are called "bugs".

      Now, you can check a lot of these things yourself by adding in so-called "debug code" to your games to display on the screen the information you require, or you can have it that it shows messages when there is an error, but this is often a lot of work and if you aren't sure where the problem is in the first place then it can be a time consuming case of trial and error to track down your bug. For that, GameMaker has a special test mode called Debug Mode which will start the Debugger, and there is also a comprehensive error reporting system which displays messages on Compiling to help you track down any problems with your game.

      The sections below cover the different ways that you can debug your game:

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

      Debugging

      -
      © Copyright YoYo Games Ltd. 2025 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2026 All Rights Reserved
      @@ -72,7 +73,7 @@

      Starting A New Project

      -
      © Copyright YoYo Games Ltd. 2025 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2026 All Rights Reserved

      UI Element Properties

      The Element List displays all UI layers and all parts of a UI layer, including Flex Panels and assets:

      -

      You can select a UI layer, Flex Panel or Asset Element in the Element List and its properties will be shown in The Inspector.

      -

      Besides being able to change the Element name and associated asset (if any), there are other properties which are described below for each type of Element.

      +

      You can select a UI layer, Flex Panel or Asset Element in the Element List and its properties will be shown in The Inspector. Besides being able to change the Element name and associated asset (if any), there are other properties which are described below for each type of Element.

      These properties are represented at runtime by the Flex Panel Struct Members.

      UI Layer Properties

      A UI layer contains the following main properties:

      @@ -114,7 +113,7 @@

      Extra Options

      -
      © Copyright YoYo Games Ltd. 2025 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2026 All Rights Reserved
      @@ -49,7 +50,7 @@

      GameMaker IDE

      -
      © Copyright YoYo Games Ltd. 2024 All Rights Reserved
      +
      © Copyright YoYo Games Ltd. 2026 All Rights Reserved