I’ve long been fascinated by visual novels and text-based games, not just as stories, but as systems where writing, visuals, and interactivity intersect. Recently, I decided to stop overthinking it and actually make one.

In this post, I’m going to cover:
- Why I chose Ink + Godot for visual novels
- The pros and cons of Ink vs Twine, Ren’Py, and Yarn
- How I scoped a small VN for a game jam
- How I structured my story in Ink
This is part 1 of a series documenting my process of building and releasing a short visual novel.
Starting the process
I’m currently developing a larger VN/hidden object hybrid with the working title of, ‘Gemseeker’. I wrote a first draft of the script (and a prequel novel!) and then realised that the game was going to be too large. That’s the classic first-time game creator pitfall.
Once I’d shaved the script down to size, it occurred to me I wanted to make a much smaller VN as a sort of practice run. While by this point Gemseeker’s prologue chapter is already semi-functional, it’s going to take a lot more work to get it finished. In the meantime, there were questions I had about things like exporting, optimising and distribution that I thought would be best answered by making a smaller visual novel and then just putting the damn thing out there. For me, I learn best when I actually go and do something, and thus, a self-motivated game jam began.
For starters, I decided on two key things. First, I wasn’t going to spend more than two weeks on it, tops, with a preference for finishing within a week. Secondly, I was going to use Godot with Ink, because I wanted to replicate the engine setup for Gemseeker.
Ink and Godot for Visual Novels
Ink is a narrative scripting language designed for interactive fiction. It allows authors to create text-based adventure games. The resulting story can then be exported to the web or simply as a JSON file. This allows for the creation of beautiful browser text ‘choose your own adventure’ stories, but it can also be plugged into game engines to take advantage of functionality there. In this sense, Ink is similar to Yarn, another narrative scripting language.
As of this writing, Ink has two different integrations with Godot, InkGD and GodotInk. The latter requires the .NET version of Godot, which guarantees a hefty size for the final game (just a trade-off of using C# — more on that later). InkGD, which I have yet to try, is more portable and uses Godot’s native GDScript.
I am using GodotInk for Gemseeker, thus the choice remained the same here. If you’re wondering why I chose GodotInk for Gemseeker, it was a matter of the integration having more recent updates and my understanding that it has better performance.
For me, performance probably wouldn’t have mattered much for a small VN. But Gemseeker isn’t small, and I tend to build systems with future complexity in mind. So I opted for the C# route.
(https://github.com/paulloz/godot-ink see here for GodotInk on GitHub).
Ink vs Twine vs Ren’Py vs Yarn
While researching solutions for Gemseeker, Ren’Py, Twine, and Yarn did come up. Ren’Py is one I’m pretty familiar with, having years ago made an attempt at a hidden object game of sorts using the engine. Even back then, as a youngster, I really wanted to make HOGs and tried (and failed) to manipulate the thing to get it to do what I wanted it to do. There are lots of languages and tools out there that can help authors create the interactive fiction of their dreams. There are four in particular that I’ll highlight, starting with Twine, below.
Twine:

If you haven’t heard of it, Twine is a popular software for writing interactive stories, which visualises your passages on a flowchart. Stories are exported to HTML and can be dolled up with CSS and JS. I actually really like this tool, especially coming from a UI/UX background. I can see how this could be used to supplement a user flow diagram or even create user personas! And as for scripting interactive fiction, it’s easy to get started and the visualisation of the different passages is something I wish more tools incorporated.
Ren’Py:
As for Ren’Py, I believe this is the most popular language/tool for creating visual novels, and for good reason. It’s approachable and very focused on what it wants to do, which is enable people to create VNs. Its scripting language is based on Python, which I imagine would allow people with sufficient command of this language to bolt on additional functions.
Yarn:
Yarn is very similar to Ink. The Yarn Spinner dialogue language can be added as an extension to Visual Studio Code. You write your story in Yarn Spinner, and your game engine of choice handles the playback. I think the fact that the extension is within VS Code would likely make it a very attractive option for developers. When I started Gemseeker, I actually did give Yarn a whirl. I had some difficulties getting it to work within Godot (which I’ll put down to my own lack of dev knowledge rather than any issues with Yarn itself). As a result, I haven’t explored it further. However, I would definitely be interested in trying it again when I have more confidence.
Choosing Ink:
I found Ink very straightforward to get working with Godot, and I was able to fairly quickly make a VN Runner based on their docs.
I think both Ren’Py and Twine are very worthy picks for anyone wanting to create ‘Choose Your Own Adventure’ stories, but I started looking into Ink and Yarn because I knew I wanted to take things further and introduce more complex functionality into Gemseeker. For example, I knew I wanted to allow for puzzles (including hidden object scenes) and maybe even for 3D. Yarn and Ink then emerged as workable solutions.

If it’s not already obvious, I’m not a software developer; in the course of my career as a professional designer, I’ve made websites with HTML or CSS, and I’ve dabbled with JS, but a programmer I am not. (And working as a UI designer for games and apps definitely makes one very jealous of the things software developers can make!)
That being said, I do have experience with Unreal in an artist capacity, and I’ve also made certain attempts with Unity. I can say that for newbie/indie devs, Godot is an excellent choice. It’s lean, open-source, and I personally find it friendlier to work with.
In the end, Ink is my current choice when it comes to writing interactive scripts, because integrating with Godot is quite straightforward. I would assume that its integrations with Unreal and Unity are exactly the same.
Writing stories in Ink
I chose the title of ‘Something by the River’ for my game jam. Because the story is so short, I structured the story around a single conversation between two characters. Two characters (and one cameo), two locations, and seven endings (which are achieved based on choices the player makes in conversation). I took a day to write most of the story, which ended up being 8888 words (as of this writing).
Because I knew I had to keep things contained, there were certainly compromises during the writing process. On the other hand, because of the nature of digital storytelling, it’s straightforward to go back later and add additional things, like extra dialogue, scenes, or even endings.
I wrote the entire script directly in Ink. Some people might choose to write in a word processor where they would have access to grammar and spelling tools, but I find that approach pretty unwieldy. It does mean that there’s more risk of spelling mistakes getting through; I hope that ProWritingAid Everywhere eventually hooks into the Ink writer (it doesn’t for me — wonder why?).
Explaining Ink
Ink stories are comprised of knots, which contain different passages. As you can see from this screenshot, passages can have tags to indicate speaker. In my case, I have tags to indicate things like background image, character portrait, and even sound effects. These things will be familiar to anyone who has read visual novels or created them. These tags can be read in the VN runner, and assets can be swapped out from within a dictionary (I will discuss the nuts and bolts of my script in another post in this series).
Ink choices are prefaced by ‘*’ or ‘+’, the former of which is used for choices that appear only once. As you can probably see from the screenshot, I haven’t structured Something by the River in a complex way, though Ink stories can certainly get very complex. There are knots and then there are choices that divert to different knots.
There are no variables in this story, though Ink can definitely handle them. In concert with your game’s global variables, they can combine to create some very complex conditional branching. In Gemseeker, I’ve opted for the simple approach of dealing with variables only on the Godot side. I do, however, want to explore all Ink has to offer in another project (perhaps a web-based one?).

Next steps
With the story finished, the next thing to do was to boot up Godot, add the Godot Ink plugin, and import the Ink story.
In the next post, I’ll break down how I built my visual novel runner in Godot — including how Ink tags drive UI, portraits, and audio. This is where everything starts to come together.
The rest of the series:
→ Part 1: Overview
→ Part 2: Building the VN System
→ Part 3: Art and Design
→ Part 4: Exporting the game