Making of Riko, a free JavaScript puzzle game

Published

February 21, 2021

gamedev devlog js

The city was quiet, friends had moved away. Offices were no longer filled by the buzz of work. My wife had just been laid off and toilet paper was hard to buy. So I made a puzzle game.

This post is a mix of journal, game dev, and miscellaneous thoughts from releasing a game that made one player comment “I broke my heart in the four rooms on the top floor”. The post is loosely split between analytics, how the mechanics were developed, how audio and art was produced, how game tools were made, and the tradeoffs made.

There’s a horrifying trend going on in gaming. Puzzle games are getting less violent. The sokoban genre that involves arranging boxes in a warehouse is especially nonviolent. “Sokoban but with a gun” became Riko.

Six months into development, I couldn’t finish the final levels in the game. My friend Nick was able to keep making the last sequence of levels harder. Completion was always just out of my reach. He’d discovered rules and combinations that bent the systems I had coded. There was only one way I could ensure I’d eventually complete Riko – I published Riko at Itch.io on the first of August.

Four days after release an event alerted me of a full game completion. Humbled and shocked, I watched more and more people play and finish the game. Bontegames awarded Riko the third best browser puzzle game of 2020. Jonathan Blow streamed and critiqued the game for almost an hour!

If you’re interested in playing, check it out here: https://spyr.itch.io/riko

Otherwise shoot open a door and walk with me to the next section.

Marketing to convince you to play the game. I excel at marketing. ;)

Analytics

Impressed by how the Slay the Spire devs used data to balance their game, I implemented some tracking events. We didn’t do anything useful with the data because we didn’t know how. Riko had been balanced by family members turned playtesters. The data did show us that some people really liked Riko.

In 2020 we collected:

  • 42 full game completions
  • 5,060 completions of the first level
  • 20,200 total levels completed
  • 1,110,000 player turns

We also have this sweet graph from a couple weeks after release. It shows the number of level completions. On this graph you progress from left to right as you complete levels.

Level Complete Events

The majority of levels could be completed in around 100-200 turns. However the level “Four Rooms” is a major outlier taking 4,500 turns to solve.

I’ve learnt that tracking certain player events is vital in understanding how players engage in your game. It is a lot more data than the 24 itch.io ratings. Though I want to thank you if you rated Riko. It helps tremendously in Itch.io page rankings.

How were mechanics and levels developed?

We wanted to let the game build itself. I had an initial idea in my head of the theme and feel of the game, but no idea for the mechanics. Mechanics were developed by making them and playing them. Anything that didn’t feel interesting was removed or improved.

The first failure was having Riko’s gun shoot a bullet. Every turn the bullet would move one grid space. This felt rubbish as you could walk alongside your bullet. Hitting targets took predicting the time the bullet would travel. We improved the gun with an instant firing laser gun.

Riko shooting slow bullets

Seriously slow bullets.

We also had boxes that could explode damaging multiple grid cells. No puzzle ended up needing anything that could explode and the mechanic was cut. However worry not, the code was not wasted. Instead it’s now used for mirrors that reflect your laser. Turns out placing explosions and placing your laser is identical.

Bobby Lockhart helped us complete the first puzzle when he said “all games are just lock and key puzzles”. That night I implemented a button that opens a door when something is on it.

All the mechanics evolved something like this:

  • Bullet is too slow. Lets make it a laser.
  • A laser can reflect! We need mirrors.
  • Cool! Mirrors are also blocks!
  • What else can you shoot? Maybe enemies?
  • Enemies are also blocks!
  • Everything is a block!

Whilst programming new mechanics and features, we were constantly playing the game and creating test levels. Nick was able to discover some of the most interesting interactions as he would understand the game purely through play. I’d constantly get stuck on his simple test levels. He discovered interactions such as the backwards enemy push, and herding clumps of enemies.

Here’s a concrete example of how one level progressed through development. Nick developed this level when there were almost no mechanics in the game. It’s a mechanically simple puzzle that tests some advanced movement. The objective is to push the block through the maze to the button.

First version of the block maze puzzle.

By playing the level we figured out what parts of the maze were interesting. Then we stripped out everything else. Below is how the maze ended up. Instead of a seemingly random scattering of walls, there are distinct features that look intentional.

Crate Maze

The level has been refined to be the same puzzle, but more intentional.

It’s almost impossible to make a level that teaches a certain puzzle behavior until you’ve discovered them as the designer. Now we’re finally able to make the easier level that teaches these mechanics.

Simple maze level

An introductory level to movement in tight spaces.

Another example of this phenomenon was the Four Mirror room (the one that took ~4,500 moves). It was one of the first levels Nick built with the mirror mechanic. It was a combination of four smaller levels that were incomplete. Putting four incomplete ideas together made the hardest level of the game. Similarly, the “Precarious bridge” level was my first level exploring joined blocks, and navigating them across gaps.

Both of these levels ended up being almost unsolvable by playtesters. So we worked backwards, with the first group of levels being the last made.

How did we Audio and Art?

Music was composed by the brilliantly talented Markiyan Melnychenko. He composes bops and I’m sure would appreciate any comments or commissions.

I did the sound FXs in Reaper which is an affordable and brilliant program. Free sound samples came from this incredible free game audio library GameAudioGDC.

I’d take multiple sounds and mix them together with all sorts of wacky effects. For example I’d take a very realistic sound of concrete breaking, and add a bitcrusher to make it feel a bit retro. Or I’d softly overlay a randomized glitch effect. I highly recommend using Reaper, as it’s easy to get started with, and will not get in your way as you become more familiar with it. Audacity is often recommended but gives you far less functionality.

Take a look and listen to the crate explosion sound:

Reaper interface of crate explosion

A screenshot of the crate explosion sound in Reaper! Three free sounds mixed together with effects applied.

Audio was a lot of fun.

Art was drawn pixel by pixel with a mouse in Aseprite. I did cut some corners like having code arrange all the art for me. Variation was done by randomly choosing from a selection of hand crafted tiles. A random seed was set to ensure a level wouldn’t look different every time the player loaded it.

Cutting corners with art was a must. For example the world map auto generates the level icons from the level data. Anywhere I could add subtle artistic variation with a system, it’s added with code.

Riko 3d render with a perspective camera

What if I had the resources to make it 3d?

How were the game tools developed?

Riko was developed in TypeScript using Phaser. Phaser handles rendering, audio, and loading assets. It also integrates nicely with Texture Packer, letting me easily load a texture atlas.

The undo system uses Immer.js. The entire game is an immutable data structure that immerjs modifies. These modifications create small patches recording the change, and a revert patch. The undo system is a list of these revert patches that when applied to the game state, undo moves. It works extremely well!

Bullets and undo system - slow bullets were cut from game

A lot of bullets, and a lot of undoing!

I built a very rough level editor over a weekend and hosted it on Netlify so that Nick could develop levels. It’s very low tech, using React to layout different components. You can play with it here if you dare: http://riko-game.netlify.app/?dev=true

Building a playable level!

I added new tools to this custom editor as we made the game. More complex actions have developer console commands. Ultimately it’s a tile placing app that lets you quickly change a level and play it. Nick could iterate on levels while I did coding and art. He’d send me a JSON text file. I’d copy paste it in the right place, add it to version control, and the level would be added to the game.

Why did I code my own janky editor instead of using a free product like Tiled? Great question! Coding a custom editor for a small game is quick. It opens the door to your own extensions and tooling. For example when doing the art for the game, I really wanted to see how the levels looked together. I quickly added a screenshot tool that flicked through the levels taking a screenshot of each one.

The game started off very brown.

This immediately identified a need to work on colors and their progression through the game. Nick also used this tool to quickly create screenshots of levels for mocking the level map.

What tradeoffs?

Although I wanted to make an MMORPG fantasy game the likes the world hasn’t seen, I knew that could take me the rest of my life. Inspired by the Pico-8 fantasy console constraints I decided to go small. The 128 by 128 pixel resolution was chosen to ensure the art would be easier for me. Level size was restricted to 16 by 16, keeping ideas focused. Tiny levels also avoid needing any camera functionality in the game or editor. The keyboard input system also isn’t great. Sorry :(

These were necessary to get the game out the door and in your hands. I regret not spending more time on the input system.

Till next time

Thanks for reading this post!

If you have any comments or questions, please don’t hesitate to message me on twitter. And please follow me if you’d like to be notified of my future projects!

Thank you and see you around. :)

The end