This last part was what got me, I was really curious how others fit games in such a small space – what later turned out to be much more than it looked on the first sight.
As the competition was already halfway or was over when I found it (I can’t really recall) I could only examine others’ entries and decide I will participate next year, in 2013. I also tried to gather some ideas and set up a concept before the competition start date – strictly not a line of code was written.
There is a theme each year (which is optional but worth bonus points if honored), for 2013 it was bad luck – and I skipped it entirerily…
Okay and now about my entry.
My concept was to create a 2 player networked tower defense/tower attack game.
I must admit I am really bad at naming things, I just called the main (and only) client side file 13312.js and not long before the deadline I came up with the exceptionally uncreative name untitled13.
Of course to fit in 13 kB entries usually do not use existing engines, they are written from scratch – a thing I don’t mind at all, I’ve been always curious about the details and liked the control one has when starts from the ground up.
For graphics and animations I decided to go with a fixed color palette and dynamically generated content. All the objects consist of one or more layers rendered by a function that takes a string that describes a series of commands and their parameters. It turned out only two commands were necessary, a “draw a closed polygon filled with a color” and a “draw an alpha overlay” for shadows. The parameters were simply X and Y coordinates of the points, represented as characters in the base64 character set (64 distinct values), multiplied by the size of sprite. (For example: sprite size is 64×32, string is “AAAzjj”, therefore the coordinates are 0;0, 0;25, 35;17).
The map consists of starting points for the attacker, paths for the units to walk on, path intersections with switches, a few objective tiles for crystals the defender has to defend and concrete blocks to build the towers upon. There are three types of monsters with different parameters (speed, health) and three towers with different parameters (attack type, damage).
The networking approach is pretty simple but the most interesting part: the initial state is known to both players (the map is fixed in the entry version, in later versions it is randomized but the seed is shared), the mechanics are known as well and the actions can be described easily. So I came up with the idea to run a whole game instance for both players, create delayed action queues for them and synchronize them. When one player clicks a button the action is added to their queue with the configured delay, sent to the other player’s game, and a bit later executed on both instances at the same moment.
To get this working I needed reliable advancement of simulation steps, one that is not affected by skipped frames. I created a tick() method that steps the simulation by exactly one time slice (one simulation step), so when a frame is requested by the browser I calculate how many tick should have happened up until then since the last frame and call tick() that many times. (I usually go with this method to keep games frame rate independent – skipped frames are less worse than game slowing down.)
As both players are running the same game (only playing different sides), are aware of every details (only hidden from them), all events are happening at the exact same time, the game should play out identically for both of them. Later I learned this is called simultaneous simulation and it is the core of great games like Age of Empires, Starcraft and a lot more.
In this form however there is a serious flaw. There is no guarantee that the actions will reach the other player before they are due, it is blindly trusted that it will. For example: Let the action queue delay be 10 frames. The defender clicks to build a tower at frame #100, this will be executed at frame #110. If the network lag is say 7 frames then the other player gets the notification at frame #107, still 3 frames before execution, the tower gets built at frame #110 in both instances and shoots the attacker just before it reaches the crystal. But if the network lag is more than the queue delay, say 13 frames then at frame #110 the tower gets built in one instance, then the notification arrives at frame #113 for the other player, tower gets built at frame #113 when it’s already too late, the crystal was reached and the game is over. In the defender’s instance the crystal is saved, in the attacker’s the crystal is destroyed – the game is out of sync.
To address this the other instance must be notified about no action as well periodically to make sure nothing is missed. And when there is no info, the game should pause and wait until it arrives. This is a feature I had no time to think through and implement before submitting my entry.
The server part is running in node.js (my very first application) and it is very basic, it just matches the players by their IDs and passes the messages between them.
Random minor thoughts: The map is a hexagonal grid, which made finding neighbour tiles for concrete block and fog calculation ugly, but it looks so much better than a square grid – although it is handled like that. The map has fog to hide tiles that are too far away from units/towers. The UI is usable but confusing and unhelpful at first.
The project is on GitHub, the version I submitted is in the js13kgames-2013-entry branch. I like to commit often (and to have descriptive commit messages) so the submitted version had 381 commits, but for some reason I have not uploaded the final ZIP file, it was around 11255 bytes of 13312, so I used up 84.5% of the limit.
The game was better received than I expected, it ranked 1st place in Server category and 9th place in Desktop category.
The competition had awesome prizes including various licenses for game engines and gamedev related services, ebooks, physical books and vouchers. It was organized by Andrzej Mazur who tirelessly did an epic job, I’d like to thank him again for organizing and hosting this event, finding sponsors, arranging prizes and of course organizing the event annually since then, so thank you Andrzej!
Check out js13kgames.com for previous and upcoming competitions.