Home » Programming

Every byte count - Optimization Tricks

By Pascal Bestebroer 11 November 2007 No Comment

In this article I will give you some helpful tips on how to decrease your JAR files, and will also introduce you to a tool we developed and use at OrangePixel: PNGSplitter. The magical tool that will strip kilobytes of your jar files!


Ever since the first games were developed for mobiles, there has been a major problem of storage room. Even tho these days the storage available on phones for game files has increased, it is still a good idea to try and get your files as small as possible. In this article I will give you some helpful tips on how to decrease your JAR files, and will also introduce you to a tool we developed and use at OrangePixel: PNGSplitter. The magical tool that will strip kilobytes of your jar files!

The tips

Many tips can be found on the internet on how to reduce the file size of your JAR. I tried to get most of the tricks we use in this article, to give you one very good resource. After that we will give you the ultimate tool for reducing your image sizes.


Tip 1:
Directory structures. Most developers and artists will want to use directories to place their files in an orderly fashion. If you learned Java the official way, you will most likely have classes in a hierarchy of directories. Now that’s all nice and sweet, but when we want every byte in a JAR file to count, we can certainly do much better by not using any directories at all. For the basic reason that a directory name alone is a few bytes that could otherwise be used for some small code.

So try to get rid of the directories, and just dump all the resources and class files into the JAR file without a hierarchy. You can even use compilation tools to take care of this for you, so that you can still work with a pretty directory structure, but when it comes time to deploy the final game files, you can get rid of those.


Tip 2:
File names. A logical sequel to Tip 1, is of course the file names you use. The shorter you keep them, the more bytes you save in the final Jar file. Again it only saves a few bytes from your Jar file, but we are trying to make every byte count in this article!


Tip 3:
Check and recheck. In many (and I mean MANY) game files you will see files that are not supposed to be there. The most found file is probably Thumbs.db. A system file created by Windows that contains thumbnail versions of the images from a certain directory. This file is usually hidden from your file-explorer, but very much visible in a Jar file. On top of that the file is always a few kb in size! You can turn off the thumbnails in your windows file-explorer, and it’s a smart thing to do when you are developing.

Next to the Thumbs.db, make sure you are only collecting resources files that are really used! Way to often there are files there that are simply to big or not optimized to their fullest (mainly images).


Tip 4:
Image optimization. The most of your optimization can be done in the image department. Use less colors, put multiple images in one png file, and use tools to improve the optimization even more (see below). Get to know the tools that are available for image optimization, in most cases your artist will use a paint program like Paintshop or Photoshop, and these programs are not the best for optimizing png images.

Myths

Some myths in the world of file size optimization:


Tip 1:
Optimizing level data. Nice idea to create tools that optimize your game level data. Like maybe some simple crunching algorithms. However, a Jar file is basically a ZIP file. So in 99% of the cases it will crunch your data a lot better then any tools you can come up with. Level data is usually in a fairly basic binary file, and such a file will be compressed very good by the compression used in Jar files. So leave your level data alone, don’t create crunching tools!


Tip 2:
Bin compilers. Often people will use a Bin compiler to “pack” multiple data files into one big file. This obviously a nice thing, but it doesn’t really do anything to help your file size, and in some cases it will actually be bigger then your normal files due to a resource-location-table that has to be included in either the bin-file or the source-code. The downside of a large bin file is the fact that you have to seek the right data from within your J2ME code, so that loading most likely will be slower. The upside is that it gives a little extra protection to your resources, and it can be easier for distributing new content for a game (only one file to send). So make sure you understand the ups and downs on this one!

Optimization of images

There are various ways to optimize your images. From simply using less colors, to using special tools that optimize the PNG data, it can strip multiple kilobytes from your final Jar file. The way we do it at OrangePixel is the following:


Step 1.
First you have to create your images (obviously). But you have to use the same 256 color palette for all images. You can do this by copying all images into one big empty image, and then decreasing colors to 256 in your favorite ArtyFarty program. Save that palette, and load that palette for each of your images


Step 2.
Copy all your images into the pngcompress/ directory that can be downloaded here.


Step 3.
After copying, run the orangepixel.bat file, this will optimize all the images in the directory while retaining their palette.


Step 4.
Run our tool called PNGSplit.


Step 5.
Click on the button labelled “Split”  and select the optimized images from the pngcompress/ directory


Step 6.
Wait a second


Step 7.
In the pngcompress/ directory there should now be all your graphic files, stripped from their extensions AND most importantly stripped from their palette!

How does this help? Well since every image uses the same palette, there is no sense in having that same data for every image. So PNGSplit gets the palette, saves it as a file named “PAL” and then strips the palette-chunk from all your PNG’s.  Seeing as a 256 color palette is 768 bytes in size, you can save a lot of bytes if you have many images (the more images you have, the more data you can save obviously).

By using the PAL file and the RAW-png files (the files without extension) you will save a lot of data….but..you might find they don’t load in your J2ME midlet anymore. Have no fear, we will supply you with the source code for loading these RAW-png’s !

RAW-PNG loader

The most important part is the class file we named oPNG.java. You can download the source code here. This class file is very small and easy to use. What’s that? You want to know how to use it? Well lucky you! Read on!

First thing is to create an instance of the oPNG class:

// used for RAWPNG handling
public static oPNG rawPNG;

// initialise our object and load the palette file
rawPNG = new oPNG("/pal");
As you can see we specify the /pal file that was created with PNGSplit as the palette file of our choice. This will then initialise the rawPNG object, and it is now ready for use. We kept the usage very similar to the usage of the Image class. So it should only be a matter of copy and paste when you want to use rawPNG’s instead of normal PNG files.

To load an image you would normally do this:

monsters[4]=Image.createImage("/bat.png");

Now that we use rawPNG we simply change that to:

monsters[4]=rawPNG.getRawPNG("/bat");
As you can see, loading of the rawPNG files is very basic stuff, you will hardly notice any changes.
There are a few more methods in the oPNG class, these are to draw rawPNG images onto an existing Image object, or loading a rawPNG file from a Binary data file. The methods are:
// draw a rawPNG image onto the canvas of monsters[4]
drawRawPNG("/bat",monsters[4],0,0);

and

monsters[4]=rawPNG.getRawPNGBin("/bat",fileoffset_of_bat_file);

Finally

All our games use the rawPNG files, and it has saved us many times to get our games running on the old Nokia Series40 devices with their 63kb file size limit. As you have noticed with PNGSplit there are a few other buttons and options. These are for more advanced usage, and require a little understanding of the PNG file structure.

For example, you could remove the TRANS chunk from all png files that don’t need any transparency at all. This might save you a few more bytes here and there, but is mostly not really that impressive.

Enjoy the PNGSplit tools, and if you have any questions don’t hesitate to drop them below this article!

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.