GRAB is my entry for the 2013 JS1K contest. It is a prototype for a complete game I’m currently working on that is built in under 1KB or 1024 Bytes.
You control a brave, little, glowing arrow and your mission is to gather up as many resources (glowing orbs) as possible. BUT every resource you pick up also spawns an enemy mine that drifts towards you at a speed inversely proportional to your distance from it. Weave your way in and out of the enemies that begin to clog the screen and rack up as many points as you can.
This was probably the most fun I’ve ever had writing several lines of code. After completion I feel like I almost know what it must have been like to program games when every single bit of code and memory counted. Imposing such strict limits on what you can do is actually a liberating experience; one that lets you work fully inside a defined space as opposed to an infinite one in which you bumble about.
There were a few techniques I learned after working on this project that helped me to achieve the tiny file size.
If you aren’t using a compiler/minifier for JS1k the competition is a bit over before it even begins. Trying to write code and maintain it without good variable names and a nice visual hierarchy is going to be a nightmare. So for this project I used the Google Closure Compiler which got me like 60% of the way to 1KB from my original source code.
Don't do this for normal code. This is for code golf / hacky purposes.
If you find yourself repeating a lot of the same function calls with the same parameters, say for example repeatedly calling addEventListener('keyDown')
and addEventListener('keyUp')
, you may be able to save some space with this method. Essentially you are turning your source code into a string and replacing those long function calls (or w/e else) with a single symbol. Then use regex on the string to replace those symbols with the original code, and eval the result. I was able to get a decent savings out of replacing the following:
b.addEventListener("key
function
600*M.random()|0
The final trick or technique I utilized for this project was simply to rethink what I was trying accomplish. We don’t often need all of the stuff we write. Throughout a project like this you should be thinking, “What can I remove from this?” far more often than “What can I add?”.
In GRAB one of the easiest examples I can remember of this, had to do with how I was clearing the canvas and then repainting everything. In the original version, I had a white background and every frame i was clearing the canvas and drawing everything back to the screen. Then I realized I could get rid of the canvas clear and just use the canvas fill method that I was already using. Only now I made it black and gave it an alpha value. This meant every frame had a bit of a ghost from the previous frames. In the end I saved some bytes and gained a visual feature that I really liked!
Here’s the final code for the JS1k 2013 Submissions. Unfortunately I don’t have the original unobfuscated source code anymore.