Lost in Asterion – js13k 2017 – v0.2 released – final compo update

This is the final update of the development of Lost in Asterion for the 2017 js13kgames contest. I managed to create an interesting exploration game, and I’m pretty happy with the results (check it out here). Giovanny Ramirez created a cover art for it and it’s amazing

Following is the journey thru the last 10 days of development. You can see the previous days here and here.


September 2 – Added enemy support with a single kind of enemy.

Enemies (actually, general “entities”) are updated once on each iteration of the game loop, they have their speed affected by gravity, are checked vs collisions with the world objects (in which case they are completely halted).

Enemies have a simple AI where they check if player is close enough. If that’s so they’ll calculate the direction to the player (in simple manhattan terms, not degrees) and then propel towards the player using they acceleration in x and y.

They are also drawn on each iteration of the game loop, scaling simple geometrical operations based on their size, around a central point.

September 3

Attack enemies using bubble beams: Every time the player presses ‘z’, a bubble beam is created in the direction he is facing. The bubble beam is a group of bubble created in sequence within milliseconds between each one, all originating from the same spot and in the same direction (with slightly different speed).

On each update cycle, entities are checked for collisions with these bubbles, in which case their health is diminished and they are drawn in white for some millis to show they have been hit.

Added sound effects using the jsfxr library. At this point I wasn’t still worried about size. I just added it and used it for movement. The way it works is providing the library with a set of parameters mirroring the configuration of the asfxr player, and they are played using the web audio API.

Also added support for plot messages tied to positions within the world fragments

September 4: Designed and added more plot. Designed the overall world map too.

September 6: After wondering how I’d tackle some variety on the maps, I decided to try to generate then procedurally with a simple “rogue” like 9 interconnected rooms algorithm.

The way it works is a random size is defined for each of these rooms, and some of them may be discarded. Connections are then defined, and then it’s drawn.

While it’s a simple generator, in the middle of implementation I noticed: a.) it was taking too much time to implement, b.) it was eating quite a bit of source code and c.) it wasn’t really worth implementing it since I wanted to have fixed maps in the end (I intended to seed the map generators)

So, I discarded the initial idea and went instead for something completely different. I rendered the maps in a spreadsheet and encoded them as bytes. The map is represented as a bitmask of open/closed spaces, I chunked it in 8 spaces long fragments, and encoded them as an hexadecimal byte representation.

Screen Shot 2017-09-16 at 4.29.19 PM

This allowed me to represent a 24 spaces segment in 6 bytes. The full map for the first temple section, which is 18×24 sectors big, is represented by this string: FFEFFF398FC1018781011C800185C1458DEFFFFDEFFF8187FFE184000084000080FF0184FF0184FF01ECFF03EEFFFF87FF0780FF87FF

When the map generator is creating a fixed map sector, it decodes the String into a boolean mask, and generated solid blocks based on the desired scale.

I used this technique to create the map for the Temple.

September 7

I had a corporate leadership training during the morning. I designed some creatures while waiting for it to develop. All of them using basic shapes.

I was running out of time and the world was not yet ready, so I focused on trying to complete it.

I added some sections requiring the player to have a given orb to pass thru, else player’s speed was drastically affected. This acted as a simple “plot device”, making players have to transverse the map in 3 different “segments”, giving the player a sense of non-linearity while still having some strict control of the game flow.

Added more world content by configuring the map generator for Volcanic Rift (simply using fiery colors for the background) and creating another fixed map for the City Ruins (thus capitalizing on the code added to handle it on the temple ruins).

Having the world definition in a good shape, I continued by adding enemies generation on demand. As the player moves around a sector enemies will be constantly generated off screen up to a given limit.

Finally, I added Game Over flow, the game loop will check if player is dead and render a different screen instead.

September 8

One remaining piece to make the game playable was having a better victory condition, so I worked on adding an end boss. Also started working on support for different kind of enemies.

September 9: Rendered different creatures types based on the designs I had made. Used simple canvas 2d content drawing directives such as fillArc, as well as paths being stroked and filled.

September 10: Assigned enemy level / difficulty based on sector (harder ones as the player progresses).

Also made some missing powerups work: Made the bubble beam work only if the player had the Orb of Verra Kera, and hull recovery only happening if he had the Orb of Gabrielle.

Also added the “title screen” of sorts, and continued polishing the “plot”.

September 11 – Begun the quest to reduce space. Started by questioning myself whether I wanted to keep (and may be even extend) the plot and content OR if I’d rather work towards keeping sound support. I decided for the latter. Started having 2.76 KB of compressed code to take away.

This was extremely painful, some of the things I did were:

  • Ditched the original minified version of the Voronoi library. Instead included the original source code into the minification flow, and removed some parts which were not being used.
  • Move code into data, placing redundant code sections into methods executing batches of operation based on arrays of parameters.
  • Change formatting of definition of function prototypes using Class.prototype = { fn: {} } instead of Class.prototype.fn = function(){}. *
  • Replace all const with var*
  • Reduce HTML infrastructure to a bare minimum, no css nor styles, very plain index.html with no HEAD section or encoding declaration, etc.
  • Remove “use strict” from all modules
  • Shorten plot and ending messages.
  • Move “private” functions outside the functions prototype (effectively allowing uglify to mangle their names)

For the things marked with *, I found of they didn’t really help much in the end since zip compression took care of repeating Strings pretty well. The only thing that helps is actually removing content.

Additionally, I adding the knock back mechanics to make “combat” more interesting (and making the game less hard by allowing player to tackle enemies away). I also added the drill as a default “melee” weapon before acquiring the sonic beam.

September 12 – I was running out of time and hadn’t done proper testing so I released a first version for public testing.

I worked hard to reduce the package size more and more, doing the following:

  • Use the same SFX for the movement fans and for the drill
  • Modularize the Voronoi library. Extracted the different classes used by it on different modules, hoping to refactor them to move private functions from the prototypes into module scope functions. I actually had to roll this back afterwards since the additional module management increased size, but it was helpful to simplify the modules individually and prevent introducing bugs into an unknown code base.
  • Configure uglify to mangle properties starting with underscore (both functions and attributes). This was extremely helpful! I proceeded to use it mainly on the Voronoi library.
  • Cut more plot.
  • Remove unused error message Strings.
  • Ditch the minified jsfxr file and include the already minified source into my own minification process.
  • Merge modules into single files, making the code less readable for now.

Went to bed with 50 bytes left and the plans to finish thru next morning as well as doing some testing…

Then, while already on bed around 1AM, decided to check the deadline and found out it was 13:00 CEST, not Central American Time as I initially thought. That meant it was happening in less than 5 hours. The panic.

There was no way I was going to lose all the time I had invested, so I got up and finished the adventure by completely removing two kind of enemies and cutting the plot text even more.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s