The upcoming release of GameMaker Studio 2.2.2 will bring with it an update to the Spine runtimes, setting the new recommended Spine version to be 3.7. Unfortunately this means that projects using Spine sprites created using previous runtimes will have to update their sprites to prevent any possible issues, as Spine runtimes are not generally backwards compatible.
Now, after updating to GMS 2.2.2, you may test your project and see that the Spine sprites look okay and don't show any errors... but you should still update the sprites, as legacy spine sprites may appear correct most of the time, but they may still cause issues later on in development. Updating now will also make it less likely that future Spine updates will break your games.
How To Update Spine Sprites
The only way to ensure that your sprites will show correctly all the time using the 3.7 Spine runtime is to have exported the sprites using this runtime. The steps to updating your sprites are:
- Open Spine and in the settings ensure that it is using the 3.7 runtime:
- Open the legacy sprite in Spine
- Check that it looks okay and make any tweaks, additions, or fixes required (see the Features, Changes and Additions section below for more information)
- Export the sprite again
Once you have done this for all the sprites, you can then load them into GameMaker Studio 2. You can do this by either opening the sprite editor for each sprite in GMS2 and loading the updated Spine sprites one at a time, or you can drag and drop all the JSON files for all the Spine sprites onto the IDE and they will be added to your resource tree, where they can then be renamed as required.
NOTE: While Spine 3.7 is in beta you can use Spine 3.6.53 to export sprites and they will work fine in GMS2 2.2.2 (but any fixes or new functionality introduced by Spine 3.7 will obviously not be available).
Features, Changes and Additions
This update brings a number of new features and functions and changes how some of the original functions work. The New features are:
- Clipping attachments - GameMaker Studio 2 now supports rendering of sprites that use clipping attachments. These are attachments assigned to spine slots that clip away parts of the sprite.
- Per-attachment colours - GMS2 now supports tinting attachments based on their assigned colours
- Per-slot blend modes - GMS 2 now supports per-slot blend modes as specified in the Spine IDE
- Partial tint-black support - GMS2 now supports partial tinting of dark colors separately from the light colours. Note that this requires a custom shader, which is given, along with an explanation of how to use it, further down this article.
Changes To Existing Functionality
The core Spine functionality remains the same, but there has been a minor change to the function skeleton_bone_state_get(). The DS map that it returns will no longer contain the following keys:
- "worldSignX"
- "worldSignY"
These have been removed from the map as they are no longer exposed by this Spine runtime version
New Functions
To go along with the new features, there have also been a few new functions added. These functions are outlined below, but for full details you should see the manual inside 2.2.2 when it is released:
- skeleton_attachment_create_colour(name, sprite, index, xorigin, yorigin, xscale, yscale, rotation, colour, alpha): This creates an attachment and at the same time allows you to specify a colour and alpha value for it.
- skeleton_slot_data_instance(list): This populates a pre-created DS list with the slot data for the spine sprite associated with the current instance (including any attachment modifications).
- skeleton_slot_colour_set(slot, colour, alpha): This permits you to set the colour and alpha blending values for a given slot.
- skeleton_slot_colour_get(slot): This will return the colour blending set for the given slot.
- skeleton_slot_alpha_get(slot): This will return the alpha blending value for the given slot.
- skeleton_bone_list(sprite, list): This function will populate a (pre-created) DS list with the bone names for a given Spine sprite.
- skeleton_slot_list(sprite, list): This function will populate a (pre-created) DS list with the slot names for a given Spine sprite.
- skeleton_find_slot(x, y, list): This will add the names of all slots found at the specified position to the (pre-created) ds_list. Note that the list is always sorted in descending order starting from the top-most slot.
Tint Black Support
This feature allows the dark areas of spine sprite slots to be tinted differently to the light areas (see the "Tint black" section on this page: http://esotericsoftware.com/spine-attachments for more details). Currently, in order to make use of this feature in GameMaker Studio 2, you are required to use a custom shader when drawing a spine sprite that uses it. This shader contains a global uniform variable called "gm_SpineTintBlackColour" which the runner fills with the current tint-black colour, retrieved from the Spine data automatically. The shader required is shown below:
// Vertex shader (this is the same as the default passthrough vertex shader)
attribute vec3 in_Position; // (x,y,z)
attribute vec4 in_Colour; // (r,g,b,a)
attribute vec2 in_TextureCoord; // (u,v)
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
void main()
{
vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
v_vColour = in_Colour;
v_vTexcoord = in_TextureCoord;
}
// Fragment Shader varying vec2 v_vTexcoord; varying vec4 v_vColour; uniform vec4 gm_SpineTintBlackColour; // This is the uniform containing the tint-black colour void main() { vec4 tb = gm_SpineTintBlackColour; vec4 texcol = texture2D( gm_BaseTexture, v_vTexcoord ); vec4 outcol; outcol.rgb = v_vColour.rgb * texcol.rgb; outcol.rgb += tb.rgb * ((tb.a * (texcol.a - 1.0)) + (1.0 - texcol.rgb)); // This line performs the tint-black blending logic outcol.a = v_vColour.a * texcol.a; gl_FragColor = outcol; }
You would use this by first calling the shader, then drawing the sprite, then resetting the shader. Something like this:
shader_set(shd_spine_tint_black);
draw_self();
shader_reset();