Binary export format

This page describes Spine's binary export format for skeleton and animation data. Runtimes load this data to display animations. Also, Spine can import data in this format, allowing interoperability with other tools.

The Spine Runtimes handle loading binary and JSON data. You do not need to write your own loading code unless you are writing your own runtime from scratch (which is an enormous amount of work).

The binary format has a very small file size and loads very quickly at runtime. The downside is that any changes in the runtime that affect data loading will require the binary data to be re-exported from the Spine project. Also the binary format is not human readable, so the JSON format may be a better choice for inspecting the data.

Data marked "nonessential" is only output when the Nonessential data export setting is checked. This data is not required for rendering but may be useful for tools or when importing the data back into Spine.

The binary format is the serialized version of a "skeleton data" instance, which has a list of bones, slots, skins, and animations. This is stateless data that is not tied to a particular on-screen skeleton instance.

Data types

The binary format uses a number of basic data types. The example code is shown in C as a reference.

Boolean

A boolean is 1 byte, stores and 1 for true and 0 for false.

Short

A short is 16 bits and stored as 2 bytes.

int readShort () {
   return (readByte() << 8) | readByte();
}

Int

An int is 32 bits and stored as 4 bytes.

int readInt () {
   return (readByte() << 24) | (readByte() << 16) | (readByte() << 8) | readByte();
}

Varint

A varint is an int but it is stored as 1 to 5 bytes, depending on the value. There are two kinds of varints, varint+ is optimized to take up less space for small positive values and varint- for small negative (and positive) values.

For each byte in the varint, the MSB is set if there are additional bytes. If the result is optimized for small negative values, it is shifted.

int readVarint (int/*bool*/optimizePositive) {
   unsigned char b = readByte();
   int value = b & 0x7F;
   if (b & 0x80) {
      b = readByte();
      value |= (b & 0x7F) << 7;
      if (b & 0x80) {
         b = readByte();
         value |= (b & 0x7F) << 14;
         if (b & 0x80) {
            b = readByte();
            value |= (b & 0x7F) << 21;
            if (b & 0x80) value |= (readByte() & 0x7F) << 28;
         }
      }
   }
   if (!optimizePositive) value = (((unsigned int)value >> 1) ^ -(value & 1));
   return value;
}

Float

A float is 32 bits and stored as 4 bytes. Depending on the language and architecture, the bytes can be combined into an int, then converted to a float.

float readFloat () {
   union {
      int intValue;
      float floatValue;
   } intToFloat;
   intToFloat.intValue = readInt();
   return intToFloat.floatValue;
}

String

A string is a varint+ length followed by zero or more UTF-8 characters. If the length is 0, the string is null (which can be considered the same as empty for most purposes). If the length is 1, the string is empty. Otherwise, the length is followed by length - 1 bytes. A UTF-8 character may be more than one byte, so there may be more bytes than UTF-8 characters.

void readString (char* value, int maxLength) {
   int count = readVarint(true);
   if (count-- > 1) {
      if (count >= maxLength) count = maxLength - 1;
      for (int i = 0; i < count; i++)
         value[i] = readByte();
   }
   value[count] = '\0';
}

Color

A color is an RGBA value stored as an int.

float* readColor (float* value) {
   int rgba = readInt();
   value[0] = ((rgba & 0xff000000) >>> 24) / 255f; // R
   value[1] = ((rgba & 0x00ff0000) >>> 16) / 255f; // G
   value[2] = ((rgba & 0x0000ff00) >>> 8) / 255f; // B
   value[3] = ((rgba & 0x000000ff)) / 255f; // A
}

Constants

In some places constants are used for identification. A constant is 1 byte. Constants are shown with the prefix in ALLCAPS.

ATTACHMENT_REGION = 0
ATTACHMENT_BOUNDING_BOX = 1
ATTACHMENT_MESH = 2
ATTACHMENT_LINKED_MESH = 3
ATTACHMENT_PATH = 4
ATTACHMENT_POINT = 5

BLEND_MODE_NORMAL = 0
BLEND_MODE_ADDITIVE = 1
BLEND_MODE_MULTIPLY = 2
BLEND_MODE_SCREEN = 3

CURVE_LINEAR = 0
CURVE_STEPPED = 1
CURVE_BEZIER = 2

BONE_ROTATE = 0
BONE_TRANSLATE = 1
BONE_SCALE = 2
BONE_SHEAR = 3

TRANSFORM_NORMAL = 0
TRANSFORM_ONLY_TRANSLATION = 1
TRANSFORM_NO_ROTATION_OR_REFLECTION = 2
TRANSFORM_NO_SCALE = 3
TRANSFORM_NO_SCALE_OR_REFLECTION = 4

SLOT_ATTACHMENT = 0
SLOT_COLOR = 1
SLOT_TWO_COLOR = 2

PATH_POSITION = 0
PATH_SPACING = 1
PATH_MIX = 2

PATH_POSITION_FIXED = 0
PATH_POSITION_PERCENT = 1

PATH_SPACING_LENGTH = 0
PATH_SPACING_FIXED = 1
PATH_SPACING_PERCENT = 2

PATH_ROTATE_TANGENT = 0
PATH_ROTATE_CHAIN = 1
PATH_ROTATE_CHAIN_SCALE = 2

Format

The data appears in the following order:

string hash: A hash of all the skeleton data. This can be used by tools to detect if the data has changed since the last time it was loaded.

string version: The version of Spine that exported the data. This can be used by tools to enforce a particular Spine version to be used.

float width: The AABB width for the skeleton's attachments as it was in the setup pose in Spine. This can be used as a general size of the skeleton, though the skeleton's AABB depends on how it is posed.

float height: The AABB height for the skeleton's attachments as it was in the setup pose in Spine.

boolean nonessential: If false, data marked as nonessential will be omitted.

float fps: The dopesheet framerate in frames per second, as it was in Spine. Nonessential.

string images: The images path, as it was in Spine. Nonessential.


varint+ bone count: The number of bones that follow.

For each bone:

string name: The bone name. This is unique for the skeleton.

varint+ parent index: The index plus one of the parent bone. This value is omitted for the root bone.

float rotation: The rotation in degrees of the bone relative to the parent for the setup pose.

float x: The X position of the bone relative to the parent for the setup pose.

float y: The Y position of the bone relative to the parent for the setup pose.

float scaleX: The X scale of the bone for the setup pose.

float scaleY: The Y scale of the bone for the setup pose.

float shearX: The X shear of the bone for the setup pose.

float shearY: The Y shear of the bone for the setup pose.

float length: The length of the bone. The bone length is not used much at runtime except for 2 bone IK and to draw debug lines for the bones.

TRANSFORM_* transform mode: Determines how parent bone transforms are inherited.

color color: The color of the bone, as it was in Spine. Nonessential.


varint+ slot count: The number of slots that follow.

For each slot:

string name: The constraint name. This is unique for the skeleton.

varint+ bone index: The index of the bone that this slot is attached to.

color color: The color of the slot for the setup pose. This is an 8 character string containing 4 two digit hex numbers in RGBA order.

string attachment: The name of the slot's attachment for the setup pose. If null, there is no attachment for the setup pose.

BLEND_MODE_* blend: The type of blending to use when drawing the slot's visible attachment.


varint+ ik constraint count: The number of constraints that follow.

For each constraint:

string name: The constraint name. This is unique for the skeleton.

varint+ order index: The ordinal for the order constraints are applied.

varint+ bone count: The number of bones that follow (1 or 2).

For each bone:

varint+ bone index: The index of the bone whose rotation will be controlled by the constraint.

varint+ target index: The index of the target bone.

float mix: A value from 0 to 1 indicating the influence the constraint has on the bones, where 0 means only FK, 1 means only IK, and between is a mix of FK and IK.

boolean bendPositive: If true, the bones will bend in the positive rotation direction.


varint+ transform constraint count: The number of constraints that follow.

For each constraint:

string name: The constraint name. This is unique for the skeleton.

varint+ order index: The ordinal for the order constraints are applied.

varint+ bone index: The index of the bone whose transform will be controlled by the constraint.

varint+ target index: The index of the target bone.

boolean local: True if the target's local transform is affected, else the world transform is affected.

boolean relative: True if the target's transform is adjusted relatively, else the transform is set absolutely.

float offset rotation: The rotation to offset from the target bone.

float offset x: The X distance to offset from the target bone.

float offset y: The Y distance to offset from the target bone.

float offset scale x: The X scale to offset from the target bone.

float offset scale y: The Y scale to offset from the target bone.

float offset shear y: The Y shear to offset from the target bone.

float rotate mix: A value from 0 to 1 indicating the influence the constraint has on the bones, where 0 means no affect, 1 means only the constraint, and between is a mix of the normal pose and the constraint.

float translate mix: See rotate mix.

float scale mix: See rotate mix.

float shear mix: See rotate mix.


varint+ path constraint count: The number of constraints that follow.

For each constraint:

string name: The constraint name. This is unique for the skeleton.

varint+ order index: The ordinal for the order constraints are applied.

varint+ bone count: The number of bones that follow.

For each bone:

varint+ bone index: The index of the bone whose rotation and/or translation will be controlled by the constraint.

varint+ target index: The index of the target slot.

PATH_POSITION_* position mode: Determines how the path position is calculated.

PATH_SPACING_* spacing mode: Determines how the spacing between bones is calculated.

PATH_ROTATE_* rotate mode: Determines how the bone rotation is calculated.

float offset rotation: The rotation to offset from the path rotation.

float position: The path position.

float spacing: The spacing between bones.

float rotate mix: A value from 0 to 1 indicating the influence the constraint has on the bones, where 0 means no affect, 1 means only the constraint, and between is a mix of the normal pose and the constraint.

float translate mix: See rotate mix.


Skin default skin: The default skin data, which holds attachments not assigned a skin in Spine.

varint+ skin count: The number of skins that follow.

For each skin:

string name: The skin name. This is unique for the skeleton.

Skin skin: The skin data.


varint+ event count: The number of events that follow.

For each event:

string name: The name of the event. This is unique for the skeleton.

varint- int: The integer value of the event.

float float: The float value of the event.

string string: The string value of the event.


varint+ animation count: The number of animations that follow.

For each animation:

varint+ slot count: The number of slots that follow.

For each slot:

varint+ slot index: The index of the slot.

varint+ timeline count: The number of timelines that follow.

For each timeline:

SLOT_* timeline type: The type of slot timeline.

varint+ frame count: The number of keyframes in the timeline.

For SLOT_ATTACHMENT:

For each keyframe:

float time: The time in seconds for the keyframe.

string attachment name: The name of the attachment to set on the slot, or null to clear the slot's attachment.

For SLOT_COLOR:

For each keyframe:

float time: The time in seconds for the keyframe.

color color: The slot color to set for the keyframe.

Curve curve: The keyframe's curve. The curve is omitted for the last keyframe.

For SLOT_TWO_COLOR:

For each keyframe:

float time: The time in seconds for the keyframe.

color light: The light slot color to set for the keyframe.

color dark: The dark slot color to set for the keyframe.

Curve curve: The keyframe's curve. The curve is omitted for the last keyframe.

varint+ bone count: The number of bones that follow.

For each bone:

varint+ bone index: The index of the bone.

varint+ timeline count: The number of timelines that follow.

For each timeline:

BONE_* timeline type: The type of bone timeline.

varint+ frame count: The number of keyframes in the timeline.

For BONE_ROTATE:

For each keyframe:

float time: The time in seconds for the keyframe.

float rotation: The rotation for the keyframe.

Curve curve: The keyframe's curve. The curve is omitted for the last keyframe.

For BONE_TRANSLATE, BONE_SCALE, and BONE_SHEAR:

For each keyframe:

float time: The time in seconds for the keyframe.

float x: The X translation, scale, or shear for the keyframe.

float y: The Y translation, scale, or shear for the keyframe.

Curve curve: The keyframe's curve. The curve is omitted for the last keyframe.

varint+ ik constraint timeline count: The number of IK constraint timelines that follow.

For each IK constraint timeline:

varint+ ik constraint index: The index of the IK constraint.

varint+ frame count: The number of keyframes in the timeline.

For each keyframe:

float time: The time in seconds for the keyframe.

float mix: The IK constraint mix.

boolean bend direction: The IK constraint bend direction.

Curve curve: The keyframe's curve. The curve is omitted for the last keyframe.

varint+ transform constraint timeline count: The number of transform constraint timelines that follow.

For each transform constraint timeline:

varint+ transform constraint index: The index of the transform constraint.

varint+ frame count: The number of keyframes in the timeline.

For each keyframe:

float time: The time in seconds for the keyframe.

float rotate mix: The transform constraint rotate mix.

float translate mix: The transform constraint translate mix.

float scale mix: The transform constraint scale mix.

float shear mix: The transform constraint shear mix.

Curve curve: The keyframe's curve. The curve is omitted for the last keyframe.

varint+ skin count: The number of skins that follow.

For each skin:

varint+ skin index: The index of the skin.

varint+ slot count: The number of slots that follow.

For each slot:

varint+ slot index: The index of the slot.

varint+ deform timeline count: The number of deform timelines that follow.

For each deform timeline:

string name: The name of the attachment for the skin and slot.

varint+ frame count: The number of keyframes in the deform timeline.

For each keyframe:

float time: The time in seconds for the keyframe.

varint+ end vertex: The index of the last vertex value. If 0, start vertex and the vertex values are omitted.

varint+ start vertex: The index of the first vertex value.

For each vertex value between start (inclusive) and end (exclusive):

float value: The amount to adjust the vertex relative to the attachment's setup pose.

Curve curve: The keyframe's curve. The curve is omitted for the last keyframe.

varint+ draw order count: The number of draw order keyframes that follow.

For each draw order keyframe:

float time: The time in seconds for the keyframe.

varint+ change count: The number of draw order changes that follow.

For each change:

varint+ slot index: The slot index to modify in the draw order.

varint+ amount: The amount to move the slot in the draw order.

varint+ event count: The number of event keyframes that follow.

For each event keyframe:

float time: The time in seconds for the keyframe.

varint+ event index: The index of the event for the keyframe.

varint- int: The integer value of the keyframe.

float float: The float value of the keyframe.

boolean has string: If false, string is omitted.

string string: The string value of the keyframe.

Skin format

varint+ slot count: The number of slots for the skin that follow.

For each slot:

varint+ slot index: The index of the slot the following attachments belong to for this skin.

varint+ attachment count: The number of attachments for the slot.

For each attachment:

string placeholder name: The name in the skin under which the attachment will be stored.

string name: The attachment name. If null, use the placeholder name. This is unique for the skeleton. For image attachments this is a key used to look up the texture region, for example on disk or in a texture atlas.

ATTACHMENT_* attachment type: The type of attachment.

For ATTACHMENT_REGION:

string path: If not null, this value is used instead of the attachment name to look up the texture region.

float rotation: The rotation in degrees of the image relative to the slot's bone.

float x: The X position of the image relative to the slot's bone.

float y: The Y position of the image relative to the slot's bone.

float scaleX: The X scale of the image.

float scaleY: The Y scale of the image.

float width: The width of the image.

float height: The height of the image.

color color: The color to tint the attachment.

For ATTACHMENT_BOUNDING_BOX:

varint+ vertex count: The number of vertices for the bounding box.

Vertices vertices: The bounding box vertices.

color color: The color of the bounding box in Spine. Nonessential.

For ATTACHMENT_MESH:

string path: If not null, this value is used instead of the attachment name to look up the texture region.

color color: The color to tint the attachment.

varint+ uv count: The number of UVs for the mesh.

For each UV:

float x: The X texture coordinate for the vertex.

float y: The Y texture coordinate for the vertex.

varint+ triangle count: The number of triangle points for the mesh that follow.

For each triangle point:

short vertex index: The index of the vertex for this point.

Vertices vertices: The mesh vertices.

varint+ hull count: The number of vertices that make up the polygon hull. The hull vertices are always first in the vertices list.

varint+ edge count: The number of edge points that follow which define the edges between connected vertices. Nonessential.

For each edge point:

short vertex index: The index of the vertex for this point. Nonessential.

float width: The width of the image used by the mesh. Nonessential.

float height: The height of the image used by the mesh. Nonessential.

For ATTACHMENT_LINKED_MESH:

string path: If not null, this value is used instead of the attachment name to look up the texture region.

color color: The color to tint the attachment.

string skin: The name of the skin that contains the source mesh. If null, the source mesh is in the default skin.

string parent: The name of the source mesh, which is always in the same slot as this mesh. If the source mesh is not in the default skin, this name is used to look up the actual attachment in the skin.

boolean deform: If false, deform timelines for the source mesh are not applied to this mesh.

float width: The width of the image used by the mesh. Nonessential.

float height: The height of the image used by the mesh. Nonessential.

For ATTACHMENT_PATH:

boolean closed: True if the last and first vertex are connected.

boolean constantSpeed: True if movement along the path uses constant speed.

varint+ vertex count: The number of vertices for the path.

Vertices vertices: The path vertices.

For vertex count / 3 lengths:

float length: The length in the setup pose from the start of the path to the end of each curve.

color color: The color of the path in Spine. Nonessential.

For ATTACHMENT_POINT:

float rotation: The rotation in degrees of the point relative to the slot's bone.

float x: The X position of the point relative to the slot's bone.

float y: The Y position of the point relative to the slot's bone.

color color: The color of the point in Spine. Nonessential.

Curve format

A curve defines the interpolation to use between a keyframe and the next keyframe: linear, stepped, or a Bézier curve.

The Bézier curve has 4 values which define the control points: cx1, cy1, cx2, cy2. The X axis is from 0 to 1 and represents the percent of time between the two keyframes. The Y axis is from 0 to 1 and represents the percent of the difference between the keyframe's values.

CURVE_* curve type: The type of curve.

For CURVE_BEZIER:

float c1

float c2

float c3

float c4

Vertices format

boolean weighted: True if the vertices are weighted.

If weighted is true:

For each vertex:

float x: The x position of the vertex relative to the slot's bone.

float y: The y position of the vertex relative to the slot's bone.

If weighted is false:

For each vertex:

float bone count: The number of bones that influence the vertex.

For that many bones:

float bone index: The index of the bone that influences the vertex. float bind position X: The vertex X position relative to the bone. float bind position Y: The vertex Y position relative to the bone. float weight: The weight for the bone.