ART & ANIMATION

Spine Animation Optimization: Save Your Nerves and Time by Avoiding Bugs

The most common problems with integrating Spine animations into a game engine and basic methods for optimizing animation.

Mikhail Shlykov
G5 Careers

--

Hello, everyone! My name is Mikhail Shlykov. I’m a Spine animator at G5 Games, a mobile game developer and publisher. I’ve been working with Spine for 8 years, and I’ve encountered a lot of animation bugs and errors in different game engines. In this article I want to share my experience and help other animators avoid such problems and reduce time and stress.

Animation display and performance issues can happen in any project, no matter what game engine and animation editor you use. I’ll talk about the most common problems with integrating Spine animations into a game engine and suggest basic methods for optimizing animation. This article will be useful for Spine animators who export animations and for developers who work with animations in game engines. Many of the principles I describe also apply to other animation editors besides Spine.

About Skeletal 2D Animation

In this article we’ll discuss skeletal 2D animation, which is often created using Spine, DragonBones, Blender COA Tools, Rive, and the built-in Unity editor. The main advantage of skeletal 2D animation is the ability to reuse images many times, which cuts down on the amount of graphics stored in RAM. This idea is the basis for maximum optimization of resource utilization. By reusing existing elements, the visual appeal of animations can be enhanced without increasing the amount of graphics created.

In this example, an explosion animation is created by using only four images.

Anticipating Bugs

Regardless of the editor chosen for creating animations or the game engine, there is a set of rules that can help you avoid wasting time fighting bugs in the future.

Naming and Project Order

The names of all elements, attachments, and storage paths of animation files in the operating system must always be saved in Latin characters, without spaces or special characters. Different engines may work with different encodings, but Latin is the universal naming method supported everywhere.

In addition, it’s important to maintain order in the project and give elements easy-to-read names. This makes transferring the source files to other animators easier and simplifies your own work if you’ll need to return to any of your previous projects in Spine in the future. This way you can orient yourself more quickly and easily, even after a long time away.

Image Storage Paths

One of the reasons for attachment loss during export is absolute paths. For proper atlas packing, you should specify a relative path to the folder with images.

Working With Images and Their Metadata

Before you start work, always check the graphics for unused empty spaces accidentally created in the graphics editor. Even one random semi-transparent pixel can make working with graphics more complicated and increase the size and weight of the final atlas. One of the methods for reducing atlas size is polygonal packing, in which images are packed taking into account the boundaries of their mesh size.

For this method of atlas packing, all attachments are converted to mesh, which is used to cut the empty areas. This will increase the number of triangles in the project, which should be controlled and the appropriate packing method should be chosen individually.

Metadata in PNG images can significantly increase the weight of the atlas and cause freezes in Spine when working with such graphics. Older versions of the Photoshop to Spine script could record metadata in PNG if this feature wasn’t disabled in Photoshop by default. You should take this point into account and check the weight of PNG images after export.

Size of Original Graphics

Quite often the original graphics are provided for animation at a higher resolution. To minimize unnecessary work with the animation, it’s important to find out in advance what final size will be used in the engine. This lets you avoid adjusting the size of the skeleton and graphics exported to Spine after creating the animation. It’s much easier to resize a graphic before exporting it from a graphics editor than it is to remake an already customized rig.

Impact on Performance

I’ve worked with a variety of game engines — Unity, Pixie, Godot, Cocos Creator, and a custom engine at G5 Games — and during that time I’ve developed my universal rating for the impact of Spine elements on performance.

1. Masks

The most resource-intensive part of using masks is creating a draw call, which is a request to the graphics API to render a visual. At that moment, all the data is collected and analyzed for display on the screen, and the calculations are done on the CPU and GPU side. At the same time, the majority of the load is placed on the process of preparing for the request itself. The presence of a mask in a project generates two additional rendering requests. The number of mask points and its animation have almost no effect on performance, unlike the requests themselves and the area of hidden images.

2. Blend Modes

Game engines work with image color multiplication differently, so the impact of modes other than Normal may vary. If there are slots with Additive, Multiply, and Screen modes, then an additional draw request is created. The degree of load at this moment depends on the size of the images using these modes.

3. Number of Mesh Vertices

Each point has its own coordinates, and each time it interacts with the mesh, these coordinates behave like a separate bone. Each attachment, even if not turned into a mesh, has 4 vertices, so increasing the number of vertices leads to additional calculations in the engine, putting a load on the CPU. And manual deformation of mesh points, without bone binding, leads to the creation of a separate timeline for each of the mesh vertices. An additional capability when working with mesh is linked mesh, which allows you to inherit mesh state for images of the same size without creating new timelines for the mesh or calculating them on the CPU side again.

4. Bounding Box

In most engines, if there is no bounding box, it is generated dynamically for each frame of the animation, which greatly affects performance. That’s why it’s better to create a bounding box in Spine manually. Furthermore, the presence of a bounding box allows you to unload an animated object from memory the moment it leaves the screen, which also improves performance.

5. Constraints

TK and IK constraints in the engine are a mathematical construction that affects the position of the bones. Their presence adds additional calculations to the CPU. The impact of each constraint on performance is comparable to ten additional bones.

6. Paths

On the engine side, the path is a cubic Bézier curve, each segment of which is constructed using four points. The construction involves the CPU, but the curves use the same construction principle as the bone position. The differences are only in the visual representation and additional curve controls.

7. Bones

A bone is the minimum computational unit that can move in space and transmit data to the engine to track coordinates. Each bone adds data for the CPU to work with: the more bones, the more data it has to handle.

8. Skins

Skins are a visual representation of the set of attachments used. On the engine side, they add markers to switch attachments and bones, as well as their features.

9. Slots

Slots are containers for storing attachments. Because slots cannot move without bones, they require minimal resources. The main load is put on the GPU since there are no timelines created for moving in space.

Export

Before exporting the animation, you should make sure that all unnecessary and unused elements (bones, slots, attachments, background files, additional unused animations) are removed from the Spine project and from the image folder.

The size of the created atlas must be divisible by two. If the animation is created for use on mobile devices, the size must not exceed 2048 pixels on the long side. This constraint is due to the inability to display images larger than 2048 pixels on the long side on Apple devices.

A common problem with graphics after export is artifacts around PNG images, such as black outlines and white glows with semi-transparent pixels. This is caused by a mismatch between the alpha modes of the material in the project and the exported animation.

Premultiply Alpha and Bleed parameters are responsible for the alpha mode. Choose your export option based on the settings of the project in the game engine.

Another type of graphic artifact during export is sharp image crop lines. The reason might be a lack of indents on the images, which can be fixed by increasing the X and Y axis indents.

Incorrect animation display can be caused by the Clean Up animation function, which automatically removes unnecessary animation keys and often greatly optimizes animations by removing many unused keys. However, it sometimes results in the incorrect display of attachments or incorrect position of bones. This happens due to the inheritance of bone states when switching animations. State inheritance is customized in the game engine and should always be discussed with the developer.

Optimization

Optimization should not be the main goal when creating animations because otherwise the artistic expression of the animations suffers and we limit ourselves in the resources we use. Moreover, it’s not always necessary to optimize something without good reason, as it can be a waste of time. You should handle this problem sensibly and proactively define the limits beyond which you should not go. In such a case, when acceptable values exceed the limits and there are real performance issues, you should devote your efforts to optimization. Sometimes even a very load-intensive animation with effects can look fine and not affect performance if there is nothing else in the scene besides it.

That’s why I recommend you to start optimization at the final stage, when there are real performance issues, and find alternatives to the current tools and improve performance by reducing elements.

Removing unnecessary things is a basic method for optimization. Oftentimes during rigging, we create more complex structures to increase the mobility and greater capabilities of the rig. However, after creating the necessary animations, we may not use all the capabilities of the rig. In this case, it’s possible to simplify the rig to improve performance.

Fake Add Mode

Sometimes the ability to use image blend modes is limited and it’s necessary to find alternatives. In such cases, it may help to use additional attachments that contain effects. This method is used when the additive effect doesn’t go beyond the boundaries of the main object. To do this, we can apply a blend effect to the necessary attachments in SETUP mode and export as PNG files. After that, the attachments with additive mode are replaced with the previously received images but in normal mode.

Removing Unnecessary Mesh Points

When rigging a mesh, points are oftentimes created to increase the smoothness of the curves and for greater capabilities when working with graphics. But after animation, you may realize that the mesh could be simpler and visually there is no difference if we remove any points. Also, removing extra points can positively affect animation performance.

Disabling Attachments in Animation

When you need to hide an attachment and make it transparent, you should always disable it, not just leave it transparent. This will free up memory and reduce the load on the GPU because an attachment, even if it’s transparent, participates in the rendering calculation and is processed at each rendering request.

Reducing Frame Sequences

If you use sequences in animation, you may often notice the difference between high frame rate sequences and low frame rate sequences on mobile devices. For this reason, sometimes removing unnecessary frame sequences can be imperceptible and will not only reduce the atlas but also improve performance. To make the animation smoother, you can distort the frame sequences with mesh, or you can pull them out of the sequences as an ordinary container and animate them with bones, enlarging, moving, and tilting them.

Reducing the Size of Background Graphics and Effects

Single-color background images and images with blurred edges (clouds, glows, rays of light, shadows, etc.) can be reduced by half or more by restoring their size with Spine. This allows you to reduce the atlas size and thus free up RAM and the volume of stored build graphics.

Choice of Export Format

At the project formation stage, you should give preference to the .skel binary format because, unlike the .json format, it has smaller volumes and is read faster by the engine. Each animation key is a set of figures defining the position and properties of objects. One number in the binary system is 4 bytes of information, but in the .json format it’s 8–9 bytes. If these values are accessed numerous times during animation, the difference can be significant.

Conclusion

Communication with developers and artists, as well as figuring out all possible constraints and requirements, plays a key role in creating quality animations. Close interaction with the team helps you identify potential problems and requirements in advance, which helps you avoid many errors and save a significant amount of working time. Don’t ignore this important aspect of work, and your projects will be smooth and successful.

G5 Games is committed to expanding and creating fresh projects. My team is always looking for new artists. If you want to try your hand in the growing gaming industry, join us!

--

--