Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Words, Friction, Syntax: Stuff I thought about when making Videotome

In April this year I released Videotome, the first in what would become a small family of homebrew IF engines for making text based games. Videotome was made as part of a game entry for Domino Club, which has grown a small list of engines made by all of us for doing a specific style of largely text-based game in a format of our choosing that was harder to do with an existing engine (or, just for the fun of making a custom engine). 

The reason I wanted to make Videotome wasn't so much for the visual presentation and format, so much as the user experience of writing for it. I've used a couple of different engines over the last few years for writing text heavy games, and a lot of them have involved a degree of friction when it comes to doing the actual writing. This is what I wanted to avoid, with my intention being to make writing a game - or rather, a particular style of text heavy game that displays lines one at a time with some optional extra effects - as hassle free as possible.

Disclaimer: I think friction in game engines is a good thing too sometimes and this is absolutely not an anti-friction post. Friction forces you to consider if what you are trying to do is truly worth it. Friction is good. But! This is specifically a post about the kind of friction that slows me down when writing a game to the point where I don't want to write it any more.

Anyway. Did I manage to make a friction-free syntax for writing a game? Well, sort of, maybe, for me. But first, some case studies of other engines I've used and my thoughts on them.

Case Studies

TWINE

Twine is the engine I started making games in and eventually stopped making games in because I found it painful. Admittedly this was largely my own doing, because of what I was trying to warp it into and tying myself up in knots. The below is an engine-side excerpt from one of my more complex projects in it:


What I was running into here was the desire to display text one line at a time, in a strict layout, with colour highlighting and stuff like that. While there was probably definitely a smarter way of doing this, it still required the two main things I wanted to (and have, to some extent, managed to) do away with in Videotome: wrapping text in special characters, and explicit html commands on things. All the custom colour/format text in the above is wrapped in <span class="essex">styled text here</span> tags like this, which gets real annoying to write after a while (even not accounting for the rest of the macros/table layouts/etc).

(disclaimer: writing in Twine CAN be easier, if sticking with relatively simple formatting and letting it handle most of the formatting for you with default stuff or else precise CSS. but it still requires the phase of actually putting stuff in individual passages and linking it up).

What I found with writing games in Twine was that I tended to write the whole thing in raw text in notepad first, with some shorthand for characters, branching etc, and then manually transpose it across to twine in a tedious step of splitting it into passages and then applying macros/html tags/etc. This added such a speed bump in the development process that I hit a wall and stopped making the sequel to Superlunary and after that never really went back to twine with much enthusiasm, even to try a simpler method.

Irony here: I am manually doing html tags like this to handle some of the styling on this blog. No escape

BITSY

Bitsy has changed how it handles writing dialogue several times, but the consistent part of it is that the dialogue you want to play is attached to an item, sprite, or event such as going through a door. Then you walk into this and trigger the dialogue. To do a twine-like "one passage of dialogue, then manually advance to the next" you have to set these up as chains of dialogue attached to the same or different items/sprites/doors. The most painful part of this would be a) splitting your writing into individual passages and placing all the items to progress through by moving your character into them. In the case of text heavy bitsy games that had no obvious character movement (e.g. Terrortoma) this means an invisible character moving through invisible items over a background image.


Text item given a single dot to illustrate (usually invisible)


 Raw text in bitsy code, each chunk separated by a hyphen. THIS part is actually pretty fluid to write if you're not doing anything fancy inline, and I would usually make it in notepad again (are you spotting a trend with how I write games). The friction mostly comes from then integrating that into the engine, hooking it up to something to trigger it, and translating my notepad shorthand into actual engine commands.

The second most painful part of this is manually working out how lines wrap across text boxes. The importance of this wrapping & pacing is something I emphasize when showing people how to make text-heavy games in bitsy, or any game; there's a good thread explaining this here (featuring one of my games as a good example😊). An example of text & manual line breaks written in another of my games, Ace & Hearts, is below:


This also shows another friction in Bitsy; wrapping any text you want styled in a particular way (e.g. in a particular colour) in commands like {clr3}this text is a custom colour{clr3}. This is something I wanted to avoid; for my purposes it's no improvement on the <span>s used in my Twine example.

I am painfully aware that none of the above is really what Bitsy is designed to be. Adam has been pretty explict before that it's inspired by old Zelda games and is basically directed at that format, with all the other uses of it a sort of welcome if ancillary use case. I include it here becuse for ~2 years it was my main engine, and offered me the most intuitive way to tell a story with control over pacing and display of images. And the wider bitsy scene does favour quite narrative heavy games over, like, capital-G Gameplay, so I don't think it's that unfair to point out its relative clunkiness when it comes to writing a lot of text in it.

REN'PY

Ren'Py differs from the first two examples by being a visual novel engine and not a text or pixel art heavy engine. In theory this should make it more amenable to writing games how I want: each line I write becomes a new displayed text box, and I can write it close to writing a non-game novel; just words in a document.

In practice... it was not like this. Ren'Py text has to be wrapped in doublequotes, and it follows a very specific format of command shorthand and attentiveness to indenting. Below is an ending sample from Slasher, Interrupted, showing the multiple levels of indenting and the alternating text and non-text commands, with each line of dialogue separated out.


My main gripe with Ren'Py was how vulnerable it was to a single misplaced quote, tab, space, etc. Making SI was a constant battle against my own keyboard fumbles where I would cause a gamebreaking bug with a single missing quote somewhere, or sloppy indenting. Having never written in a language that actually cares how you indent your code (god bless javascript) it was a wild ride in trying not to fuck up.

However, you can kind of see the lineage of Videotome cropping up here with the single-letter character commands, as well as Super Videotome's image layer system.

RENJS

RenJS is a smaller engine by fellow Domino Club member Luna that was the engine I used last just before making Videotome. As a direct-to-web version of Ren'Py with different syntax it was fun to write in; doing nothing particularly fancy, the syntax is a little closer to my platonic ideal of "write words in a notepad doc that become a game", as displayed by this sample from paradigmfetish:


Gone is the requirement to wrap the text itself in start and end symbols, whether they're brackets or quotes or what. I think this is where my mental delineating of Videotome's "Commands, Delimiter, Text" format to each of its lines comes from, with the commands 1 says chair: No, that wasn't right.

meaning:

[character] [says the text] [with this sprite version]: No, that wasn't right.

But there's still friction here for me: the reliance on space-hyphen-space-commands-colon before even an unadorned line requiring a gamewide copy-paste before every new line of text. This became even more of a friction point with that's the worm for me, a fangame of another fellow domino fotocopiadora's against the will of the chainsaw. This reuses some custom code for RenJS that allows placing text boxes anywhere onscreen, with the engine code looking like this:


Looking back on this I can see some of the influence on code that would become Super Videotome's text handling, but it also represents another large amount of copy-pasting between the "just write the words" step and the point at which they're all lain out on screen where you want them. And again; an errant bracket, comma, symbol etc can crash the game. While I really liked the output of this, and it resembles Super Videotome's "text placed anywhere on an image" style, actually implementing it was a bit frustratingly slow.



INK

Ink is a special case here because it represents both a relative ideal for me while also an unsatisfying lack. Ink's syntax is very fast to write in, being reliant on a very lightweight syntax for doing commands. Below is an excerpt from A Day of Maintenance, which holds the personal record for the number of words I've written on a project (estimated at about 40-60k, with the game's total at 100k with the rest of the words from Elliot and Peter):


Clearly it can't have been that much of a friction experience for me to have managed to write that many words. And for the most part it wasn't! You can see here how some of the lines have very little in the way of non-text parts; the # tags at the end of each line are technically optional, and the syntax only requires special characters when it comes to identifying choices, branching, etc. I won't go into the specifics of Ink here because it has a slightly unique set of descriptions for its parts, but you can always read up here.

I do quite like Ink. But unfortunately it's a little hamstrung by being middleware; it's not really designed for use as a standalone engine, but rather designed to be plugged into Unity or another big boy engine. It does have very basic support for being standalone, and others have expanded on it to provide that, such as Elliot's Calico. A sample from Winter, a game Elliot & I did together that is currently the demo project for Calico, is below:

The non-text commands here are pretty sparse; there's the #frame: park_bg:3, park_fg:4 command to show a specific image, and the #play: act1park command to play music, with the rest of the sample being Ink's syntax for choices, knots and optional text.

It's still... unsatisfying, to me. A stumbling block I find with Ink is that you have to remember about 11 different special characters and what they do, what they do in combination (e.g. * vs **). In its credit, it's a bit less prone to game-breaking crashes with a single special character misplaced. I suspect this is because of its status as a middleware engine built into something more powerful like Unity, rather than a standalone, with famous examples of its use such as in Disco Elysium demanding a more robust error handling. This isn't to say you can't introduce gamebreaking bugs with errant characters; getting stuck in a loop or dead end is eminently possible. But often the integration layer, be it Unity or something else, can detect and escape these. 

(obviously unity is a WHOLE different bucket of fish here. no comment on that)

But I like Ink because it's usually pretty quick to write. It has a pleasingly low number of non-text keystrokes required per line, often zero, and it's pretty fast to read back. Good job. But sadly not quite what I want for a "easy to write one stop web game shop" engine, so, I started tinkering.


Videotome

So, with this analysis of a few engines out the way, let me turn back to Videotome.

The original idea was to literally turn my habit of writing a game in notepad into a reality, with an engine that could handle a simple list of lines and turn that into a game. It would somehow grab a literal .txt file and parse the lines into an array, spitting them out one line at a time as a kinetic novel. The first Videotome game was Hot Wet, with the first bunch of lines in the story file looking like this:



One of the main reasons I was able to get away with completely engine-code-free lines in the story script is because the game leant very heavily into a stripped down presentation. You cannot make choices; your interaction is limited to progressing through the game one line at a time, triggering music and images at certain times. I am aware that this simplicity of vision and execution is not something any of the other engines are directed at, which is why I'm able to do this and - broadly - they're not.

Where the code blocks are, they're using a sort of hybrid of Ren'Py and some of the others. The S! - command styles the line of dialogue in the way that I've set up the S character to look, in this case called Sophie - although the only different in the game presentation is the text alignment off to one side, and a colour tint. The other commands like BG_SOPH or MUS_DAY1 are directly calling image/audio files set up in an assets array, and switching them in to replace whatever previous one was present. Asides from a late-added CLEARSCREEN command to erase everything currently on screen, that's basically it!
In my mind, what I wanted to do with the syntax for these is to make them:

  1. Limited number of characters to input
  2. No really special characters (e.g. ¦ } ~) that feel unnatural to type
  3. Not visually overwhelm the important part of the line (the actual text)
  4. Not prone to crashing your game if one symbol is wrong
  5. Syntax that just feels like what I naturally use as shorthand already

I think this came out successfully! Point 4 is probably the one I'm least confident in, because the code isn't that robust under the hood - but a lot of the time, if a command block is mistyped, it will either silently fail or else be printed with the rest of the story text. Which I think isn't so bad compared to immediate error.


Videotome:ADV

With the first version out, I wanted to keep prodding at the engine and see what else I could do with it. I've had a soft spot for the aesthetics of 80s/90s japanese adventure games and early visual novels (see this bot for an example, or just google PC-98 games - particularly fond of the look of Jesus II) and wanted to bend Videotome into that shape. A weekend-long fey mood resulted in Videotome:ADV, shrinking the three-rows-of-text from Videotome and adding an image and choice section:



In terms of the expansion to the codebase, this didn't actually change that much. The base script is still the same, and you can still totally write a bunch of lines without a code block. Some changes to old functionality include character tags now appending a predefined name and colour before the text line, and wrapping it in quotes; plus the image command has smart behaviour and places the image in the background or over the top of it depending on the reference name. The script below looks roughly the same as Videotome's, if more complex:

The main differences are the story being broken up into chunks delimited by an identified as the first line (e.g Chapter2) and an end identifier that is unlikely to be one the writer would use elsewhere (###). This feels like a hybrid between a Twine passage and a Ren'Py label.

Plus, the new commands... adding the ability to branch based on player choice, being able to set and check variables... the CHECK command viscerally upset me at the time to write because of how far it strayed from the platonic ideal of a simple code. But with the syntax still being based on my own "wrote this in notepad" shorthand for Real Engine Commands, it didn't feel that bad to actually write on the fly, the command breaking down into "CHECK" "this variable" against the value "yes" with logical operator "equals" and go to "Chapter5" if tru and "Chapter6" if false. Writing these more involved commands was an interesting exercise in how I thought the user-facing logic should come acorss and flow, and like... translating my own description of how it SHOULD work, and my written example syntax, into a syntax that ACTUALLY worked was Fun.

When it came to the milestone of adding choices, I sat down and considered what I wanted out of this. Some internal dialogue about "why would anyone use this" and "what sets this engine out from every other VN/IF engine out there" resulted. I mostly dampened this down - the reason I was making this engine was basically self-gratification and the thrill of tinkering, rather than any desire for people to actually use it instead of another engine. But I'd been thinking about Ladykiller In A Bind off and on for a while, and how I really liked the non-blocking choices there - where you can keep going on the current conversation thread instead of having to choose a choice, with them timing out naturally after a few more bits of dialogue. This became my One (Sort of) Unique Feature, in that I didn't know of another engine specifically designed for this functionality instead of it being a developer-added feature. (if I am wrong here and one exists, please let me know! I wanna check it out). The underlying engine functionality of "continue through an array of lines of text one at a time" lent itself pretty well to the style of choice, and I neatly tied up my introspection about why I was making this engine in the first place.

To figure out the pain points in using the engine, I spent some time porting the first little bit of Superlunary across to it. Compare the two story scripts below:


To me, the second was much more satisfying to write in, and I didn't hit such a speed bump with the "turn words into functional script" phase. The painful part was getting a layout; I couldn't directly emulate Superlunary's table-based graphical layout, so ended up just converting the game into the shape I already had laid out.

After making the initial layout, I was playing some more visual novels and thinking about the way they can pivot between delineated text boxes to fullscreen images and back. So I added a MODE command that switches between some predefined setups:



Ultimately, this functionality wasn't satisfying to me, and I couldn't get enough control over the layout of anything with the existing barebones HTML elements canvas. I never finished a game using this engine, although some others did. So, for myself, I ended up making another engine to get greater visual control over stuff, lol. Pain point identified!


Super Videotome



Where Videotome was basically just three <div>s on a page, and Videotome:ADV was about 5 <div>s on a page, Super Videotome became a canvas based renderer instead, doing away with the html partitions of content (mostly - choices remained separate to be clickable) and offering free placement of text and unlimited images drawn at a time. The image & text commands had to be rewritten to accommodate this, while the where-in-the-story-am-I commands could be left basically as they were. Comparing the above image to the screenshots of Videotome:ADV's different modes, it doesn't look that far off.

Super Videotome now consists of multiple canvases stacked on top of each other, forming a background, paired foreground, and text layer stack. Images and arbitrary rectangles of colour can be drawn & cleared to any of these layers, and text is drawn to the text layer by default. Layers can be cleared and drawn mostly as desired, and a 2-frame animation can be done on the foreground layer, switching between two manually defined frames sort of like an expanded Bitsy.

In theory, the story can be written in much the same way as original flavour Videotome - just a list of lines in a text document. In practice, doing anything fun with the engine requires code blocks on a lot of lines, as seen in my first game/proper roadtest of it, Victim Doll:

While manually positioning lines of text if you want to see more than one on screen at a time requires some pretty tedious commands, I am pleased that you CAN get away with writing a lot of lines with no command syntax whatsoever. In what I think of as "standard VN" mode, a plain text line with no commands will just clear the text layer and write a new line of dialogue at the bottom of the screen. I actually ended up doing this a lot for longer narration scenes, where I didn't want to play with position or multiple lines on screen at once; and the script itself was written with only character commands as the first pass, with a second pass through to add images, sounds, effects etc.

On the other hand... the commands necessary for arbitrary image and text positioning became much less straightfoward. The original, simple image command - literally just calling the image by the reference set up for its filepath in the assets list, and it being automatically placed based on its name - becomes IMAGE:imagename:layername:x:y, and the command to do non-standard text (where standard text requires no command) being TEXT:[colour]:x:y:z. The most gnarly command, the ability to draw a rectangle of arbitrary size and colour (mostly used by me for blocking out areas of the background image to draw text over) being RECT:layername:[colour]:x:y:sizex:sizey... with all three of these more complex commands required for a screen like the below:



Closing Thoughts

There feels like a clear tradeoff between ease of writing the game at speed and without friction, and the scope of its feature set and variance. In making Super Videotome, and having more ideas for it - e.g more complex animations than 2-frame ones - I can feel myself wandering away from the original pitch. It almost tempts me to do the reverse of standard engine development and start making less features, actively removing ones I don't like.

It makes me think about the false idea that permanent growth is a natural feature of the world, and not one invented by capitalism; about the trend for games engines tend to always add more and more features until full of things 90% of users will never touch; until the appealing core pitch and direction of a small boutique engine loses its charm and is squashed by the complexity the rest of it allows. I think about my own tendency to describe Videotome in an apologetic way, as "small" and "simple" and "just a web IF engine"; I think I am in the process of reevaluating that description as not a caveat but a feature in its own right. 

I wonder if it is possible, in the moment, to know when a naturally growing engine is "done"; whether you can detect some kind of crystallisation or solidification, or a point where adding new features becomes less straightforward and more of a faff that makes you go okay, I'm done here. I think about the concept of a sculptor not creating a sculpture from scratch, but rather freeing one that already exists within the stone; is there a platonic form of every game engine every started, at which point it is finished?

It feels a little grandiose to say the Videotome family has reached its platonic, perfect form; there are quality-of-life tweaks that I want to roll out to all three engines in the family, and I can see the murky shape of a foruth engine somewhere in the water. But I am trying to think back to my original purpose for making them - to make an engine that reflects how I naturally want to write a game script, in one long raw block of text and just have everything magically handled. This ideal script - or the syntax that I write out of the ether, my ideal markup that I based the code around rather than a markup based on how the code had to work - exists in dialogue with what I can actually accomplish. The choice tag gaining square brackets around the choice text being a compromise because without it I couldn't get the regex to pick it up; or the fact that you can't write " - " (space hyphen space) in any videotome engine game's actual text or it breaks. Parts of the syntax and engine still exist in conflict with each other, letting the developer sort of peer through the matrix and see how it works behind the scenes.

You could plot a lot of the engine syntaxes I've listed here on a line between abstracted (Ink) to basically just html (Twine), with a separate axis that tracks the percentage of your story script that makes it through to the player versus the amount eaten and obfuscated by the engine. Rather than come to the thought that I've come up with The Perfect Easy Syntax, writing these engines has been a fascinating practical lesson in how the engine syntax lives in conversation with the feature scope. This may sound sort of obvious - of course it does - but I don't really think I appreciated it before.

Where do I go from here? I'm rolling a bigger animation system around in my head, at least. Whether that's for Super Videotome or some fourth engine (Ultra Videotome? lol) I don't know.

Game Examples

I want to end with some examples of games others have made in the Videotome family. For me this is the most satisfying part of this whole process - not only have I made an engine that caters to my own whims and fancies for how to write it, other people find the same package and syntax at least frustration-free enough to use themselves! So below is a small list from the collection I keep - if you make one of your own, let me know :)

Videotome

Our Lovely Ladyverse by Digital Poppy 
perverseoverride by coleo_kin as Wanda Ballard

Videotome:ADV

Dyar Beach by MULTIPLICATION BITCH & Ogilvy, for Domino Club
Quinn & Flynn by Stanwixbuster

Super Videotome

Greaser by nat_content, for Domino Club
(as featured in rockpapershotgun recently 😃)

Support this post

Did you like this post? Tell us

Leave a comment

Log in with your itch.io account to leave a comment.

Interesting writeup! I wonder if you have ever used Kirikiri? It’s Japan’s legendary VN engine and has long been discontinued but new works are still being made with that engine. It solves the tedium of copy-pasting common syntax with a powerful macro system. A fork called KirikiriZ exists on GitHub.

I wasn't aware of it by name, but looking it up there's a lot of games I'm familiar with using it. Thanks for the pointer, I'll have a look at the fork.

Thank you for this writeup! I have been on mobile without a computer for a few years now (the recording i attached to greaser was during my trip across the country). So some domino club things are accessible and others are just what i can read in a gane’s comments or video. Oh, things!

you can keep going on the current conversation thread instead of having to choose a choice, with them timing out naturally after a few more bits of dialogue. This became my One (Sort of) Unique Feature, in that I didn’t know of another engine specifically designed for this functionality instead of it being a developer-added feature. (if I am wrong here and one exists, please let me know! I wanna check it out).

It’s an in-house engine for campo santo of Firewatch, BUT Magpie has a context-dependant timeout feature. I think there’s a global location trigger for dialogue progression and then a bunch of if clauses for what to populate at trigger, with ranked filing and some sort of deckbuilding feature (“If Alice knows about the time with the cat, then Alice knows about the cat” –> “$Alice: Got any more cat stories? $You: (a) Nope. (b) Not any to get into. (c) Sure, what kind of story are you looking for? $You_asAlice: (a) Let’s hear something funny. (b) Was the cat ever the comforting type? $You: They were more the type seeking comfort, but there was this one time…).

How to manage the complexity and data flows of conversations when…Osbourne…? The player can interrupt at any time. William and Patrick will discuss the logic, tools, and workflow behind the dialog system used on ‘Firewatch’. From its beginnings as an interrupt heavy bark system, to the long, restarting, conversations they shipped, they will go over what worked and what didn’t as they built the system and the game around each other. They will discuss what a data driven system needs to be able to handle as it grows in complexity and scale, and how to keep your tools running well without a team dedicated to them. — https://www.gdcvault.com/play/1024415/Do-You-Copy-Dialog-System

also this article came to mind, for some reason? so theres that.

Really gratifying to read, I've run into a lot of the same frustrations you listed here. I've only ever thought of making custom engines for action games or rpgs, thanks for getting my gears turning about text games too!

(+1)

I so frustrated myself trying to twist twine into completely different shapes than intended that I lost all enthusiasm for the engine, and haven't touched game-making in months. Your Videotomes ( and this write-up ) are the only reason I cracked open my game files today, and considered picking up the habit again.

(+1)

Great piece. I've been a fan of your works & this puts all these engines into perspective.

I've been eyeing Videotome precisely because of its simplicity. I will have to give it or one of the other iterations a try when I have some time.

(+2)

Brilliant write-up, I honestly find it pretty inspiring that you just... made your own engine rather than try to bend an existing engine to one's will.

One particular bit I connect with is "But I am trying to think back to my original purpose for making them - to make an engine that reflects how I naturally want to write a game script, in one long raw block of text and just have everything magically handled." / "But I am trying to think back to my original purpose for making them - to make an engine that reflects how I naturally want to write a game script, in one long raw block of text and just have everything magically handled."

It's like every project is an idea you start with, but the actual act of making it is how you find out what it really is. It's very easy to deviate from your initial "story pillars" or whatever; although a lot of times I kinda feel like that deviation is just as fun to look back on.

(I mean we're talking a software here, so there is a point where your code gets spaghetti-fied that you really do need those pillars, but whatever, Art Art Art cool)

Thanks for writing this

(+2)

I found that the simplicity of videotome’s interface was a real ease just like you mention, to write text off head, in notepad, like I usually write, and then just add minimum formatting and the simplicity can be very powerful to convey a strong message.
anyway thank you for making thos tool 🙂 i made a game Decalogue of Binary Division with it last spring and it was a perfect tool for it

https://axoona.itch.io/decalogue-of-binary-division

Thanks for your comments and sharing another game made with Videotome, I'm glad you found it a good tool to use :)

Mentioned in this post

a minimal linear narrative engine
Run in browser
a little engine for little games, worlds, and stories
Run in browser
an illustrated bitsy horror novel
Play in browser
happy holigays
Interactive Fiction
Play in browser
Campfire comedy-horror storytelling
Visual Novel
ditherpunk VN sex monologue on the moon
Interactive Fiction
Play in browser
chainsaw fangame
Interactive Fiction
Play in browser
a web engine for interactive fiction
you have to face your fears, don't you?
Interactive Fiction
Play in browser
Interactive Fiction
Play in browser
micro ADV engine
Run in browser
(18+) lesbian romance, comedy, and kinky sex
Visual Novel
micro narrative engine
Run in browser
everything painful is right
Interactive Fiction
Play in browser
A lonely lesbian misses her wife very much.
Interactive Fiction
Play in browser
Interactive Fiction
Play in browser
an account of the disaster
Visual Novel
Play in browser
Catch a criminal; pursue a poet
Visual Novel
Play in browser
fucked up girls on fucked up bikes
Interactive Fiction
Play in browser