• Register

hake is a 2d action platformer with procedurally generated levels and challenging gameplay where the player must master the grappling hook and shield in order to overcome obstacles and conquer foes

Post news Report RSS hake devlog #4

In this devlog we explain a bit how we go about generating levels in our game.

Posted by on

Update 4: Level Generation using templates


When looking at how to actually create levels procedurally we had many ideas for more or less advanced techniques. But as we wanted to also achieve progress quickly, we got quite intrigued by the techniques used by Spelunky, especially of the idea to create templates and thus combine procedural generation with pre-designed components. This, in our minds, would make for the best end result, where the levels would enable new experiences every playthrough but where the design of the levels still would indicate a certain intent with the design and also decrease the possibility of weird combinations which a human designer would avoid. So, that’s what we decided on. A level in hake would consist of chunks. And a chunk would have a certain template type which would ultimately decide what that specific chunk would look like, how it should be populated and how it would correlate to other chunks.

Quick Iteration

In order to be able to iterate quickly on chunk template designs, to fix broken stuff or improve because of a lack of challenge for example, we needed some kind of tool, some kind of chunk template editor. And aside from finetuning mechanics in the game, it will be the templates that will require the most time, but they also bring most bang for the buck as well since we wanted an easy way to edit them and create more, each template adding to a more varied and hopefully better experience for the player.

Tools are often fun to make yourself, depending on the scope of course. We will touch upon this in another update. The first thought was to make an editor on our own using C++ or maybe Python, or perhaps trying to use another tile editor. We eventually ended up using Pyxel Edit, the tool we had been using to create the actual tileset.

The Template Tileset

By creating a new tileset, a specific one for templates, where each tile had a specific meaning, we could easily create and edit chunk templates and also get a visual indication of what the template would look like and how it would probably work inside the game. We kept it simple, so that we only had to define where we wanted solid wall tiles to begin with and then added concepts such as probabilistic tiles of both walls and spikes. The level generation code would then interpret this, and assign the correct tile ids (so corner tiles would look like corner tiles etc), placing decoration, determining if wall and spike tiles should be generated and so on until we had a proper chunk generated that fit well with other chunks depending on the layout of the entire level of course.

An example chunk template:


Part of a generated level:


Further improvements

Right now we are quite happy with this format. Whenever we need more functionality, it’s quite easy to define a new tile type and create the logic for it in code, as long as we don’t make too much spaghetti code of the level generation code. Right now we don’t have any drastic changes in mind, but it would be nice to be able to define where spikes could appear, and if they don’t it should be filled with regular dirt tiles. As well as adding new forms of static obstacles of course.

For even quicker iteration and easier playtesting, it would be even better to be able to edit the chunks in-game, so things that doesn't work can be removed right there and then. But right now we have other stuff to focus on, so that will go on the nice-to-have pile for now.

A sneak preview of our, very basic, inventory system:

screenshot 0


More screenshots when playtesting enemies and generated levels:

screenshot 6


screenshot 2


Don't forget to test our playable prototype here: Fjordaroo.itch.io


Thanks for reading!

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: