2019-03-12

Baconist

The Baconist is a web-based puzzle game, with text graphics. I made it in 2018. The goal of this project was to check out how viable would it be to build some kind of game using Haskell compiled to Javascript with GHCJS.

You can play The Baconist here.

Baconist screenshot

How to play

The only keys you need are movement keys. Two schemes are supported: the numpad scheme and vikeys scheme hjklyubn. I’ve also implemented rudimentary mouse support but it will probably be very painful to play it with that.

The goal is to solve puzzles to find “Energy Cells”. The game is quite incomplete but I made sure to implement at least a few interesting game mechanics. I don’t think I’ll come back and finish this game. I learned what I set out to do: how does Haskell fare in webland.

Performance

The performance of the compiled code emitted by GHCJS is disappointing. As of today, the Baconist will run very slowly on pretty much anything except a recent Chrome browser on a powerful CPU.

When I was measuring performance, one of the benchmarks I was using was the time it takes to calculate the field of view. The Baconist has a complicated portal-based sight which is more expensive to compute than most roguelike field of vision algorithms.

For The Baconist, the GHCJS performance seems to be about 20x worse than natively compiled code with just GHC for computation-intensive code.

It probably would have been better if I had chosen not to have field of view. If you compare The Baconist to another text-based game I made in 2017, Submarination. (This is also incomplete so don’t start playing expecting any kind of real gameplay). Submarination does not have field of view (you can see through walls) and as such performance is a lot better.

Thoughts on GHCJS

GHCJS is fricking amazing in terms of just how much Haskell code compiles as-is. It’s insane. Even advanced RTS features like threads and STM and weak references work out.

This is why it is unfortunate that you cannot expect good performance out of its code. I’m sure for many applications this does not matter but it does matter for me because I like to build simple games in Haskell and they need some amount of performance.

Future

After I did this project, I learned about the existence of Asterius and WebGHC. These are work-in-progress (at least as of today) Haskell compilers that target WebAssembly. GHCJS outputs Javascript.

My hope is that maybe later on I can recompile the Baconist with one of these compilers to check if they are any better with performance.

Source code

Source code is here. You compile this with Stack Haskell build tool. There is a separate stack-browser.yaml to compile for browser.