Development of Goblin Tower 13k for Steem Monsters Game Jam
Although Goblin Tower 13k has already been submitted into Steem Monsters + Js13kGames jams, I would like to present how it was done from scratch. Project is maintained in spirit of free and open-source software. Anybody can look into the code and investigate last weeks development progress.
https://github.com/mys/goblin-tower-13k
Two Game Jams at once
Luckily there were 2 interesting competitions that started in the same time. They are Steem Monsters Invitational and Js13kGames HTML5 and Javascript Game Development Competition in just 13 kB.
Steem Monsters Game Jam is one week competition where developers create a game in theme of Splinterlands and card game characters.
Js13kGames is a JavaScript coding competition for HTML5 Game Developers. The fun part of the compo is the file size limit set to 13 kilobytes. It lasts for 4 weeks.
I have decided to create simple minigame that could fit in both challenges. Let it be my own challenge to do so ;)
Requirements I had set
Goblin Tower 13k should be a clone of an old retro game called Xjump / Icy Tower. 2D platform game where player jumps up through the platforms to get as high as possible.
Main character is Goblin (Sorcerer). He travels through changing levels of Splinterworlds and meets other characters from Steem Monsters world. To fit the 13kB file size restriction, its graphics should be low-resolution and pixelized in the "feel" of retro-game. Codebase is pure HTML5+Javascript.
ETA: 1-2 weeks.
Game engine
During research I had dilemma whether should I create my own game engine or use existing one. Finally realized that there is no time to think about engines and chosed kontra.js as as base. There is good presentation about the statement "Coding own game engine is the worst idea in the world" by Michał Budzyński. Author says we should decide if we want to make game engine OR make a game.
Kontra.js is lightweight JavaScript gaming micro-library created specifically for game jams like Js13kGames. Sounds perfect to me.
What kontra.js gives me at start:
- game loop with 60 fps
- game sprites, assets and vector usage
- sprite sheet and animation
- buildin collisions between objects
- keyboard control
Scene composition
There are 3 scenes in the game: Main menu, Credits menu and Game scene.
Let's partition the game scene, because it is where the user plays. Game scene is composed of objects (sprites) where each of it has its own parameters, if needed. In each frame whole screen is being redrawn in order: background, walls, platforms, character, monsters and text labels. It is worth to mention there are 60 frames per second being rendered. Everything is painted on <canvas>
board.
Game logic
With created object sprites all I needed was to connect them with logic physics and reactions.
Also camera speed, score system and random generations 12 parts.
Graphics generation
Low resolution sprites
To achieve small file size of the game, most of the graphics should be generated in realtime. However I wanted to use some of the monsters low-resolution sprites to achieve Steem Monsters theme. Few days before deadline @heraclio appeared with nice pixel-art sprites for this card game. They were designed for this game jam.
@heraclio's sprites
Main character is small green Goblin. The art was taken from opengameart.org authored by Stephen "Redshrike" Challener under CC-By license.
This is set of my own drawings. They are 16x16 px platform blocks for each of Splinterlands. Sticked together they form groundline.
Pixel font and dualism effect
For this type of retro game I wanted to use pixelized font. However I couldn't use any external .ttf file because their size weights kilobytes even up to megabytes! Luckily there exists library for drawing PixelFont point by point on canvas. Additionally it lengths only 300 hundred lines. With compression should be what I need.
At above screenshot there are 2 different sizes set. By drawing two text labels with offset by 1-2 pixels, we get nice looking shadow.
Take a look at second text line. By using odd size of "font" at low-resolution canvas we get some kind of filter raised on the letters.
Generating bricks and dithered background
Same filtering technique appears at drawing walls "bricks". In fact they are just double-rendered rectangles with offset by 1-2 pixels. Low resolution gives us illusion of fugue between cells.
Background dithering is rendered simple close. Firstly a color of Splinterland's color is being drawn(). Then each pixel line's brightness is lowered down by manipulation of hex color. This technique let us render very beautil things. People of demoscene art are masters of it :)
Crisp pixel
There is one gimmick that should be used when drawing retro pixel art games. Modern browsers are blurring low-resolution images if upscaled by default. This should be turned off if we want to achieve 'pixelized' mood.
https://developer.mozilla.org/en-US/docs/Games/Techniques/Crisp_pixel_art_look
Code needed to apply in canvas css style:
canvas {
image-rendering: -moz-crisp-edges;
image-rendering: -webkit-crisp-edges;
image-rendering: pixelated;
image-rendering: crisp-edges;
}
13 kilobyte size restriction
Going under 13312 bytes distribution size (compressed, uh!) is tough restriction.
Js13kGames standard allows to minify and compress source code files. However it has to be done properly to maximize results. For help comes gulpfile.js configuration. While building game specific actions does compress our code:
- minification of html/css/javascript files
- optimization of images
- compress to zip
- verify if we exceed 13*1024 size
> gulp build
[21:49:58] Using gulpfile /gulpfile.js
[21:49:58] Starting 'build'...
[21:49:58] Starting 'cleanDist'...
[21:49:58] Finished 'cleanDist' after 60 ms
[21:49:58] Starting 'buildHTML'...
[21:49:58] Starting 'buildCSS'...
[21:49:58] Starting 'buildJS'...
[21:49:58] Starting 'copySounds'...
[21:49:58] Starting 'optimizeImages'...
[21:49:58] Finished 'buildCSS' after 549 ms
[21:49:58] Finished 'copySounds' after 575 ms
[21:49:58] Finished 'buildHTML' after 608 ms
[21:50:00] Finished 'buildJS' after 2.66 s
[21:50:01] gulp-imagemin: Minified 12 images (saved 5.23 kB - 51.5%)
[21:50:01] Finished 'optimizeImages' after 2.92 s
[21:50:01] Starting 'zip'...
[21:50:01] Size of game.zip: 13 KB
[21:50:01] Finished 'zip' after 88 ms
[21:50:01] Finished 'build' after 3.08 s
> stat zip/game.zip
File: 'zip/game.zip'
Size: 13312 Blocks: 32 IO Block: 4096 regular file
Exactly 13312 bytes length. Perfect!
What could be done better
The contest ended and my project reached perfect 13kB size so I take it as finished. Especially that Steem Monsters Game Jam closed 2 days ago. However if I had more time, could consider trying to work at below:
- compose more efficient wav sound
- draw even lower resolution monster sprites to pack more of them
- merge sprites into one image
- optimize text labels drawing
- reorganize javascript code for better minification and compression
- after done above, add new effects, features, scenes or even simple music
Gameplay
The game is playable under GitHub pages link:
https://mys.github.io/goblin-tower-13k/
Source code history
The game has beed done in <2 weeks. Every commit is verifiable.
https://github.com/mys/goblin-tower-13k/commits/master
Links
- GitHub repository https://github.com/mys/goblin-tower-13k
- GitHub commits https://github.com/mys/goblin-tower-13k/commits/master
- GitHub game https://mys.github.io/goblin-tower-13k/
- zipped 13kB archive https://github.com/mys/goblin-tower-13k/blob/master/zip/game.zip
Game looks great.
This review took a great amount of time since, while trying the game, I couldn't stop playing. :)
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @emrebeyler!
So far this week you've reviewed 6 contributions. Keep up the good work!
Congratulations! Your post has been selected as a daily Steemit truffle! It is listed on rank 7 of all contributions awarded today. You can find the TOP DAILY TRUFFLE PICKS HERE.
I upvoted your contribution because to my mind your post is at least 9 SBD worth and should receive 139 votes. It's now up to the lovely Steemit community to make this come true.
I am
TrufflePig
, an Artificial Intelligence Bot that helps minnows and content curators using Machine Learning. If you are curious how I select content, you can find an explanation here!Have a nice day and sincerely yours,
TrufflePig
Your game was really cute! Good job finishing it for the jam!
great game I also got to somewhere around 3000 so it is pretty addictive! It is very interesting what people can do in such a small file size!
Hey, @mys!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
I appreciate the upvote on my video, but theres no way you watched it, as its 5mins long and its been online only 30secs...
You are smart ;)