Entries in pipeline (1)

Wednesday
Jun202012

Optimising my (simple) graphics assets pipeline

I recently optimised my games graphics asset pipeline as it's in-efficiency had been bugging me for ages.

The original process for updating/adding graphics to my games was:

  1. Open the graphic .psd file in Photoshop and do required edits
  2. Run a Photoshop action that exports the graphic into a retina and a normal sized .png
  3. Open up my retina Zwoptex file and export a new retina sized spritesheet
  4. Open up my regular Zwoptex file and export a regular sized spritesheet
  5. Build the game in Xcode.

This was pretty crappy and full of repetitive manual steps. Everytime I went through this process, I would think "this should really be scripted"... Finally I've gotten around to it!

Basically, the desired outcome would be to take a retina sized .png file, drop it (or export to) my assets directory and then that's it, everything else would be automated during the build.

The first step was to write a simple script to do all the spritesheet stuff, which would be called by Xcode when doing a build. Unfortunately, Zwoptex didn't have command line support so I went searching for an alternative. I eventually settled on TexturePacker which looking from the documentary, was very programmer friendly and had full command line support. After using it for a while, I'm very happy with it, it offers a few helpful features missing from Zwoptex such as dithering.

So I whipped up a Perl script which would call TexturePacker with the required arguments to suck in all the .pngs from a specified directory and spit out spritesheets. Also keeping in mind I would be calling this from an Xcode build target, so included handling of the appropriate parameters.

Here is the script if you are interested in taking a look.

The script usage is as follows:

buildspritesheet.pl <clean> <inputdir> <outputdir> <sd_out> <hd_out>

With <clean> being either set or not set (Xcode either passes in "clean" or nothing). The script when run, will spit out a normal sized sprite sheet <sd_out>, and a retina sized sprite sheet <hd_out>. Or, if "clean" has been passed in will delete the current sprite sheets.

Okay, so now that the script was done, I simply needed to get Xcode to call it when doing a build. This was done by creating a new "External Build System" target in Xcode:

If the game uses more than 1 spritesheet, I simply create multiple "External Build System" targets.

Once the target was created, I set "Build Tool" to "/usr/bin/perl", to be able to run my script, and then in "Arguments" passed in the script and appropriate arguments:

I then did a test of running and cleaning the target in Xcode to make sure everthing was cool, and then set this new target to be a dependancy of the game target:

And then I was done!

My new, more efficient process to update/add graphics is:

  1. Open the graphic .psd file in Photoshop and do required edits
  2. Export to .png
  3. Build the game in Xcode

With this new process, I can simply just drop or export new .pngs into my game's asset folder and be done. Converting to spritesheets is now a fully automated process that is part of building the game.