KLAC logo KLAC Word puzzle Available for

Automate sprite management with Texture Packer

When it comes to mobile games, graphic assets management can be a serious pain. Mobile phones have limited graphic performances, therefore to achieve a good gaming experience developers must adopt various strategies.
Our upcoming game Aedo Episodes uses sprite packing technique to dramatically reduce draw calls. Packing merges all images in a single texture. This allows to batch all the drawing calls involving the same texture in one single call, gaining a huge performance benefit.

The trick is to group all images in logical containers, usually related to loading stages, for example all images for level 1, level 2… In this way, you have to organize all graphic assets in different folders. Don’t be scared to repeat some images used by multiple levels. By packing the images per level the benefits are vastly more than the extra memory used. Of course, if the game is very simple and has no loading screen, you can group all images at once.

Thanks to tools like TexturePacker the process of packing sprite is straightforward. Just open the tool, put your images and generate the texture. For extensive help, you can refer to the online guide. TexturePacker allows to save a project, a .tps file, that contains all packing configurations you set. This file includes the source images (you should import the whole folder) and the output file, thus the workflow becomes:

  • creating, editing images
  • open TexturePacker
  • publish the texture
  • run the game and test

Suppose you are the graphic designer in the creative phase, i.e. the loop of edit-test-edit-test. Dealing every time with the tool can become quite annoying. In addition, for sure, you will face the situation where you edited some images but the changes are not reflected in the game, and you begin to shake your brain asking yourself: “why? doesn’t work now! why? It worked two minutes ago …unreliable developers!”. And then your realize that you simply forgot to repack!

We extensively use gulp as task automata. So, why not use gulp to script the boring stuff? The overall logic will be: when some changes occur in the image folder(s), launch TexturePacker to republish the texture. Luckily, TexturePacker comes with a command line companion, so it is very easy to automate the process.

Here is a gulp task that do it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var fs = require('fs'),
path = require('path'),
exec = require('child_process').exec,
gulp = require('gulp'),
glob = require('glob'),
watch = require('gulp-watch'),
batch = require('gulp-batch');

var spritePath = 'assets/sprites';
var texturePackerCmd = '"C:\\Program Files\\CodeAndWeb\\TexturePacker\\bin\\TexturePacker.exe" ';

gulp.task('watch:sprites', function () {
glob(spritePath + '/**/*.tps', function (_, files) {
var pngs = files.map(function (file) {
var dir = path.dirname(file) + '/' + path.basename(file, '.tps');
return dir + '/*.png';
});

watch(pngs, { read: false }, batch({ timeout: 1000 }, function (events, cb) {
events.on('data', function (ev) { }).on('end', function () {
var dir = this._list[this._list.length - 1].base,
name = path.basename(dir),
tps = path.join(dir, '../' + name + '.tps');

exec(texturePackerCmd + tps, function (err, stdout, stderr) {
console.log(stdout);
console.error(stderr);
cb(err);
});
});
}));
});
});

Place the task in your gulpfile and, to run it, open the prompt and type:

1
gulp watch:sprites

Leave it executing while you work on the images.

The task assumes that you put all tps files in the spritePath, and there are folders with the same name of the tps files. For example: sprites/level1/*.png <– all images here sprites/level2/*.png <– all images here sprites/level1.tps sprites/level2.tps

So, when the script detects a change in a folder, it will use the relative tps file to repack the images.

Be sure to install the required modules:

  • glob
  • gulp-watch
  • gulp-batch

Do not use built-in gulp.watch as it has several performance issues (v3.9). Use the external module gulp-watch available via npm. The task uses gulp-batch as a throttler to prevent multiple runs when many file changes occur near-simultaneously, i.e. rename, paste 2+ images, etc… It could be better and a real debouncer, I know, but there is a story behind and, because basically it works, I want to preserve it.

This website uses cookies to improve your experience