A sick and busy week

Roguelike Celebration; Arkham City roguelike mockup

A week ago, I was at the Roguelike Celebration. Josh Ge did a great writeup of the whole thing with lots of photos, so I'll just say that I met a lot of great people, showed off Dr. Hallervorden, and came away inspired.

I fell sick the Tuesday after the conference, and wasn't really functional until Friday night, when I had enough energy to make this mockup capturing an idea I'd had at the conference:

Arkham City as a roguelike mockup

Having done that, I decided that 10PM on a Friday night was a great time to translate the REXPaint manual into HTML. REXPaint users, you're welcome.

Roguelike tools in Nim

On Saturday, I got the itch to try out the Nim programming language, so I skimmed the tutorial again and sat down to do some real coding in it. Naturally, my first program was a wrapper for the C[++] library BearLibTerminal, which I used to make Dr. Hallervorden. It was a neat experience to have my first program consist mostly of C bridge code.

With my BearLibTerminal integration finished, I moved on to a REXPaint .xp file parser. These are the two basic tools of game development for me: a way to display stuff, and a way to render ASCII “images” to that display.

REXPaint uses a straightforward binary format, except it mixes 32-bit integers with 8-bit integers, and the 8-bit parts throw off the alignment of the 32-bit parts. In safety-oriented languages like Nim and Swift (which I wrote a REXPaint file parser for earlier this year), this means it's necessary to unfasten your seat belt and do pointer arithmetic, even though the car beeps annoyingly at you the whole time.

Here's how you read a 32-bit integer from an arbitrary spot in a binary blob in Swift:

let data: Data = Data(contentsOf: URL(string: "file://foo"))
let pos = 13 // or whatever
let theNumber: Int32 = data.withUnsafeBytes({
    return Array(UnsafeBufferPointer<Int32>(start: pos, count: 1))[0]

Here it is in Nim:

let data: string = readFile("foo")
let pos = 13
let stringPointer = unsafeAddr(data[pos])
let theNumber: int32 = cast[ptr array[0..0, int32]](stringPointer)[0]

I packaged my code up into two libraries:

To use them, you simply nimble install and import them.

Generally, my impression of Nim is that it's a workmanlike language, but it also feels like somebody took Swift and beat it with jumper cables.

Literally Canvas JSification

For the past few months, there has been a community effort (be still my beating heart!) to translate Literally Canvas's CoffeeScript codebase to ES6. Today, that effort crept forward a little bit more: someone separated the “core” version of Literally Canvas into its own repository! This means we can significantly reduce the size of the main code base and drastically simplify the build process, removing barriers to new contributors.

That's great news for me, because I would love to move on from being involved with Literally Canvas.


That doesn't mean I'm done with open source libraries that help you make illustration programs! I announced on the Asana blog on Monday that we're releasing Drawsana, a “markup tool construction kit” for iOS in the same vein as literallycanvas-core.


When I wasn't doing all that stuff, I was playing Tangledeep. The developers were showing off the upcoming Switch port at the Roguelike Celebration arcade, so I had an excuse to try it out again. It's progressed a lot since the last time I played a year or two ago!