Pack My Sprites is a program that generates sprite sheets from a collection of images made with Gimp. The process does not requires the user to produce any intermediate image files. Thus, all you have to do is drawing the image and listing which layers to use for each sprite, then the program will generate the sprite sheet from it. Pack My Sprites makes the modifications on the source images costless for the project. It was especially used during the production of Andy's Super Great Park.

Download

Pack My Sprites is available in source code form also on GitHub. It is written in C++.

Claw, Boost, CMake and docbook-to-man are required to compile the program. Gimp and Xcftools are required at run-time to process the images.

Presentation

A sprite packing software is a useful tool in game development and typically builds a large image file from several smaller image files. See for example Sprite Sheet Packer or TexturePacker among others.

As a 2D artist I am really bored by the steps I have to follow before I can see my drawings in the final product. Unfortunately, the classic sprite packing softwares ask me to follow the following steps each time I make a change in my source images:

Each of these steps is repetitive and useless, thus should be automatized. A first step toward automatization is to have a command line tool instead of a graphical interface. On this point, glue is going in the right direction, but it is not enough.

I want a sprite packing software that works with my source images: the XCF files I create with Gimp!

The purpose of Pack My Sprites is to reduce the time required to integrate graphic updates into the final product. In order to achieve this goal, Pack My Sprites automates the generation of the sprites and helps its integration in the build process of the product.

The default behavior of the program is to parse an input text file to generate some sprite sheets and a listing of the localization of their sprites. The input file must describe each sprite with a unique name, the layers to show to build them, and their final size in the sprite sheet. The output is a PNG file containing each sprite and a text file associating the position and the size of each sprite with its name. See the input format for details about the syntax of the input file.

Eventually, Pack My Sprites can also generate a makefile whose rules build the sprite sheets, with dependencies on the XCF files and the input text file.

The software relies upon the gimp-console and xcfinfo programs for the generation of the sprite sheets.

Usage example 1

This example uses an animation of the flying bird from Andy's Super Great Park and is available in the download. Here is a capture of the image in Gimp:

To produce the sprite sheet from this image and another one, I write the following file:

/* file bird.spritedesc */
sprite_sheet "bird" 256 x 256 order "height"
/* The source images. */
fly "bird-fly.xcf.bz2"
afraid "bird-afraid.xcf.bz2"
/* The sprites. */
"afraid" autosize * 0.33 with afraid
"eyes"
"beak"
"body"
"tail"
;
"fly 1" autosize * 0.33 with fly
"body"
"eyes"
"back wing 1"
"wing 1"
;
"fly 2" autosize * 0.33 with fly
"body"
"eyes"
"back wing 2"
"wing 2"
;
"fly 3" autosize * 0.33 with fly
"body"
"eyes"
"back wing 3"
"wing 3"
;
"fly 4" autosize * 0.33 with fly
"body"
"eyes"
"wing 4"
;
"fly 5" autosize * 0.33 with fly
"body"
"eyes"
"wing 5"
;
"fly 6" autosize * 0.33 with fly
"body"
"eyes"
"back wing 6"
"wing 6"
;
"fly 7" autosize * 0.33 with fly
"body"
"eyes"
"back wing 7"
"wing 7"
;
"fly 8" autosize * 0.33 with fly
"body"
"eyes"
"wing 8"
;

Then I execute the following command to generate the sprite sheet:

pack-my-sprites bird.spritedesc

The command produce two files. The sprite sheet:

and a file containing the localization of the sprites in the sprite sheet:

fly 1: 0 0 75 84
fly 2: 76 0 75 84
fly 3: 152 0 75 84
fly 4: 0 85 75 84
fly 5: 76 85 75 84
fly 6: 152 85 75 84
fly 7: 0 170 75 84
fly 8: 76 170 75 84
afraid: 152 170 94 69

Usage example 2

Here is another example of input file:

/* Comments are written like this. */
sprite_sheet "name" 1024 x 1024 margin 1 order "height"
logo "logo.xcf.bz2"
/*
This entry produces a sprite with all layers whose name start
with "andy" followed by a space. The resulting sprite is the
part of the image bounded by the layer named "andy color" and
reduced to a quarter of its size.
*/
"andy's" "andy color" * 0.25 with logo
glob "andy *"
;
/*
This entry produces a sprite by merging two given layers. The
resulting sprite is cropped to the bounds of the merged
layers and reduced to one third of its size.
*/
"wave" autosize * 0.3 with logo
"wave"
"wave border"
;
/*
This entry produces a sprite by merging all layers whose name
start with "letters", and cropping the result to the bounds
of the layer named "par_K_". This layer is also used as a
mask in the resulting sprite.
*/
"par_K_" autosize * 0.3 with logo
glob "letters*"
mask "par_K_"
;

The processing of this file will produce two outputs: an image named letters-1.png and a text file named letters-1.spritepos. The latter contains the following localization of the sprites in the image:

wave: 0 0 1002 186
andy's: 0 187 268 168
par_K_: 269 187 120 118

Input Format

The input files can contain one or several sprite sheets. Each one begins with the sprite_sheet keyword, followed by the name of the sprite sheet and the maximum size of the output image, according to the following syntax:

sprite_sheet "name" width x height [margin M] [order "O"]

The margin M optional argument allows to define the spacing between the sprites in the output. The default value is 1.

The order "O" optional argument allows to force a given heuristic for the placement of the sprites in the output. The default value is "area", which considers the sprites in decreasing order of their area. Other possible values are "height" to select the sprites by decreasing order of their height or "none" to consider the sprites in their declaration order.

Following the header is a list of XCF files used to build the sprites:

image_name_1 "file_name_1"
image_name_2 "file_name_2"

Then come the sprites, defined by a name, a size, a source image, a selection of layers and an optional mask:

"name" reference_box * scale_factor with image_name
layer_selection_1
layer_selection_2
[mask "layer_name"]
;

The reference_box can be the name of a layer from the source image, or one of the following special values:

autosize
The box is the smallest one that contains all the selected layers.
image_size
The box is the one of the canvas in the input image.

The scale_factor is a positive value that determine the size of the sprite in the output. For example, a value of 0.5 will produce a sprite half the size of the reference box.

The layer selection has different formats:

"layer_name"
Selects the layer with the given name in the source image.
glob "pattern"
Selects all layers whose name match the given pattern. The pattern can contain the following special charaters:
*
Matches any sequence of symbols, empty sequences included.
.
Matches a single symbol.
?
Matches zero or one symbol.
exclude "layer_name"
Forces the layer with the given name in the source image not to be selected. This is useful to remove a layer from a glob expression.
exclude glob "pattern"
Forces the layers whose name match the given pattern not to be selected.

The optional mask instruction tells to use the layer with the given name as a mask in the resulting sprite. The white parts of the layer will be opaque in the resulting sprite, while the black parts will be fully transparent. Intermediate grey values will be partially transparent.

License

Pack My Sprites is written by Julien Jorge <julien.jorge@gamned.org>. It is hereby licenced under the terms of the version 3 of the GNU General Public Licence.