While there is some documentation for the *.spr file format, it can be underwhelming and full of technical jargon. This post aims to provide an easy to follow tutorial for the creation your own sprites so together we can populate the sprite network with an even larger amount and variety of random sprites.
Table Of Contents
- Table Of Contents
- What is a sprite?
- The anatomy of a sprite.
- States
- Parameters and Values
- X and Y values
- Cropping and Displaying a Frame
- State Chains
- Animated GIFs
- Inheritance
- SPRITE_META_DATA
- actions specify to the sprite engine what the sprite is capable of doing.
- flags turn on special behaviors for the sprite.
- credits provides the sprite engine with details of the person who created that sprite.
- version
- spawn is used to spawn other sprites upon death.
- Sprite Death Animations
- Using flipX for easy Left and Right states
- Transparency
- Offsets
- Fixtures
- Sprite Validation
What is a sprite?
If you right click your favorite sprite and open it with notepad, you’ll notice it is nothing more than plain text. This text tells the sprite engine how and what to display. When a sprite is opened, this text is read by the sprites engine which is then rendered using the sprites engine according to the file’s contents:
The anatomy of a sprite.
A quick glance over this file shows its parts: SPRITE_META_DATA contains miscellaneous info on the sprite, SPRITE_STATE_DEFAULT contains common parts, and it has stand and walk states (for both left and right). Each of these items are formatted in a very specific format (known as JSON) so that the sprites engine can read and render them easily. Basically every item in the text file falls into one of these categories: state, parameter, or value.
Even though Sprite Editor manages all of this under-the-hood for you and makes sure that the file is correctly formatted, you should be familiar with the underlying anatomy.
Here is the same sprite from above but showing its parts:
States
This is the fundamental backbone of the sprites engine. Sprites engine is basically a Finite State Machine (FSM). In simpler words, what it does at that moment depends on the input that you give it. If the sprite is standing there doing nothing, it displays SPRITE_STAND state. If you hit left arrow key to move him to the left, it displays SPRITE_STATE_WALK. It chooses which one from the LEFT or RIGHT states depending on which direction the sprite is facing at that time.
There are many more states which are all triggered by various actions performed by the user. Here is a table showing all possible states:
STATE | Trigger Input |
---|---|
SPRITE_META_DATA | None |
SPRITE_STATE_DEFAULT | None |
SPRITE_STATE_STAND_LEFT | Idle (Facing left) |
SPRITE_STATE_STAND_RIGHT | Idle (facing right) |
SPRITE_STATE_WALK_LEFT | Left Arrow Key |
SPRITE_STATE_WALK_RIGHT | Right Arrow Key |
SPRITE_STATE_JUMP_LEFT | Space Bar |
SPRITE_STATE_JUMP_RIGHT | Space Bar |
SPRITE_STATE_DESTROY_LEFT | Double Click |
SPRITE_STATE_DESTROY_RIGHT | Double Click |
SPRITE_STATE_RUN_LEFT | Hold Left Arrow Key |
SPRITE_STATE_RUN RIGHT | Hold Right Arrow Key |
SPRITE_STATE_FLY_LEFT | Idle (fly param specified) |
SPRITE_STATE_FLY_RIGHT | Idle (fly param specified) |
All of these states are displayed depending on user input, with a few exceptions. SPRITE_META_DATA is special because it holds a basic description of the sprite. It tells who authored the sprite, the actions it is capable of, the flags which modify its behavior, version number, and a spawn parameter which means the sprite can actually spawn other sprites (more on this later).
You’ll notice in the above table that FLY left and right states have the fly parameter as their trigger. To use these states you must specify that the sprite is a FLYER by using a parameter in SPRITE_META_DATA. More on parameters next.
Parameters and Values
A parameter is basically specifies which part of the sprite you are setting and the value is what you are setting it to. Since parameters are nested within and associated with a particular state, it just tells additional detail about how to render that state.
For example, the walkMultiplier parameter specifies the speed of which the sprite walks. If it is not specified, it walks at the default speed. If you set it to 2, the sprite will walk twice as fast when the user presses the arrow key. In this example, walkMultiplier is the parameter and 2 is the value of that parameter.
Within each state, you will find nothing more than a nest of parameters and their associated values. There are two types of parameters: attributes and properties.
SPRITE_META_DATA is unique since it only contains unique “attribute” parameters that describe the file such as telling who the author is, the actions the sprite performs, the version number of the sprite, etc. All other “property” parameters are universal and can be used in any valid non-metadata state.
Property parameters must have an attached value and must be found within a valid state from the table above. Here is a complete list of possible params:
Name | Type | Value | Description |
---|---|---|---|
actions | attribute | Parameters | Specifies which actions the sprite has. Valid parameters are walk, fly, run, jump, destroy, or death. |
flags | attribute | Parameters | Specifies which flags the sprite has. Valid parameters are isCollector, isItem, disablePhysics, disableWindowCollide, disableSpriteCollide. disableJump. or doFadeOut. |
version | attribute | Integer | Specifies the version number of the sprite. Used by sprite server to determine if the user has the newest version of a sprite. |
credits | attribute | Parameters | Specifies the sprite creator’s details. Valid parameters are author, description, and url. |
spawn | attribute | String | Specifies a *.spr or *.spi file to spawn when the sprite is closed. |
fixtures | attribute | Parameters | Specifies specific clipping areas. See Fixtures at bottom of page. |
uri | property | String | Similar to URLs that you put into web browser. This specifies a file location. Used mostly to specify the name of the image or sprite sheet that the spr uses. You can just use the filename itself without the path as long as your *.spr file is in the same directory or a subdirectory. |
flipX | property | Flag | If set to 1, the sprite is flipped or mirrored vertically. Useful if you have a LEFT state and want the RIGHT state to mirror that while facing the opposite direction. |
sizeMultiplier | property | Integer | This increases the size of the rendered sprite. If the sprite source sheet or image is way too small, use this to increase the size. |
sizeDivider | property | Integer | This decreases the size of the rendered sprite. |
frameDelay | property | Integer | When a state is animating, there is a delay in milliseconds between each frame. This specifies the amount of time for each frame. |
cropX | property | Integer | Sets the X value of the crop area. See: Cropping |
cropY | property | Integer | Sets the Y value of the crop area. |
cropW | property | Integer | Sets the width of the crop area. |
cropH | property | Integer | Sets the height of the crop area. |
offsX | property | Integer | After you select an area of the spritesheet to display, it centers automatically. If one STATE has a larger or smaller size than another it may cause the sprite not to line up correctly. This param is used to offset a frame’s X value so that each state lines up better. |
offsY | property | Integer | Offsets the Y value, similar to above. |
isChain | property | Flag | If set, it specifies that there are multiple frames to display in the current state (animation). |
usePrevious | property | Flag | If on, this uses the values from the previous animation state. |
autoClose | property | Flag | When this is on, it causes the sprite to close. |
transparent | property | String | If the sprite sheet does not have a transparent background, you use this parameter to specify the color to make transparent. It is a HTML HEX color code. |
walkMultiplier | property | Integer | Amount to speed up the walking of a sprite. |
Notice each parameter has a specific type of value that it takes. If it takes parameters, it is a special case and is only used in Metadata (check the description). If it takes integers, it must be a valid numeric input. Others take strings such as file names and HTML hex codes. Finally, there is flags. Flags take the value either zero or one. 1 means the flag is on, 0 means it is off (which is the default).
X and Y values
A quick tangent on co-ordinate systems:
These should sound familiar from your high school algebra classes since everyone has studied the Cartesian coordinate system that uses the (x,y) ordered pairs format to depict locations on a plane:
In the above diagram: up is +Y, down is -Y, right is +X, and left and -X. Windows uses a modified version of this. Basically the Y axis is flipped: up is -Y, down is +Y, right is +X, left is -X. Here is a diagram to further illustrate this:
All sprites and all windows applications use these coordinates so make sure you are using correct Y values! The origin (0,0) is always at the top left corner of a sprite or window. Sprite Editor does handle coordinates for you under-the-hood if you use it to Crop or Grab Y values.
Cropping and Displaying a Frame
Now to illustrate the concept of how the sprite engine chooses what to display, lets look at a sprite submitted by IceAge: Bald Bull from Punch Out! Here is the source sprite sheet that he used:
Now look at this section of Bald Bull.spr:
"SPRITE_STATE_DEFAULT": {
"uri":"Bald_Bull_Idle.png",
"cropX":"0",
"cropY":"0",
"cropW":"62",
"cropH":"140"
}
This tells the sprite engine that the image to crop from (uri) is “Bald_Bull_idle.png”. To crop the image, it provides X, Y, W, and H values. This is the X, Y, Width, and Height of a rectangular area of the sprite sheet to select, crop, and display. The units are in pixels, which just represents one small colored dot on the monitor. If you open the above sprite sheet in Windows Paint and zoom in as far as possible you will see this:
Each one of those squares is 1 pixel. Also notice that when you move your cursor over the image it will tell you the coordinates on the bottom left corner in MS Paint.
So the above code is saying to crop at X,Y values of (0,0) with a width of 62 pixels and a height of 140 pixels. This is the result (in the red rectangle) of what is cropped and displayed:
The top left corner of the rectangle is (0,0), the top right corner is (62,0), the bottom left corner is (0,140) and the bottom right corner is (62,140). So when SPRITE_STATE_DEFAULT is the current state, this is what is displayed to the user!
State Chains
So now you know how to display an image for any given state, from SPRITE_STATE_STAND_LEFT to any other one you wish. The problem? You are only specifying one crop area per state so the sprite will not appear to animate and will just stay in this one frame that you have specified using cropX/Y/W/H values. If you need to display more than one frame in a specific state, you will have to use chains.
Chains are a simple concept. You just tell the sprite engine that it is a chain, then number each state incrementally. Look at this code from Bald Bull.spr:
"SPRITE_STATE_STAND_RIGHT": {
"isChain":"1",
"cropX":"0",
"cropY":"0",
"cropW":"62",
"cropH":"140"
},
"SPRITE_STATE_STAND_RIGHT_0": {
"cropX":"63"
},
"SPRITE_STATE_STAND_RIGHT_1": {
"cropX":"125"
},
"SPRITE_STATE_STAND_RIGHT_2": {
"cropX":"187"
},
"SPRITE_STATE_STAND_RIGHT_3": {
"cropX":"249"
},
"SPRITE_STATE_STAND_RIGHT_4": {
"cropX":"311"
}
As you seen in the previous section, this is telling the sprite engine that when bald bull is in his SPRITE_STATE_STAND_RIGHT state to crop the rectangular area x=0, y=0, width=62, and height=142. This is the same area that was highlighted in the picture from the previous section, shown by the red rectangle!
What is new here is the “isChain”: “1” and the numbered states. You have to tell the sprites engine that you need to display multiple frames for a state by setting isChain: 1, then you enumerate the states. By enumerating the states, I mean:
The 1st frame that is displayed is specified in SPRITE_STATE_STAND_RIGHT_0, the 2nd is SPRITE_STATE_STAND_RIGHT_1, the 3rd is SPRITE_STATE_STAND_RIGHT_2, and so on. So the above code provides an animation of 5 frames when bald bull is facing his right side, all displaying different rectangular areas of the source sprite sheet.
Note that chains start with STATE_NAME_0 instead of STATE_NAME_1!
Animated GIFs
Cropping can be a time consuming process, even if you use the sprite editor’s quick crop or X/Y grabbing capabilities. If you want to save time, just use animated gifs! Each frame of an animated gif will automatically be rendered as if it were a chain. All you have to do is provide the URI (filename) of each gif file for each state and there is no need to worry about X and Y values.
Inheritance
Inheritance can be overwhelming at first but at its core it is a very simple concept and allows you to save time when creating sprites. Notice how the STATE_NAME_0, 1, 2, 3, and 4 above did not specify cropY,W,H values? They were unnecessary because of inheritance.
If you specify a parameter in any SPRITE_STATE_* such as SPRITE_STATE_STAND_RIGHT, then each of the following chains (SPRITE_STATE_STAND_RIGHT_0, SPRITE_STATE_STAND_RIGHT_1, etc.) will also have the same parameter set to the same exact value unless you specify otherwise. In this example, SPRITE_STATE_STAND_RIGHT is the parent state and SPRITE_STATE_STAND_RIGHT_0 is the child state.
The only thing that changed was the X value in each frame since the Y was always 0, width was always 62, and the height was always 140. So the sprite engine knew that SPRITE_STATE_STAND_RIGHT_0 would have the values of “cropY”:”0″, “cropW”:”62″, “cropH”:”140″.
So the example from above that introduced chains effectively functions the exact same as this, thanks to inheritance:
"SPRITE_STATE_STAND_RIGHT": {
"isChain": "1",
"cropX": "0",
"cropY": "0",
"cropW": "62",
"cropH": "140"
},
"SPRITE_STATE_STAND_RIGHT_0": {
"cropX": "63",
"cropY": "0",
"cropW": "62",
"cropH": "140"
},
"SPRITE_STATE_STAND_RIGHT_1": {
"cropX": "125",
"cropY": "0",
"cropW": "62",
"cropH": "140"
},
"SPRITE_STATE_STAND_RIGHT_2": {
"cropX": "187",
"cropY": "0",
"cropW": "62",
"cropH": "140"
},
"SPRITE_STATE_STAND_RIGHT_3": {
"cropX": "249",
"cropY": "0",
"cropW": "62",
"cropH": "140"
},
"SPRITE_STATE_STAND_RIGHT_4": {
"cropX": "311",
"cropY": "0",
"cropW": "62",
"cropH": "140"
}
Important: SPRITE_STATE_DEFAULT is the parent of all other states. Any parameter that you specify in DEFAULT will propogate down to all other STATES through inheritance, unless you specify otherwise. This is why we can specify the uri of the image in DEFAULT and not have to worry about adding it to each other state.
Here is a diagram showing the heirarchy. Note that SPRITE_STATE_* means any state:
SPRITE_META_DATA
As mentioned in the states section, metadata is unique in that it describes the file itself. It is the first thing looked at by the sprite engine. As such, it has special “metadata” parameters and values that are attached to it: actions, flags, credits, version, spawn, fixtures.
actions specify to the sprite engine what the sprite is capable of doing.
For each item listed in this list of actions, there will be a corresponding state. Here is a table summarizing each action and what STATE the action indicates to the sprite engine:
Metadata action | Indicates |
---|---|
walk | SPRITE_STATE_WALK_LEFT and SPRITE_STATE_WALK_RIGHT |
run | SPRITE_STATE_RUN_LEFT and SPRITE_STATE_RUN_RIGHT |
fly | SPRITE_STATE_FLY_LEFT and SPRITE_STATE_FLY_RIGHT |
jump | SPRITE_STATE_JUMP_LEFT and SPRITE_STATE_JUMP_RIGHT |
death | Sprite will have a corresponding Death animation. |
destroy | SPRITE_STATE_DESTROY and SPRITE_STATE_DESTROY_RIGHT |
flags turn on special behaviors for the sprite.
Here is a list of all supported flags:
Flag | Description |
---|---|
isCollector | Indicates the sprite can pick up items in the form of other sprites. |
isItem | Indicates the sprite is collectable by isCollector sprites. Used for sprites such as coins and items. |
disablePhysics | Disables the sprites physics engine for this sprite. |
disableWindowCollide | Diables the sprite from colliding with any windows. |
disableSpriteCollide | Disables the sprite from colliding with other sprites. Useful for props and scenery such as trees. |
disableJump | Denies the sprite the ability to jump. Added specifically for zombie sprite so he doesnt go crazy when auto-move is turned on. |
doFadeOut | This enables the default sprite death animation, which is just a slow fade out. |
Sprite Editor also helps editing and adding flags to Metadata. If the flags parameter is not present in Metadata, right click SPRITE_META_DATA and Add Parameter > flags. Once added, you can right click flags in the tree and select Add Flag and it will show a list of all valid flags.
credits provides the sprite engine with details of the person who created that sprite.
If you right click a sprite, you can see these. Note that a sprite can have many sets of credits, each with an author, description, and url. Here is a list of parameters:
Parameter | Description |
---|---|
author | Name of the person who crated the sprite. |
description | Text to display on right click. |
url | URL of author’s website which launches when right click menu is selected. |
SPRITE_META_DATA, SPRITE_STATE_DEFAULT, credits, and version are automatically added to new files in Sprite Editor. To add more than one set of credits, right click the [1] in the tree under credits and select “Add New Group”.
version
stores an integer value indicating how new the sprite is.
If a submitted sprite has an error, it can be revised with a higher verison number and the sprites engine will make sure everyone’s local copy will get properly updated.
spawn is used to spawn other sprites upon death.
This is useful for creation of death animations, which conventially are stored in a seperate file. See Sprite Death Animations.
fixtures help with overly large sprite clipping areas. See fixtures.
Sprite Death Animations
As of now there are two methods for creating sprite death animations:
- You can use SPRITE_STATE_DESTROY_* state and the destroy attribute to create the animation within the existing *.spr file.
- You can use a seperate *.spi file and the spawn attribute to encapsulate the death animation in a seperate file.
For 1, look at Taz.spr by IceAge as an example. He included “death” as an action in metadata and then provided the correspondign DESTROY states and uses an animated gif for them:
"SPRITE_STATE_DESTROY_LEFT": {
"uri": "Taz_Death.gif"
},
"SPRITE_STATE_DESTROY_RIGHT": {
"uri": "Taz_Death.gif"
}
Here is what it looks like when he dies (without the loop, of course):
For 2, look at Jason.spr by caustik as an example. In the metadata, he included a “death” action and a “spawn” attribute:
"spawn":
[{
"uri": "Jason (Death).spi",
"spawnX": "0",
"spawnY": "0"
}
]
When the sprite is destroyed, it spawns an external file “Jason (Death).spi” which then handles the death animation. here is that file:
{
"SPRITE_META_DATA": {
"credits":
[{
"author": "Caustik",
"description": "Scripted by Caustik (caustik.com)",
"url": "http://www.caustik.com/"
}
]
},
"SPRITE_STATE_DEFAULT": {
"uri": "jasonsophia.png",
"sizeMultiplier": "2",
"frameDelay": "200",
"cropX": "325",
"cropY": "129",
"cropW": "16",
"cropH": "16",
"transparent": "0088FF",
"autoClose": "1",
"isChain": "1"
},
"SPRITE_STATE_DEFAULT_0": {
"cropX": "205"
},
"SPRITE_STATE_DEFAULT_1": {
"cropX": "285",
"cropY": "128"
},
"SPRITE_STATE_DEFAULT_2": {
"cropX": "325",
"cropY": "124"
}
}
*.spi files are traditionally used to encapsulate death animations, but this is not necessary since you can just use DESTROY states instead. Also notice caustik uses “autoClose: 1” to make sure the sprite closes after the death animation is complete instead of looping indefinitely.
Using flipX for easy Left and Right states
The flipX parameter can be used to save time when creating sprites. All it does is flip the X coordinates of the image, effectively mirroring or flipping the image vertically.
This is useful if you have a STATE_*_RIGHT and need to create an appropriate LEFT state as well. All you have to do is use the same exact parameters from the RIGHT state and include flipX: 1 to create a mirrored version.
Transparency
Also, if a sprite sheet does not have a transparent or colorless background then it will be shown when you load your sprite up making it look ugly. This is what the “transparent” parameter is for. if you look at Bald Bull’s spr file text contents once again, you’ll notice that it has “transparent”:”bafeca” in his SPRITE_STATE_DEFAULT section. The BAFECA is just a HTML hex color code.
The way you count in HEX is 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. Hex is base-16 while our number system is only base-10, so the letters (A to F) indicate the extra digits (10 to 16). The color code’s first two digits are RED, second two are GREEN, last two and BLUE. 0 is darkest and F is the lightest. So FFFFFF would be white. 000000 is black. FF0000 is pure red. 00FF00 is pure green. 0000FF is pure blue.
You do not have to fret over learning HTML hex color codes. Sprite Editor makes it easy!
Offsets
If you crop areas of different widths or heights, the sprite engine may not properly align them since it does a best guess and centers the frames. Maybe the third frame is too far to the left and it looks weird, or the last frame is up too high. You can fix this using the offsX and offsY parameters.
The offsX parameter specifies an offset value in the X direction of the current frame. If the misaligned frame is to the left or right, use this to correct it. The units for this are in pixels. Similarly, offsY is for the Y value and can correct frames that are displayed too high or too low.
Fixtures
Fixtures are a hack for sprite clipping areas. Basically, it allows you to combine seperate areas fo a sprite sheet into one frame. The way you do this is by specifying X, Y, W, and H values for each crop area within the fixtures array.
These are useful if your sprite has large empty or transparent area surrounding it but it still collides with other sprites, without appearing to actually touch them.
Sprite Validation
Sprite Editor has validation built in to help you make sure the structure of your creation is perfect. It will display a red X on the bottom right corner if there is an error, or a green checkmark if all is good. Here is a list of all that is checked for:
- States
- Must be in all caps
- SPRITE_META_DATA and SPRITE_STATE_DEFAULT are required.
- Must be a known state name, matched from a list of possible states.
- Parameters
- Must be a known parameter, action, or flag name.
- Values
- Flags must be 0 or 1.
- URIs must contain a valid filename.
- HTML Hex color codes must be six digits.
- Integers must be a parseable number.
- Doubles must also parse.
- URLs must be valid links.
- Checks if param is listed without a corresponding value.
- Checks if param is blank or whitepsace.
- Other
- Array indices must be in the form [n] and have appropriate subnodes.
- Chains must have isChain:1 set.
- Checks if isChain:1 is set and there is no subsequent incremented state.
- Chain numbers must be sequential.