Raid On Java 4K

Hello,

My name is Felix and I’m new here.

I want to introduce my little action game “Raid on Java 4K” for the Java 4K contest.
You can play it on Java4k.com:
http://www.java4k.com/index.php?action=games&method=view&gid=486

Here are some Screenshots:

http://s7.directupload.net/images/140129/olxue9jg.png

It’s a 4K version of the good old C64 game “Raid on bungeling bay” by Will Wright, which I really enjoyed in my childhood (Now you can guess my age :slight_smile: ).
Of course it has fewer features. Anyway, I hope you will enjoy it.

Some features of the game are:

  • Heatmap Explosions
  • A lot of jets with a pretty nice AI
  • Defense towers
  • 16 Levels
  • Multidirectional Wraparound Scrolling

During the developing, I concentrated on the features and do not pay attention to the size. Unfortunately there are some features I had to cut off at the end:

  • A radar
  • Some water effects
  • Better looking factories with smoking chimney. Now there are only grey squares (sigh).
  • Better looking aircraft carrier
  • Better AI of the defense towers
  • Score counter

I hope, that I deleted not the wrong features and you’ll have a lot of fun.

I stumble over the java 4K contest while I read the Wikipedia entry about Markus Persson. I was curious and so I study the source code of “Left 4K Dead”. To be honest, I implemented the way how Notch handled the sprites and the sprite rotation in “Raid on Java 4k”, please forgive me.

In the end, I wish you happy dogfighting… and which level can you reach?

Bye,
Felix

It’s great to see another entry here.

The graphics look smooth and great. The heat effect for the explosions and bullets turned out well.

It’s too bad about the factories just looking like squares - at first, I didn’t read the instructions closely and thought that they were landing pads. I had cleared out all the enemies but never dropped a bomb on them. Then, I went back and read the instructions. The game definitely improves once you level up a few times.

I am quite impressed. I did not think that i would enjoy it as much as i did. well done!

only got to level 12 tho.

Thank you for your nice feedback.

@Groboclown:
I’m not very proud of the “grey-square-factories”. And really, deleting the features brought me close to tears…
Here are two screenshots from the full featured game:

http://s7.directupload.net/images/140131/ssspcusc.png

Ok, it’s still “programmer art” and not really beautiful. But landing pads look different…
Unfortunately, after my compression chain the file size is 4888 Bytes.

@moogie:
Level 12 is the point where you have to change the tactic.
You cannot just rush to the factories and bomb them.
First, you have to take care of the jets.
Anyway, I think you hold the high score.

I wonder who can complete the game.

I am a bit of a veteran when it comes to the j4k competition, if you want to make your full featured game source available I can try my hand at shrinking your code :slight_smile: If you do, perhaps list the features you want to keep the most.

Nice game !
It would be indeed easier with the map, so as moogie said, if you want some help, we can have a look.

Wow, this is a nice offer!

That would help me to learn the tricks of 4k programming.

But please do not invest too much free time. I would get a bad conscience.

@moody: you should make you 4K entry finished first. Time is running and I’m curious.

I think the radar is the most valuable feature for the gameplay, too.
I could send you in total 3 sources. I could send you the original 4k source, one with all features and one with the radar. With this, you can compare the sources and find the differences easily.
But first, I have to translate my German comments.

How may I send you the sources? Would you pm me your email addresses?

By the way, my compression chain looks like this:
Compiler -> JAR -> Proguard -> Pack200 -> 7zip -> deflOpt

Without modifying your code, you can first try to modify the end of you compression chain.

Instead of using 7zip, search the best filesize between kzip and BJWFlate compressor.
This tools allow us to specify a block split.
So execute kzip with a different block split each time (16, 32, 64, 96, 128…) using “/b” option.
Next do the same with BJWFlate using “-s” option with this values : 96, 128, 192, 256…4096
And finally keep the smallest file and apply DeflOpt on it.

My compression chain (with your Java4K source code) gives me a final pack.gz of 3905 bytes.

After that if needed, I think you can paste you sourcecode in pastebin.

EDIT : Try also JARG between JAR and Proguard

Dont worry, i enjoy hunting for bytes :slight_smile:

My entry took a bit of a break but now i have inspiration so i am back at it!

Nice action-packed game! Love the explosions. :slight_smile:

I have made some experiments with my compression chain. But I can’t shrink my game as good as Gef.
Especially kzip and bjwflate have not the effect as hoped.
But I found the tool zopfli from google. This tool has good results.
Maybe the weak spot of the compression chain is elsewhere? Maybe my proguard settings are not optimal?

You can found my pro-file here:
http://pastebin.java-gaming.org/7847a3c2087

As announced I uploaded 3 sources.

This is the original 4k-Source:
http://pastebin.java-gaming.org/847ac402781

This is the 4k-Source with radar:
http://pastebin.java-gaming.org/47ac0572185

And finally the full featured version:
http://pastebin.java-gaming.org/7ac0761258c

Here are my compression results (with immediate data):

4k-version:
Original JAR: 10.541 Bytes
After JARG: 5.400 Bytes
After Proguard: 5.328 Bytes
After Pack200 (without compression): 8.586 Bytes

Now I tried 4 different compression tools on the pack200 result:
KZIP: 4.084 Bytes
7Zip: 4.061 Bytes
BJwflate: 4.103 Bytes
Zopfli: 3.980 Bytes

At the end I used deflopt on every result:
KZIP: 4.075 Bytes
7Zip: 4.056 Bytes
BJwflate: 4.103 Bytes
Zopfli: 3.980 Bytes

radar-version:
Original JAR: 11.274 Bytes
After JARG: 5.749 Bytes
After Proguard: 5.679 Bytes
After Pack200 (without compression): 9.083 Bytes

Now I tried 4 different compression tools on the pack200 result:
KZIP: 4.396 Bytes
7Zip: 4.364 Bytes
BJwflate: 4.389 Bytes
Zopfli: 4.262 Bytes

At the end I used deflopt on every result:
KZIP: 4.377 Bytes
7Zip: 4.360 Bytes
BJwflate: 4.387 Bytes
Zopfli: 4.262 Bytes

Full-featured-version:
Original JAR: 12.754 Bytes
After JARG: 6.410 Bytes
After Proguard: 6.357 Bytes
After Pack200 (without compression): 11.114 Bytes

Now I tried 4 different compression tools on the pack200 result:
KZIP: 4.920 Bytes
7Zip: 4.907 Bytes
BJwflate: 4.951 Bytes
Zopfli: 4.874 Bytes

At the end I used deflopt on every result:
KZIP: 4.898 Bytes
7Zip: 4.904 Bytes
BJwflate: 4.950 Bytes
Zopfli: 4.874 Bytes

Maybe these information are useful for someone else.

@Gef and moogie:
It would be great if you have a good idea to save the radar.
Otherwise I think I’ll implement some minor gfx effects into the last bytes I won with zopfli.
Anyway I thank you for your support.

Felix…

Thank you! The explosions are the only eye candy that survived ::slight_smile:

I had a quick look at the code (i am going to work) and i see a few possibilities. so will have a better good tonight when i get home (approx 8-9 hours)

A few things for the optimization:

I changed the class name to “R”, because that saves a few bytes. I also removed the package, as that saves even more.

I replaced the processEvent method with:


    public boolean handleEvent(Event e) {
        boolean down = true;
        if (e.id == Event.KEY_RELEASE || e.id == Event.KEY_ACTION_RELEASE) {
            down = false;
        }
        if (e.id >= Event.KEY_PRESS && e.id <= Event.KEY_ACTION_RELEASE) {
            keyboardMap[e.key] = down;
        }
        return false;
    }

Followed by removing the enableEvents call, and replaced all the VK_ values with local definitions of the key mappings.

(full source: http://pastebin.java-gaming.org/ac071752c82)

These changes, when run through my compressor tool chain (http://sourceforge.net/p/groboutils/java4k/ci/default/tree/) brought the size down to 4124 bytes. Not quite there.

Another big optimization you can do is change the image maps from 1 character = 1 pixel down to 1 bit = 1 pixel (you have currently ‘.’ or ‘X’ to be a on or off value). Because you have 32 pixels horizontally, this maps to 2 characters per line. For the case where you have the “O” to indicate a third color, this could either be eliminated for space, or you could hard-code in the range for when it’s the specific other color. Something like this:


            char[] copterBase =
                    (char) 0x0000 + (char) 0x0000 + // "................................" + //
                    (char) 0x8000 + (char) 0x0005 + // "...............XX.X............." + //
                    (char) 0x8000 + (char) 0x0007 + // "...............XXXX............." + //
                    (char) 0x8000 + (char) 0x0005 + // "...............XX.X............." + //
                    ...
                    "".toCharArray();

I’ve also tested few quick modifications with the radar version (pastebin):

  • renaming the class, but with “A” :wink:
  • replacing some double values by integer values (0.0 => 0, 1.0 => 1)
  • replacing the processEvent method by handleEvent (like Groboclown said)
  • Modifying few operations for final compression

Compare it with your code, test it (only you can say us if nothing has been broken) and if that’s ok,
the compression chain as described above, finally gives a pack.gz of 4080 bytes.

Well it looks like with the help of Gef and Groboclown you will have it all sorted before i get home :stuck_out_tongue:

One area that may yield smaller compressed byte code is to consolidate your various arrays into one array and then use an offset to get to the relevant section. i.e.

instead of:


int[] data1 = new int[1000];
int[] data2 = new int[2000];

use:


int[] data = new int[3000];

and to use:
instead of:


for (int i = 0; i<1000;i++)
{
   data1[i]= some value;
   data2[i*2] = another value;
   data2[i*2+1] = -1;
}

use:


static final private int DATA2_OFFSET=1000;
for (int i = 0; i<1000;i++)
{
   data[i]= some value;
   data[DATA2_OFFSET+i*2] = another value;
   data[DATA2_OFFSET+i*2+1] = -1;
}

It’s even better to rename it after a method from the standard library which you need to invoke. That way they share an entry in the constant pool.

I’m agree with you (and there are lots of other tips that can be tested) !
My goal here was just to apply quick tips to produce a file under 4kb.
In fact, some tips which work for a compression chain, don’t work for another.
That’s why sometimes, a illogical thing in the sourcecode (in term of Java) finally gives a better compression :wink:

Yes i also have found that illogical things can produce better results. i.e. explicity inlining of method methods

One thing that helped me was replacing all Math.cos( x ) with Math.sin(PI / 2 + x). And replacing else if statements with if statements (where possible) also can help a bit.