4King & Country!

Hey everyone,

When I saw this competition I thought, hmm wouldn’t it be cool to fit an infinite world in just 4k? So my aim was to write a naval exploration/warfare/conquest game using a Perlin noise generated “infinite” landscape.

The game has gone through many manifestations - I started out with the idea of a ship-battling, sea monster-fighting action game but that never really got off the ground. Then I started to think along the lines of Colonisation and The Wager (http://www.surprisedman.co.uk/the-wager/) to make an explore, expand, exploit game (but no exterminate! :D).

Update! Now under size - 4,091 bytes ;D But not without some grievous cramming, as you should be able to see from the horrendous font and aliasing.

Latest news: Font rendering has thankfully been restored, but not antialiasing yet :’( Also the flashing red screen is back… hooray! Size is 4,093 bytes.

All comments and suggestions very welcome! I’m particularly interested to hear your thoughts on the gameplay as that’s all pretty rough… but I feel like at long last this is a game that actually might work or even be fun :o

[applet archive=4king130228.jar class=T width=512 height=512]

Aim:

The year is 1496. The King has sent you forth to distant lands on a voyage of discovery, conquest and exploitation. Explore uncharted waters to find the finest locations to settle, and begin transporting precious resources back to sell to the motherland. You have 100 years to prove yourself - do not let the King down or you will live out the rest of your days as a serf! Serve the King well and he will make you a Lord of the realm.

Interface:

  • Top-Left (top to bottom): Current year (game ends in 1596), Rations remaining on board (red bar), Cargo hold (to carry wood & iron), Settlers on-board (white dots)
  • Top-Middle: Gold earned
  • Top-Right: Mini-map showing charted & uncharted territory

Tips:

  • Food (red bar at town): Will help to grow the town quickly, so you can get new settlers. Also the higher the town population, the faster the resource generation rate and the more gold you make.
  • Wood (green bar at town): Required for building new towns, so make sure some of your towns are near woods! (dark green areas on the islands)
  • Iron (blue bar at town): The most valuable resource, generated if mountains are within the town radius.
  • Resource Bonuses: Diamonds on the map are resource bonuses, the colour indicates which resource they apply to (light green: food, dark green: wood, grey: iron). If a bonus is within the radius of one of your towns, that town’s production rate for the resource is doubled (or quadrupled for 2 bonuses, etc.)
  • Transporting Settlers: Carrying multiple settlers can help you to expand quickly, but beware you don’t end up out at sea with no rations! The more settlers you are carrying on the ship, the faster the rations deplete. If you run out of rations you will sleep with the fishes (the screen will start flashing red once the level of rations is below 25%). Your rations will automatically be replenished if you dock at a town.
  • Town Growth: To grow above a population of 2 requires wood, and above 3 requires iron. So to maximise production you will need to transfer resources between towns.

Controls:

  • Left mouse-click: Set direction of ship or Settle new town at mouse location (in settling mode) or Load resources from town (when docked at a town, click mouse with S = settler, W = wood, D = iron)
  • Right mouse-click: Unload resources from ship to town (when docked at a town, click mouse with S = settler, W = wood, D = iron)
  • Space: Anchor & activate settling mode (when no town is in range) or Anchor & dock at town in range

Known Bugs:

  • Ship can get stuck in crevasses in the terrain. Pressing space (anchor) can sometimes help.

Sounds very interesting… do you have a link to it?

Still getting used to how to upload applets here (it doesn’t seem to like dashes in the filename), but it should be working now!

Nice game. But too much command for me. What is the interest of carrying iron in the ship?
I guess I saw a diamond on a mountain, but nothing append… I like the exploring part, but we don’t have enough time to explore (in my opinion). Anyway, I’m very curious about the source code of this game :wink:

Cool, is it possible to get the source? I mean i was able to decompile it (i’m curious about the perlin noise algorithm, because mine is lousy slow) and to understand it in general, but with the proper variable names it is easier to read.

Regards
PS: Nice idea.

Thanks for your comments. Yes as I said the controls are pretty clunky in places… your suggestions are welcome. I was planning to replace most of the keyboard stuff with mouse controls - so anchor is right button, settle maybe left or right drag, load/unload could be done by clicking on the town resources. Regarding the time for the game, actually I didn’t get much chance to play-test it yet :persecutioncomplex: The iron was originally needed for building towns, but it’s a bit hard to get so I reduced it to only need wood. But I think I will change the town growth requirements so the town needs wood & iron to grow bigger than a population of 2. So that would make distributing resources from one town to another important.

I am going to try to tidy up the code this evening and hopefully reduce the bytesize a bit. So I should be able to post it sometime soon. There is nothing particularly clever about the Perlin noise algorithm (I wrote it to be readable as this is the first time I have implemented one), but it runs fast because it only redraws what it has to each frame. There is a double buffer the size of the screen that holds the calculated “height” from the Perlin noise for each pixel, which is only ever drawn completely for the first frame of the game. For all other frames, e.g. if the player moves 5 pixels right it just draws those columns. So that is a roughly 50-fold reduction in rendering time (5x512px vs. 512x512px).

Oh thanks for the hint, my implementation looks like the attached one (sorry, i’m atm not at the laptop which i use for java, so it is just the delphi version i got in here).
http://www.java-gaming.org/?action=pastebin&id=435

A good looking and promising project. You should consider simplifying A LOT your gameplay to save enough bytes to fit it into 4K. Good luck to finish it in only three days.

Hi everyone,

Thanks for the replies. So after a very long struggle with the filesize, I can happily announce it’s now 4,091 bytes ;D But I had to sacrifice the antialiasing and font rendering… so it’s leaning more toward the “programmer” visual aesthetic now :wink:

Changes:

  • Game length: Now set to 20 mins instead of 10
  • Controls: Now simplified (I hope) - everything can be controlled with mouse + space/w/s/d
  • Town upgrades: Towns can only grow above size 2 with wood, or size 3 with iron. You still have the option of transferring extra settlers from the ship to the town (to get around this) - let me know how it plays because maybe that should be prevented too.

I would like to reincarnate the font and antialiasing if possible. Time is very short now but I’ll post the code and if you have any suggestions on how to reduce the size I would really appreciate it. I have been working on it pretty manically so the code is like a bomb-site, you might have a heart attack but bear with it! :wink:

Not sure how to get the pastebin working? It just seems to go to a nearly blank page ~20s after submitting the code.

I thought I saw my username and was excited for a second there haha :slight_smile:

OK managed to fit the fonts in so it looks much more presentable now :point:

What do you think about the gameplay guys?

The game is up on: http://java4k.com/index.php?action=games&method=view&gid=471

But does not work, and I have no idea why! ???

My guess is because it’s zip instead of gzip, but I don’t know. Anyone take a look?

That’s what the stack trace says. I’ve used both 7zip and kzip (didn’t end up more than 5 bytes different.) Here’s the stack trace from the Java console:

ava.util.zip.ZipException: Not in GZIP format
at java.util.zip.GZIPInputStream.readHeader(Unknown Source)
at java.util.zip.GZIPInputStream.(Unknown Source)
at java.util.zip.GZIPInputStream.(Unknown Source)
at com.sun.deploy.net.HttpDownloadHelper.download(Unknown Source)
at com.sun.deploy.cache.Cache.downloadResourceToTempFile(Unknown Source)
at com.sun.deploy.cache.Cache.downloadResourceToCache(Unknown Source)
at com.sun.deploy.net.DownloadEngine.actionDownload(Unknown Source)
at com.sun.deploy.net.DownloadEngine._downloadCacheEntry(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.getResource(Unknown Source)
at sun.plugin.PluginURLJarFileCallBack$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.PluginURLJarFileCallBack.retrieve(Unknown Source)
at sun.net.www.protocol.jar.URLJarFile.retrieve(Unknown Source)
at sun.net.www.protocol.jar.URLJarFile.getJarFile(Unknown Source)
at sun.net.www.protocol.jar.JarFileFactory.get(Unknown Source)
at sun.net.www.protocol.jar.JarURLConnection.connect(Unknown Source)
at sun.plugin.net.protocol.jar.CachedJarURLConnection.connect(Unknown Source)
at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFileInternal(Unknown Source)
at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFile(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.getJarFile(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.access$1000(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.ensureOpen(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.initAppletAdapter(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
com.sun.deploy.net.FailedDownloadException: Unable to load resource: http://java4k.com/applet.php?gid=471
at com.sun.deploy.net.DownloadEngine.actionDownload(Unknown Source)
at com.sun.deploy.net.DownloadEngine._downloadCacheEntry(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.getResource(Unknown Source)
at sun.plugin.PluginURLJarFileCallBack$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.PluginURLJarFileCallBack.retrieve(Unknown Source)
at sun.net.www.protocol.jar.URLJarFile.retrieve(Unknown Source)
at sun.net.www.protocol.jar.URLJarFile.getJarFile(Unknown Source)
at sun.net.www.protocol.jar.JarFileFactory.get(Unknown Source)
at sun.net.www.protocol.jar.JarURLConnection.connect(Unknown Source)
at sun.plugin.net.protocol.jar.CachedJarURLConnection.connect(Unknown Source)
at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFileInternal(Unknown Source)
at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFile(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.getJarFile(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.access$1000(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.ensureOpen(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.initAppletAdapter(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by:
java.util.zip.ZipException: Not in GZIP format
at java.util.zip.GZIPInputStream.readHeader(Unknown Source)
at java.util.zip.GZIPInputStream.(Unknown Source)
at java.util.zip.GZIPInputStream.(Unknown Source)
at com.sun.deploy.net.HttpDownloadHelper.download(Unknown Source)
at com.sun.deploy.cache.Cache.downloadResourceToTempFile(Unknown Source)
at com.sun.deploy.cache.Cache.downloadResourceToCache(Unknown Source)
at com.sun.deploy.net.DownloadEngine.actionDownload(Unknown Source)
at com.sun.deploy.net.DownloadEngine._downloadCacheEntry(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.cache.ResourceProviderImpl.getResource(Unknown Source)
at sun.plugin.PluginURLJarFileCallBack$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.PluginURLJarFileCallBack.retrieve(Unknown Source)
at sun.net.www.protocol.jar.URLJarFile.retrieve(Unknown Source)
at sun.net.www.protocol.jar.URLJarFile.getJarFile(Unknown Source)
at sun.net.www.protocol.jar.JarFileFactory.get(Unknown Source)
at sun.net.www.protocol.jar.JarURLConnection.connect(Unknown Source)
at sun.plugin.net.protocol.jar.CachedJarURLConnection.connect(Unknown Source)
at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFileInternal(Unknown Source)
at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFile(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.getJarFile(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.access$1000(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.ensureOpen(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.initAppletAdapter(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Unzipping the file at that url and using gzip format + Ultra compressionin 7zip, it’s coming up as 4,137 bytes. Fiddling with the settings you should be able to bring that below the 4,096 threshold.

Yes sorry, my mistake, I’ve been using BJWflate based on a script from a previous year when Pack200 wasn’t allowed… with 7Zip I have the file size down to 4,122 bytes. There must be some more to squeeze out somewhere…

Well… you better, because with your game the total count is 68… and I already announced we broke the 2009 record. If you don’t squeeze it to 4096 or less bytes then you’re failing all of us. But no pressure… still 2 hours to go :slight_smile: ;D

4,110 bytes…

4 042 b : http://forthx.free.fr/x/T.jar.pack.gz

No need of sources I tweak my script…

I test it, it works! So if you run out of time … For the 68 ;)…

Tell me when I can remove it !

(note: I take the jar here : http://java4k.com/index.php?action=games&method=view&gid=471)

Thanks very much forthx :smiley: Your packing skills must be superior to mine…

I also just managed to get it to 4,095 bytes and I think the version I have is slightly updated (small bugfix, different font) so I’ve updated the game page. Enjoy:

http://java4k.com/index.php?action=games&method=view&gid=471

So looks like we all made it to a record-breaking competition. Nice ;D