I think that there are so many different compression tools and byte-saving techniques that the common programmer doesn't know about that it can be a real detriment to them, and often a bit unfair. We've had threads like this one before, so I figured I'd start a new one.

Compress your classThere are several ways you can do this. Riven has amazingly provided us with an HTTP service that does all the dirty work for you.Compile 'n Shrink - HTTP Service - http://www.indiespot.net/app/java-four-kay

If you do not use Riven's tool, then you should use Pack200 and at least one compression tool (maybe all of them!). This can be a bit time consuming but will save you a massive number of bytes.

Please please add replies to this, especially extra tips and guides on how to use the compression tools and pack200. We want this thread to eventually be full of step-by-step guides so that people can focus on their code.

I'm not sure whether the below was an intentional simplification, if so I apologise for being overly picky with my technical correctness

Quote

Every string literal you create adds exactly as many bytes as there are characters

Due to class files using a UTF-8 encoding (Modified UTF-8) to store string literals, this is not true.Every string literal ( sl ) you create adds atleast 2 + sl.length bytes, and at most 2 + sl.length*3 bytes.

So if you ignore the 2 byte length, and limit your string to containing only characters from the first 127 positive byte values (~= western-latin alphabets), your statement is sort-of accurate - beyond that, it gets progressively more incorrect.

All global variables should be named only a single character. Local variables can have whatever name you want.

All constants should be declared static final so they can go in the constants pool.

Every time you use a method, it will add bytes equal to the number of characters in that method. However, each method will be added only once for all uses.

If the obfuscators aren't capable of doing trivial optimisations like these then are they not completely useless? More useful advice would be to use a single character name for the class, because obfuscators won't rename that.

Quote

Keep your code all in one class, and put all your code in one Applet method (like start()).

I'm pretty sure that consensus from the earlier template discussion was that if you want your applet to behave correctly you have to spawn off a thread.

Oh yeah, I meant to add: correct me my mistakes! Some things (like the one byte per character for strings) were pretty much me working from memory of lsat year, I'm sure I've got plenty of little issues up there.

Thanks for the clarifications. I'll keep editing this as we get more info. I have no experience with the optimizers, so if some things are pointless then I won't really know it.

I'm personally annoyed I have to use optimizers to be able to contend - the fun part for me is putting in static final etc. etc. in order to get the bytes down. And then doing a smart thing with a loop, etc. When your code literally goes from 4kb to 1/2kb with optimizers and compression, that's kind of frustrating. Part of the reason I made this thread is because last year I was a bit overwhelmed with the incredibly large number of things I had to do to compress my game, none of which had anything to do with code. I think it's a really steep hill you have to climb as someone new to 4k.

Uh... somebody (you?) had make this massive script, that fed the JAR through at least 10 compressors/obfuscators. What I was trying to say was that I'd like to make this an online service for everybody to use. But it has to run on Linux, and without a desktop.

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

I'm personally annoyed I have to use optimizers to be able to contend - the fun part for me is putting in static final etc. etc. in order to get the bytes down. And then doing a smart thing with a loop, etc.

Last year I used Proguard and then decompiled it and saved the last 60-odd bytes by hand-tweaking the bytecode, reassembling with Jasmin. You can still be hardcore if you want to be!

I used kzip last year, but it doesn't support the gzip file format. Therefore here is a utility I've knocked up which converts zip files into gzip files. It makes various assumptions (only the first file in the zip is processed; the zip is assumed to give CRC, compressed size, and uncompressed size before the data block rather than after it). I've tested it with kzip and ensured that the result is correct.

Error handling is about what you'd expect from a throwaway tool (i.e. minimal).

Not yet tested on a .pack file, but I'm about to go to bed so I'll put it up for people to play with.

// The output still needs the CRC32 and the uncompressed size.out.write(crc1);out.write(crc2);out.write(crc3);out.write(crc4);out.write(ucmpSz1);out.write(ucmpSz2);out.write(ucmpSz3);out.write(ucmpSz4);

Interresting results -- assuming they both sqeezed their JARs, as I couldn't find a tool to do it better...

Falcon4k (Alan_W)

4,093 bytes (jar)...3,467 bytes (pack.gz => 7z on .pack)

...

Interesting to see that pack200 did a better job after a 'plain zipper' like WinRAR.

Good grief. Absolutely amazing. Thanks Riven. I knew that pack200 zipped up all the files in an archive together, thus running the compression algorithm over the lot, rather than each one individually and had therefore only expected a noticeable benefit for archives containing multiple files. I guess pack200 must also reduce some of the class overhead that comes with a standard java class. I had intended to target jre1.4 again this year as the only thing I wanted out of jre1.5 was the nanosecond timer, but am now sitting down with a dazed expression. Maybe leave Falcon4k as jre1.4 as it's pretty much finished, but on the other hand, I could fit a lot of level data in that 500 extra bytes.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org