On writing your own Visual Novel engine


As some of you are hopefully aware, I am the main (and at the time of writing only) developer of the Tsukundere engine, which at the time of writing only I use to create Visual Novels. Development of the engine and all of my games takes place on a machine running GNU Guix, which is very good for developer environments, turns out to be a major disadvantage when trying to ship your results elsewhere. Especially the Microsoft OS. Each of my games is discovered by at least one person lamenting the loss of their "privilege" to run just about any software without thinking too much about it.

As a little known side fact, I also packaged Ren'py for GNU Guix, so I feel very confident in comparing these two. Still, one must not forget, that one had 17 years of development since its initial "4.0" release (16 if you account for the fact, that the latest release of Ren'py is a year old) and the other had barely more than two months. Yes, Tsukundere is very much in its infancy.

The Ren'py Experience

Visual novel developers love Ren'py. And for several good reasons. For one, it's written in Python and its syntax closely resembles Python. This is a perfect choice for a language meant to be used by people with little to no background in computer science, since Python – for better of worse, depending on the situation – is very close to the "ideal" of pseudocode. It comes with a huge set of templates out of the box, but at the same time allows full customization for very artistic programs. And very importantly, it can create binaries for Windows, Mac, Linux and Android regardless of where you're developing, and it's starting to take on the Web as well.

Visible problems

Of course, Ren'py is not perfect. The most well-known problem to developers and players alike are tracebacks. It is trivial to create a script, that results in a traceback, but often not so trivial to recover from one. And given that Ren'py is more often interpreted than compiled – or rather, is compiled as the game is being run through the launcher – one can hardly catch problems early. Ren'py does have some tools to do that, but I doubt that they're used all that often, especially by the uninitiated. Paired with the fact, that Ren'py can't just simply crash the application like one normally would on an uncaught exception, because its target audience – both users and developers(!) – are possibly command-line illiterate, the resulting behaviour has to be one, where your failings are published across the screen of the game.

Invisible problems

An observable, but usually ignored fact, is that Ren'py has to copy all of itself as well as its dependencies into the distribution tarball in order to facilitate the aforementioned portability. This has become the de facto way of publishing visual novels built with Ren'py and it is one, that I very much dislike. The lib directory of a game can easily take up a third if not more of its size and is copied over and over and over and over. You'd think, that having Ren'py once would be enough to run any of them and that is in fact the case, but you still have to copy Ren'py everywhere, because no one bothers packaging it.

Except that people do package Ren'py already. And that's not just Ren'py packaging itself whenever Ren'py generates a distribution tarball. Admittedly, Debian and Ubuntu are slow as usual on the uptake, having version 7.3.5 in the dreaded "sid" and focal respectively with older LTS being stuck on older versions of Ren'py. Rolling release distros like Arch, Gentoo and yes, also GNU Guix, will typically update their Ren'py package sooner than every six months, however. And it's not like distro maintainers do nothing here. Both Arch and Gentoo ensure, that it builds with the system's fribidi (Guix is currently lacking that patch due to my oversight). Gentoo also ensures, that system paths are honoured during bootstrap. And I myself had to rewrite the entire "renpy" executable (i.e. the bootstrapping code) in order to make it work on GNU Guix as Ren'py would otherwise struggle with bootstrapping if left to its own devices. The resulting package is usable from a Guix perspective – I myself use it to play games downloaded from itch.io – but I'd hazard a guess, that it does betray some of Ren'py's expectations.

How Tsukundere differs

There are several areas in which Tsukundere differs from Ren'py. Some of them are deliberate design decisions, whereas others are merely signs of immaturity. For one, it does not have a launcher like Ren'py. Instead, projects have to manually set up their calls to run-game. The bootstrapping code found in Hot Spring Mermaid may at one point end up being part of a more general launcher, but there's still a long way to go.

On a somewhat related note, Tsukundere also does not yet ship its own build system. Shocking, I know, despite being a project written in 2020. While this might not look like it's related to the launcher issue, it very much is, since the build system for a game will also (for the purposes of debugging) need to launch it in the same way as expected by the launcher. I currently (ab)use the GNU build system for most of this, because apparently I love writing Makefiles.

In terms of tracebacks, Tsukundere does crash your game if you do something wrong, so at least the command line debugging cycle works as intended. I am still working on making those tracebacks usable in most contexts. For instance, if you set up your code in a way, that a sprite is missing or you reference a missing sprite, it will only notice that when it tries to divide #f by 2 during rendering. Have I mentioned, that Tsukundere is still a little immature yet? On the other hand, Tsukundere encourages ahead-of-time compilation, which makes it much easier to capture unbound variables and the like.

And also, quite importantly, the only well-supported system is GNU Guix. Tsukundere also has some CI Debian builds, but no real Debian maintainer, so take their results with a grain of salt 😉. It should in theory be possible to run Tsukundere on other Linux distributions (and also Mac using Homebrew), but no work has actively been put into that yet. Contributions, that add real support, are of course always welcome. Also, as I recently found out, Windows builds are completely busted. Tsukundere does not build against Guile 2.x, and the only existing Guile 3 packages on Windows do not support SDL (there is a bit of a history on that, which has been shared in the #guile IRC channel). What's the takeaway from all this? Upgrade to Guix, of course!

Get I've met a Mermaid in an Onsen

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.