Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » It's that time again: Java 4k contest

This thread is locked; no one can reply to it. rss feed Print
 1   2 
It's that time again: Java 4k contest
nonnus29
Member #2,606
August 2002
avatar

Yes, it's that time of year again. When some really amazing game developers try to fit as much game as they can into 4k of compressed java bytecode. There are some AMAZING games so far this year. And there are 2.75 months left in the competition....

The link above has threads to the games being entered so far. I should warn you that miners4k, speed4k, frag4k, and roll4k are quiet addictive and you'd never believe they were made in as little as 4096 bytes. Give em a try! JRE 1.4 required.

Inphernic
Member #1,111
March 2001

Very cool. :)

nonnus29
Member #2,606
August 2002
avatar

Heh, I've spent at least 4 hours playing miners4k (it's a lemmings inspired game with little miners in search of gold) and I can't get past level 3. One of the other guys beat it and he said there are some growing slime monsters in the later levels that eat your little miner guys. This game is amazing.

kentl
Member #2,905
November 2002

Damn cool, I'm considering joining with something. Are there any special tricks to reduce size to 4096 byte of compressed java byte code? That is, apart from keeping object orientation and number of classes to a minumum and generating procedural graphics. Do they use AWT for the graphics? (Swing generates larger files I would assume, I might be wrong though.)

nonnus29
Member #2,606
August 2002
avatar

It's hard to say exactly what everyone is doing. Like I'm using a jframe and a buffered image and doing my own double buffering, others are using the built in double buffering (getGraphicsConfiguration()), last year I made an applet. It's pretty free form. Here are some tips someone posted;

Quote:

Some hints:

- Use only one class
- The class should inherit from JFrame if it is a webstart app. That way the close box automagically works, although you need to call isVisible() from time to time & do a System.exit(0), if the Frame is no longer visible.
- Put the entire game in the constructor if possible. Each function added to the class has overhead
- Avoid using class variables, unless you absolutely need them (e.g. more than one function accesses them) as these are more expensive in space than local variables in a function.
- If you declare any constants as class variables, declare them as private final static. This will get them inlined.
- Use the minimum number of class library methods. Everytime you use one of these, the full name (class+method) ends up in the .class file.
- Use long variable names as usual, except for the class name, which should be a single letter. Use an obfusticator such as proguard. This will reduce all variables in the .class to single letters, remove unused functions.
- Unjar the file proguard produces and then rejar using a standard zip compressor such as 7zip or kzip. Remember to specify the command line switches to get maximum compression.
- You don't need a manifest if you use webstart as the only starting method. If you do include a manifest (& it is a nice touch) you only need the version and main-class statements.

Good Luck

kentl
Member #2,905
November 2002

I'll be sure to join in! I have read the relevant threads on Javagaming as well, good that there is still lots of time. This will be my first game in Java, so it'll be a challenge! :)

If you know of any noob tutorial for this special occasion which I could read I'm all eyes! :)

nonnus29
Member #2,606
August 2002
avatar

Here's a tip; use enableEvents() to poll the keyboard directly:

1public class M extends JFrame {
2 int[] keys = new int[256];
3 ...
4 public M() {
5 super();
6 ...
7 enableEvents( KeyEvent.KEY_EVENT_MASK );
8 //rest of game
9 //main loop is in the constructor
10 }
11 
12 protected void processKeyEvent(java.awt.event.KeyEvent e ) {
13 keys[e.getKeyCode()] = (e.getID() & 1);
14 }
15}

Here's a screen shot of my software renderer with flat shading in about 2.7k. Unfortunately I don't have alot of time over the next two weeks to do anything with it :-/

{"name":"j4k.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/7\/57c11edb8da189dd4ffc74b37e5baefe.png","w":343,"h":310,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/7\/57c11edb8da189dd4ffc74b37e5baefe"}j4k.png

kentl
Member #2,905
November 2002

Thanks!

Yeah I already picked up the enableEvents() trick from the Pengo4k thread. It differs from your solution in that it uses int[] keys = new int[5]; as there are 5 different keys to consider, while you store every keycode in your int[] keys = new int[256]; array.

I thought about why Pengo4k didn't do it the same way as you and currently use its way (as it was before I read this post), but perhaps I should change. Do you see any pros or cons with your / Pengo's method? Your method renders a bit cleaner code in the processKeyEvent method, but perhaps it results in larger jar-files?

Also, how do you keep track of time? I hear that getTimeMillis() isn't to be trusted before Java v1.5, and as the competition requires v1.4.2 (or an earlier version) I'm in a pickle. Currently my render loop is of the form:

        while (isVisible()) {

           // PLACEHOLDER: Update game logic

           Graphics2D g = (Graphics2D) strategy.getDrawGraphics();

           // PLACEHOLDER: Draw graphics to g
           
           strategy.show();
           
           Thread.sleep(10);
        }
        System.exit(0); // End the process as the application window is closed

which may not be the nicest thing (unless my logic and drawing combined takes very little CPU-time I will get different frame rates on different hardware).

And finally. Your screenshot looks great! I guess you are doing a Star Wars related shoot'em up game? Not having much time over the next two weeks can't hurt you that much? If I remember correctly the contest ends in February?

nonnus29
Member #2,606
August 2002
avatar

I think your code for keyevents may be smaller by a few bytes. I'm not at the point of scrounging for bytes yet, and when I do I'll have to check into that. Some of these people disassemble there code and tweak it with a java bytecode assembler. I'm not at that point yet!

Yes, System.currentTimeMillis() can be pretty erratic; but on win2000 xp its usable. This is my current main loop:

while (true) {
    if(System.currentTimeMillis()-dt > 10) {
        //Game logic, input, physics, etc go here

        dt = System.currentTimeMillis();
    }     
    paint(getGraphics());
}

So I draw as fast as it'll go, but only update the game 100 times a second. It seems to run pretty smooth on my computer.

kentl
Member #2,905
November 2002

I've done some things since my last post:

  • Switched application type from inheriting from JFrame into an applet. This because I might want to put it on my web page later on, I don't know much about webstart but I guess it's possible with an applet to.

  • Changed into your way of detecting key presses, some bytes where eaten by this but I consider it to be cleaner code. I might change this when I get low on bytes.

  • Switched from double buffering using Strategy into double buffering using my own code.

Your method of updating seems good, I'm using one where I do the logic updating and frame rendering at the same time.

I'm going to implement some kind of 2D game, using as much procedurally generated graphics as possible. Do you know if there is any restriction in how much memory an applet can use? I want to store the generated graphics as lots of Image's or BufferedImage's.

I might even add some sounds (something I've never done using Java), the only thing I know about sounds is that sound banks may not be used in the competition. What ever they are. ;)

nonnus29
Member #2,606
August 2002
avatar

Heh, I had the only applet in last years contest. So far as I know there is no limit on memory usage in applets. Also, applets have the method getAudioClip() you can use to play midi, wav, and au files. You might look into using those.

I have an idea on how to create ALOT of content for a sidescroller:

1) store a few tiles and sprites as byte arrays; for 16 colors tiles you can fit two pixels per byte, 4 colors can fit 4 pixels per (edit)byte. You can switch up colors by using different palletes. You could procedurally generate some tiles too by drawing into an image with gfx primitives (rects, circles etc...)

2) When you create the buffered image from the byte array multiply by a factor of two. This will give you an old school, low res pixelly style to your gfx.

3) Store tile map data in byte arrays using RLE (run length encoding) and decompress that into an int[] for your tile map.

OR

4) Use 'bitmaps' of tiles and draw them into the tile map array; ie reuse one platform, reuse a platform with a ladder, reuse a palmtree top, whatever.

I'm sure I could squeeze one hell of a lot of content using this method. The hardest part would be platformer physics.

kazzmir
Member #1,786
December 2001
avatar

How do you run these things? miners4k seems to be an xml file( .jlnp ). What do I do with that?

nonnus29
Member #2,606
August 2002
avatar

If you have java 1.4 plus and click on the link it should kick off webstart and ask you to download and run the application. Mozilla ask me to open with default application; I'd google for how to enable webstart on whatever platform your on.

kazzmir
Member #1,786
December 2001
avatar

Oh i figured it out. These games are cool!

kentl
Member #2,905
November 2002

Quote:

Also, applets have the method getAudioClip() you can use to play midi, wav, and au files. You might look into using those.

I thought about generating the sound procedurally to, I guess it would take up some space as there might be lots of class references. But I'll look into it if I have any space left when I am done with the game (even a "boing" sound when jumping in a platform game would enhance the game a lot).

Quote:

I have an idea on how to create ALOT of content for a sidescroller:

It would be interesing to see the result of your method. I suspect that it might prove not to be as effective as you think. That is the size of the compressed file, it probably won't compress your data as good if you store it in a way which is more space optimal. But as I said, interesting it would be! (Yoda talk tm)

Quote:

buffered image

If you were in my situation. You need to be able to create bitmaps and process the pixels in these (I'm going to apply my own image effects, think "Blur"). Then use a number of these within the game for animations. Would you use Image or an BufferedImage then? (I am sure you are much better at Java than me, so I'm taking the opportunity to ask.)

kazzmir said:

Oh i figured it out. These games are cool!

Yes I agree, couldn't resist joining in. You should join as well! It would be fun with many allegroids in the compo. :)

nonnus29
Member #2,606
August 2002
avatar

Quote:

I suspect that it might prove not to be as effective as you think. That is the size of the compressed file, it probably won't compress your data as good if you store it in a way which is more space optimal.

You may be right, but the real savings could come from not loading a file etc... and tile maps would be a lot of wasted space :-/ .

I'd use buffered images because they're automatically accelerated. Here's how to get the pixels:

BufferedImage bb = new BufferedImage(400,400,BufferedImage.TYPE_INT_RGB );
int [] buffer = ((DataBufferInt)bb.getRaster().getDataBuffer()).getData();


Then buffer is your framebuffer.

Edit; and my plan is to implement the a game very similar to the original star wars arcade game in 4k; it's going to be TIGHT though.

kentl
Member #2,905
November 2002

Thanks once more! BufferedImage's it is!

Quote:

Edit; and my plan is to implement the a game very similar to the original star wars arcade game in 4k; it's going to be TIGHT though.

Are you going to have the Death Star in there as well? Like in the original arcade game. Sounds cool!

My game:
I can reveal that I have my mind set on a Bomberman clone, I checked out the forums at Javagaming and couldn't find one.

It's not going to be easy though, I have the game loop ready together with a small draw tilemap test. And I am already at 3024 byte size of my class file.

I will be implementing in this order:

  • Create a test tile map with two tile types; walls and walkable.

  • Control of the main character as well as drawing him.

  • Draw the walls more nicely (procedural graphics).

  • Be able to drop bombs, which will explode and break walls.

  • Computer controlled characters of the same type as our main character. Simple AI using a finite state machine.

  • Main character and Computer controlled characters can not walk into square with a bomb or another character.

  • Characters die from bomb explotions as well.

  • Replace test map with a procedurally generated map which you give level_difficulty to as an argument.

  • Make a small menu and increasingly harder levels by feeding the map generator with a higher difficulty level.

We will see if it will result in a finished game with the above qualities. Probably not, but I'll do my best. :)

Felipe Maia
Member #6,190
September 2005
avatar

Quote:

And I am already at 3024 byte size of my class file.

Compressed or uncompressed? Make sure you use a good ziper.

I'm thinking in joining later and doing a litle christmas game, since there's a lot of time left.

kentl
Member #2,905
November 2002

Uncompressed and with debug information, so I might have enough space to finish it as stated above. :)

Quote:

I'm thinking in joining later and doing a litle christmas game, since there's a lot of time left.

Nice! I hope you will have time and feel like it later on.

Rash
Member #2,374
May 2002
avatar

2.75 months left, eh?
I guess they foresaw the amount of time one would need just to start the game all those times for the playtesting. ::)

kentl
Member #2,905
November 2002

Quote:

2.75 months left, eh?

Seems like it. I think it's perfect with a long time span like this, not everyone can dedicate their time to game development for a couple of days. This way almost anyone have a chance of completing.

nonnus29
Member #2,606
August 2002
avatar

Quote:

I guess they foresaw the amount of time one would need just to start the game all those times for the playtesting.

Har, har, har. ::) The slow start up time is usually a one time 3 second pause, after that the jvm is already loaded. Go somewhere else troll.

In my entry last year I had about 7400 bytes kzip and jarg down to 4096. Proguard should go another 100 bytes below that. I only had about 1k of game logic, the rest was graphics.

kentl
Member #2,905
November 2002

Quote:

Har, har, har. ::) The slow start up time is usually a one time 3 second pause, after that the jvm is already loaded. Go somewhere else troll.

I thought I wouldn't feed it. Rash, if you use Eclipse like me it constantly compiles the game, so when I press "Run" I need to wait about 1/3 second before the game starts. It's certainly better than any C/C++ development environment I know of. But language wars are really boring, check nonnus29's sig for my opinion! ;) It's much more fun if we keep the thread on topic.

Quote:

In my entry last year I had about 7400 bytes kzip and jarg down to 4096. Proguard should go another 100 bytes below that. I only had about 1k of game logic, the rest was graphics.

That's nice, gives me some hope to finish the bomberman game then! :) If I have enough time I might create two games, it was very fun indeed!

[edit] BTW, I am DonaldEKnuth on javagaming. ;D

[edit2]
I have a finished game now as an applet. I tried reading on how to put it in a jar file and have used jar cf jarfile.jar G.class java.policy.applet G1134013040968.html without success. It creates a jar-file, but when I double click on it I get the error "Failed to load Main-Class manifest attribute from c:\d\jarfile.jar".

Do you have any hint? I'm new to this stuff, I read in Sun's tutorial but it didn't help. Do you know how they want people to turn in their applets? (Most other people use webstart, but I've created an applet.)

nonnus29
Member #2,606
August 2002
avatar

I just stuck it on a geocities page and used the archive parameter in the applet tag:

<applet code = G archive = "G.jar" width=400 height=400 >
</applet>

kentl
Member #2,905
November 2002

Oh, nice! Thank you!

This is what I have currently, I am creating a Sokoban clone:
http://www.freeimagelibrary.com/images/mrpeanut/sokoban4kv0.png

I have lots of bytes left, I am currently at 3174 bytes with:

  • Different coloring on each level based on some factors.

  • >60 levels.

I might add (strikethrough means done):

  • Smooth movement (the player square moves in steps now).

  • More random graphics.

  • A game menu.

  • Some effects.

  • Clean things up a bit.

  • A blip sound when moving.

  • Look into the webstart thingy and run it through it instead (as most seem to do).

 1   2 


Go to: