At the end of 2022 I wrote a long essay on my thoughts and motivations behind developing the Videotome family of homebrew IF engines. A major theme of this essay was on designing for low-friction and hassle free writing, allowing myself (and others) to write game scripts in majority single-file plaintext, using a custom syntax designed from the ground up as one that I found natural and enjoyable to write in.
Since then, I have released one further member of the family, Videotome Heartbreak (a storylets powered stat raising dating sim engine), as well as released three games that use either a Videotome or a modified version of the codebase in some form:
On a little introspection, these projects all deviate to some extent from my original stated goals in writing an engine "to literally turn my habit of writing a game in notepad into a reality"; both in game content and engine content, the level of complexity has slipped away from this original statement and become something more closely remembling the sort of clunky setup requirements that I've previously been frustrated with elsewhere. They've also all been modified versions of the base engine, instead of using the engine as it comes; on reflection this suggests to me that I'm not as satisfied with the base state of the engines as I could be.
Outside of my own direct experiences, Videotome has met with an enthusiastic if limited response. The first (to my knowledge) commercial project on steam that uses it, a growing collection of friends and strangers using it, and the occasional mention in roundups of cool indie game engines. Regardless of my own satisfaction with the engines, that others find them fun is reward enough, so I could stop this essay here if it was purely a "what's happened?" essay.
So what's the deal? Why am I not happy (okay, that's too personal - why am I not happy with Videotome? Better...)? Let's dive in to work so far.
A preemptive contextual note: I have not actually studied game design, when it comes to theories, terminologies, established ways of thinking. I've picked up a bit of academic thought over the years of making games, but there's gaps in my theoretical knowledge or terminology. I invent some new theories and terms throughout this essay that I don't personally know to already exist - if they do, then please accept my reinvented wheel.
Traumakt~4.sexe is a game I made together with Jazz for Domino Club 5: Dream Gallery, that uses RPGMaker, Jupiter Engine, Super Videotome, Gatewalk, Tape Window, PCJ, and some custom javascript, as well as having prerendered images made in Unreal. This was kind of wild to work on, but I'm only going to talk about Videotome here.
The first use of Super Videotome here is deployed in an iframe, sending the contents of each message to the parent window and exchanging some variables. It's pretty straightforward and the closest to vanilla I've used it in this essay. The second use is for four ending scenes using it, which use a variety of embedded video and shader effects to a cool presentation. For one of them Jazz did some cool code to have this music visualizer / screensaver effect in the background, which I haven't the foggiest about how it works, but it's still drawing to the canvas either way. Other than the video - it's pretty straightforward.
What stands out here is that Videotome was not "enough" for this project; no one engine was, but several of them were nice and lightweight to be called from the main game and layered on top. Sending messages back and forth between the windows kept variables synced and allowed a text log persistent between all engines (Jazz takes credit for all this, not me), and made it feel cohesive.
I didn't feel restricted by the use of Super Videotome in this project because, for anything I couldn't do with it, we were just using a different engine in the first place - or we picked other engines for their aesthetic qualities. In summary - not super involved use of Videotome itself. Cool though.
The main framing engine we used for Traumakt~4.sexe was RPGMaker MV. This was the first time I'd used it, but by the end I could see how it would be a fun engine to use in a more involved way.
For Domino Club 6: Humors and Humus, Jazz & I collaborated again and made World Pole Gaiden RISE: Mark of the Deck 2: Sanguine & Melancholia, a deckbuilder cardbattle RPG. This was the first time that I really got to grips with the event scripting system in RPGMaker, and... it's kinda neat!
It IS very fiddly to do long scenes, but it's quite accessible - once you figure out some idiosyncracies - and has a lot of powerful functionality. However, it's totally opposite to the way I usually work; I have to use the editor, and can't write in a plaintext file. Boo.
What I ended up doing was writing some of the scenes in plaintext, then pasting it in, adding all the event scripting, fixing line breaks where I wanted them to break, then finishing off any other dialogue I'd missed. Although this wasn't my favourite workflow, I got very used to it by the end, and I had a lot of fun making this.
In hindsight, maybe this is the start of me chasing a more "condition based dialogue chunks" setup; RPGMaker events each have a set of conditions you can set for them to run, and they have a hierarchy system where a higher number event page will run instead of a lower one if both are true. These features, or approximations, made it into Videotome Heartbreak (more on that later).
Heaven's Cybernetic (De)Athlete: Zeug is a retro doomlike shooter slash lofi visual novel, made together with Jazz again (I like working with Jazz😊) for Domino Club 7: Bodies in Motion. It is primarily built in Gatewalk, a successor engine to the one Jazz & friends made for Gatewar. Jazz & I updated the functionality over the course of making Zeug, and it was my first time actively working on a game engine other than my own.
Zeug is also... quite a bit more complex than Videotome. It's a 3d engine featuring movement, jumping, shooting, with a level editor built in for making sector geometry a la Doom. When we started working on Zeug, Gatewalk had a dialogue system built into the engine already, but because we anticipated making longer sections of dialogue than would be practical in it, I ported Videotome into it.
However, I left some of the initial structure present; each chunk of dialogue in Zeug is an Object that contains its ID, some hooks for function calls before/after, and a link to the chapter of Videotome dialogue we wanted to display. These Objects were then called by parts of the game (NPCs you interact with, trigger volumes you step into, dying, etc), and it would spin up the appropriate dialogue. Originally, the dialogue was contained inside this object so that the entire thing existed in one place, as a string to be printed; this was replaced with a string reference to a Videotome Chapter instead.
This approach directly inspired me in creating Videotome Heartbreak (see later), because it made sense; here is your "cutscene" or "story event", it refers to a section of script as long or short as you want, and it can have other variables or actions attached to it. The story dialogue itself can be long and rambling, but it has the same fairly concise Object entry as another part. And placeholders can be set up easily and then filled in later.
After some starting hurdles, getting this working in a satisfying way went well. But Zeug is a doomlike FPS game; the dialogue made up at most only 50% of the appeal, likely less. I certainly spent more time making levels and engine code than I did writing the story, and as such, this only partially counts as a "Videotome Game".
However, it was a fun experiment in porting my own dialogue codebase into another engine, and started me thinking about the syntax and text delivery code as somewhat modular, easy to lift and convert to other contexts than a linear visual novel. Which leads directly on to the next engine:
Videotome Heartbreak is my newest engine in the Videotome family, and the motivation for this essay. It's a stat-raising dating sim, using a storylets structure for dishing up chapters of story based on story conditions, day of the month, etc. It also features a customisable calendar system I made from scratch that I'm quite proud of, maybe disproportionately.
The engine is based on a few different things; I played a lot of flash dating sims on newgrounds as a teen (for long time freya essay readers, this has come up before), and found their stripped down and stolen-art presentation engaging, while also being kind of embarassed at the thought of being found playing them. Second, while looking up dating sims more recently, I watched an engaging but offputtingly long Action Button video on Tokimeki Memorial, which is where the engine nicks its name from. Lastly... I thought it would be funny to take my VN engine and make a dating sim engine with it, mixing the two often-conflated genres together.
Previous Videotomes are very straightforward; there's only one sort of "game state", being midway through the story, progressing through a chapter or diverting via a choice. Heartbreak adds multiple different "states" in with differing options - menus, different story categories available, viewing your stats etc. I got some practice with a more game-state driven approach via assisting on Zeug and World Pole, both of which have a much more complex codebase. Compared to them, Heartbreak is pretty simple.
A lot of dating sims get pretty complex, with minigames, multiple different activity modes, lots of variables to track, and lots of fancy presentation. I don't do that here; all the Videotomes to date are intentionally stripped down engines, made with only what I think is necessary &/or can be bothered to code. I'm not a perfectionist (I think it shows) so getting something in the right shape as the engine style I was after is good enough.
Unlike the previous engines, Heartbreak is not a linear story; as part of its design it needed to be able to play back discrete chunks of story based on whatever conditions were available, instead of just progressing on to the next one in a series. To me this meant making a Storylets structure instead; I'm not going to define that here more than "a storylet is a bit of story with some conditions for it to be shown" but Emily Short has some good writing on it on her blog. A lot of games use storylets or something in that design space; what I don't know, though, is how a lot of game engines actually handle writing them.
In Videotome Heartbreak, each storylet is a "Card", as defined by the game maker while making the game. This is handled by Decks of individual Cards, each of which has playback conditions, a videotome chapter string, and optional other settings for making it infinitely playable or a one-off event, giving custom code after it finishes, etc:
I picked this format because it was close to what we had in Zeug and so it was familiar. It immediately turned out to be a bit of a pain, because writing a save/load function (finally deemed necessary due to the implicit longer length of games with this engine) that worked with Object Keys having a Function as their Value was a faff. It gets stringified then un-stringified via Eval() on load, I'm not happy with it.
While, generally, Heartbreak is an increase in scripting and setup complexity across the board, there's a few exceptions. I've tried to reintroduce some easy shorthand commands for doing stuff, like a BG command that draws to a predefined location instead of needing image coordinates; and a character sprite system that on first run only needs character and variant, then on future dialogue from the same character, automatically redraws their current expression. It's even got automated blinking, as a sort of bourgeois bonus affordance.
Despite the shorthands, though, VH is ultimately a large increase in the number of different files needing edits in different styles. Making just a small demo game - the Miku one, as traditional, that's bundled with it and playable online (thanks Toffee for the character art!) wasn't a full shakedown trip in terms of really wrangling with how much work it would be to use the engine, so I feel like I released it without a handle on that (a trait of even numbered videotomes, as ADV had the same thing).
Fortunately, I then went on to make a game in Videotome Heartbreak that tested the engine as released ignored the existing constraints.
I've had the idea of a video-centric game in rotation for a while, partly riffing on the "Video" part of the engine name and partly because it's Cool. In my day job I spend a solid 50% of my time making AAA game cinematics and the other half fighting fires, and have done them in limited amounts outside of work too (Traumakt~4.sexe had a few simple ones). A three hour childhood memory of playing The Daedalus Encounter at my uncle's house somewhat enamoured me to FMV games (although I gotta say, my memory of that game is better than the reality), and I've been meaning to play Immortality while building up an inaccurate impression of what it actually is.
Neurokino Retrograde is my latest release and the scratch of that particular video itch. Made with Cecile for Domino Club 8: Tongues (god, has it been EIGHT of them??), it's a short-ish visual novel where you use an interface of unfamliar glyphs to try to communicate with a dying post-first-contact woman. In return you get little snippets of video playback, and try to make sense of them that way.
The storylets format of VH worked pretty well for this; each combination of glyphs you provide could have a card assigned to it, which would show you the appropriate video and log some variables for tracking your progression. Other than that, though, the time-, activity-, and stat-raising features of Videotome Heartbreak were pretty much abandoned for this project - as was the entire rendering setup.
For this game, as Cecile was handling the visual design and is much more familiar & comfortable than me at using CSS, I switched the engine to use that instead of the canvases I've been using so far. Everything in Neurokino is now drawing to divs and other basic elements, with a lot more pretty UI setup for them. It also meant that adding video in was pretty straightforward - just switch which type of element I'm using - and could use all the same CSS for prettyfying it up. The text boxes being HTML too means I could write markup like italic tags straight into the story script, which was pretty nice to realise.
But... hang on. I just made this engine. Why am I tearing it up immediately? What does that say about the finality or suitability of the new engine for me to do and make what I want to with it?
Well... actually using Videotome Heartbreak as is was kind of a pain in the ass. Even ignoring the visual layout overhaul, this was my first time really going ham on lots of story cards and scripting that, and it was... really tedious. Look at this.
Not to take away from how I feel about the game itself - I'm very happy with how Neurokino turned out - but towards the end of doing the cards and story setup for it, I was really thinking... there has to be a better way of formatting this. From a developer point of view, scripting these cards meant logging each video in the assets loader, making its videotome story chapter, and making its Card with appropriate conditions. I'm sure there's a bunch of simplifications I could have made - the above screenshot you can see some triplicate mention fo each video identifier I could have cut down in a smart way - but it more had me thinking about the storylets setup itself. Assigning conditions and events to each chunk of story... the fiddliness of it being js Objects in a different file to the story itself... is there a better way? It felt like I was doing so much extra scripting compared to before, for relatively little extra features; it's basically glorified chapter branching, if you strip away all the extra context. It just seemed so... inefficient and inelegant.
The closing section of my 2022 essay discusses "a clear tradeoff between ease of writing the game at speed and without friction, and the scope of its feature set and variance", and at the time I was conscious about already wandering away from the original pitch. I describe - though do not give a name - a concept I've been rotating in my mind for a while, on the percentage or ratio of your story script that the audience directly sees, versus the amount eaten and obfuscated by the engine. I don't know a term for this, so I'm calling it the Story/Code Ratio, or the Functional Ratio.
A book has an incredibly high Functional Ratio, very nearly ∞:1. High is good here. It's not quite that, because the title, blurb, author name, and legal disclaimers would fall under "Code" here, but it's close enough to ∞:1 to be basically perfect.
A game is not a book; even the simplest text only game has a supporting stack of code in the background running it. But for some game engines, the amount of this supporting Code that the developer has to write themselves is lower than others.
My idea behind the engine was noble, I think, and this sort of system of defining an ID, a Story, and Conditions is a basic and fundamental requirement for Storylets; I can't do without it if I want to have that functionality. But the process of actually making a game that used my own engine work here ("autofellatio" seems the appropriate term, or for less polite company, "dogfooding") felt clunky, full of administrative fiddling that wasn't and isn't what I find fun about making games.
Maybe there's no way around that, though.
The term "musical temperament" refers to a system of musical tuning that introduces some imperfections to make it a more flexible tuning system overall. In the western music canon "Equal Temperament" is the dominant one, in which most different intervals between notes are slightly wrong but all equal, to make everything easier. This is a gross oversimplification, but I wrote my university thesis on this back in 2013, and a conceptual part of this has stuck with me ever since.
(Bear with me here.)
To get into the weeds a bit - intervals between notes roughly match to differences in frequency that are nice whole number ratios like 3:2 and 5:4, and we establish our 12 tone scale by the "circle of fifths", where going up five notes from a starting frequency each time has a ratio of 3:2 between the two frequencies and eventually forms a circle: C, G, D, A, E, B, F♯/G♭, C♯/D♭, G♯/A♭, D♯/E♭, A♯/B♭, F, and C, where C-to-C has a 7 to 1 ratio between the end and start C, ending up seven octaves higher. All of these frequencies are then normalised down to form a range between our starting C and 2xC, giving us the 12 notes of the western musical scale.
Problem is... it's not seven octaves, it's very slightly over. The amount by which it's over is the Pythagorean Comma, a tiny and horrible ratio of 531441⁄524288, about a quarter semitone. This is the sum total imperfection that must be present somewhere in the tuning system.
Some classical tuning systems place this entirely in one imperfect interval - between G# to Eb, say - that becomes unpleasant to the ear, howlingly out of tune: the Wolf Fifth. As this prevents ever playing that interval in a piece of music, lest it sound bad, sometimes it is moved around, and you might tune it to a different, unused interval instead, still leaving you with 11 perfect intervals and 1 wolf. In other tuning systems, this dissonance is split up and shared in smaller, more agreeable pieces among the notes, so you are left with between 2-12 more or less tolerably imperfect intervals. Equal Temperament, by making every interval identical in step to its previous one (an increment of12√2:1 each note) does this; everything suffers slightly so that nothing suffers greater.
Why am I talking about this? Because I think the development of a game, using an engine, involves the distribution of a necessary evil somewhere in the process. Maybe it's entirely on the engine devs' side, and the game dev has the most perfect time while the engine dev suffers. Myabe it's shared, and the game dev must put up with a bit of friction during development, a clunky workflow or a bit of repeated syntax to type each time. Maybe they have to wrap all text in quote marks for it to work right, etc.
You see where I'm going with this - to have a functional game engine, for me to design a functional game engine, I've got to accept part of it is going to be annoying to use; or for me to pick another engine to use for my work instead of homebrewing one, it's going to have a part that I find clunky, or a workflow I wish was different. I can do the work to shift this into a part of the engine where it is least noticeable, to hide it in a place rarely seen, or share it between several parts to be all equally, if slightly less, frustrating. I call this:
In Videotome Heartbreak, I consider the Cards system to be a Wolf Feature, despite it being the main technical advancement of the engine: it's just fiddly to make a new, perfectly formatted object each time, compared to the elegance of writing a linear script. Giving the card a name and giving the story chunk a name is inelegant; having the conditions for a story chunk be javascript arguments instead of a more abstracted user frield check; being unable to share some variables between the SET/CHECK commands and the cards (an oversight I'm fixing during Videotome Jam for my partner)... the list continues. It's an annoying workflow, but perhaps necessary.
In Super Videotome, due to my friend Stan's flexing improvements of my engines, the TEXT tag has been highlighted as a wolf feature and somewhat domesticated into simpler if more balkanised commands. The image commands, while similarly clunky, were sort of aesthetically appealing to me by specifying specific locations and sizes of what you want to draw; but for other users, perhaps they're similarly lupine features.
What about other engines? Well, Twine's chunking necessitating writing in-engine (unless you use Tweego or similar, which had its own foibles) was a wolf feature for me, the tedium of splitting up my notepad scripts into individual passages being an inspiration for original flavour Videotome in the first place. Bitsy's dialogue system was very much a wolf feature when trying to do more fiddly work, and Ren'Py - well, you have to use python, so, woof.
But from my longwinded circumnavigations to this point, I think it is fundamentally impossible to guarantee an engine without some friction-inducing feature, especially the higher up the complexity level you go. Every day I go to work and use Unreal I am fighting a dozen wolfs and then some, which I begrudingly accept as the conditions of making a game in UE5. This makes me feel a little better about my little homebrew engines being clunky or having annoying workflows; but I don't think it excuses them entirely. I think some of them are just... kind of annoying.
As I write this sentence, we're a little over 48 hours 72 hours 96 hours into the first Videotome Jam I've run, for using any of the engines; it's had a little more traction than I initially expected, and has been a fantastic source of bug reports (oops, lol). What's been interesting is the difference in requests for help between fellow engine hackers, and relatively javascript-averse devs without the enthusiasm to fix bugs themselves. I don't offer unlimited tech support, but usually help my partners and friends when they have problems with the engines. But as the audience using it starts to grow even slightly, beyond direct friends to encompass more distantly familiar names, and to total strangers, it's making me wonder...
Well, it's for me, obviously.
Okay, that's not that helpful in the context of this essay. Yes, it's for me, but I'm also a slut for positive feedback from my fellow indie dev peers, which is why I released the engines instead of sitting on them like a dragon guarding a hoard. More broadly - who is Videotome for, that isn't me?
Videotome belongs to a broader family of "Domino Engines", referring to ones made by members of Domino Club either during the course of domino game creation or prior (as our friendships largely predate the formation of the club as a formal entity). It counts itself alongside fellow engines such as Bipsi, Gatewalk, Jupiter Engine, Spectacles, Tape Window, RenJS, and others. Several members are programmers by trade, and many others are seasoned game and/or software devs with skills in futzing around with custom javascript (referred to as "gay JS", if it does not fall under an established engine category). We regularly share engines with each other, using each others' engines for jams, swapping between them to play. This means that Videotome's userbase has to date been a majority of fellow "makes a lot of small web games and is confident with the fast and sometimes hacky workflow that requires" makers, many of which are a lot better at the technical aspects of game dev than I am. This means that, on the whole, I don't have to offer a lot of technical support - my friends simply fix or edit my engine jank for their own purpses - and that feature requests are either solicited by me, or else absent; Videotome is mostly a fey mood production rather than a user tested or perfectly planned software.
I like this context; it lets me play fairly fast and loose with the engines, make what I want, and have the artifacts of my own bursts of inspiration. But I release my works publicly, beyond just my friends to be received by the indie-game-playing masses. Videotome has slowly picked up a little audience, balanced between other fellow web game hackers and a few devs for whom the stripped down simplicity appeals. This is nice! I like attention! I think it's good! But.
A wide public reach is mostly fine for me, when I'm releasing games that request little else from their audience but to be played. For some even this is not enough, whether they be right wing reactionaries, mindless fools, or just haters; but I need not offer support for games past their release. I am a small enough dev, and mostly uncommercial, so I don't have to worry about "customer support" or "bug fixes" or "the endless cycle of updates that modern videogame release paradigms demand". Fire and forget and move on to the next fey mood.
Engines... aren't like that. While I have a "I have a job please do not ask for support" disclaimer on my engine pages, this is mostly like the warning signs on an otherwise harmless bug; I do provide some support if stuff is genuinely broken, because I try to be a nice person and I have, regardless of my original intentions, put these engines out into the world to be used. "Support" here comes in several forms: clarification if people are confused by the poor documentation, fixes for unexpected problems I hadn't anticipated, or confusion or frustration at a degree of idiosyncratic workflow.
If I was actually making Videotome as A Product, then the answer to the question "who is it for?" would be obvious: it's for the users. I would be conducting research, fielding requests, identifying a gap or demand in the market to fill, etc. The answers of how to develop and pivot the engines would be evident from this approach, and I could let go of the reigns to let it go where it may. For engines that aspire to professionalism, or perfection, this is a valid course; Twine or Ren'Py are long standing and highly respected engines that continue to be polished and iterated on, and others such as Ink are the internal tools of a Real Company released for public use afterwards. But Videotome is not A Product, nor is it used by a Real Company, and I am loathe to let gamedev professionalisation bleed out from my day job into my hobby development any more than it already has. Videotome, then, is for a twin audience: indie gamedevs willing to use and fix janky homebrew tools and not complain about it too much; and for me.
And if it's for me... I'm not that happy with it.
Over four iterations, Videotome has grown from a Very Simple Basic Engine to a Slightly Less Simple Engine With More Features. It has done this because I thought it would be fun to make a more complex engine that does other things. And it was fun! I found it really enjoyable to make Videotome Heartbreak, to learn more javascript myself and to make something a lot more complex than before.
But, I think, I don't enjoy using it - and that was the reason I made Videotome in the first place. To quote my original essay on the first three engines:
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 ... 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.
Well. I don't think it is hassle free anymore, and I don't enjoy the user experience as much; by those standards it's been a fun project, but one that's ultimately betrayed its own principles. I don't think it's BAD - I finished one real game and one demo game with it, after all, and friends are already gleefully tearing it to bits to reform into their own shape of a game - but it's lost its way.
I think that's okay. The best way to learn what you like or how to do something is to not quite hit either of them, after all; and the process of introspection on how I feel about the engines thus far has made clear to me where many of my frustrations are, while giving me a better language for identifying them. How I go about addressing these feelings, whether that involves a refactor of Videotome Heartbreak or drawing a line in the sand and moving on to a fifth engine, I'm not sure. I've always kind of wanted to make a roguelike engine, but that sounds like immediately breaking my "make it simple" principles again, so who knows. I'd like to try to formulate another new "this is a very basic engine that does X" project, and try to reascertain my principles in making it; or perhaps I will just go hog wild and have fun making a piece of shit, who knows.
That's what's been most important to me through this whole thing, at least, and something I've not strayed from. It's been fun. Now... I'm done writing this essay. Fuck off and play some Videotome games xoxo
Did you like this post? Tell us
Leave a comment
Log in with your itch.io account to leave a comment.
it's been really cool, watching it grow and evolve!
also love the terminology you use in this essay, it's really on point!!
This is a huge feat. Thanks for sharing the process and building such a creative piece of software for others to create with
this is insane that i came here to read about a vg engine and got engrossed in some bit about music theory, sections 7 and 8 go together like ketchup and fries