Every byte count - Optimization Tricks
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
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
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
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
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");
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");
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
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!