Succubus Stories Mod Support: How It Works (Patreon)
Content
So what is in those mod files you select? What happens when you load them? How is content added to the game? All these questions and more will be answered in this post, where I will reveal to you much more than you ever wanted to know about mod support in Succubus Stories.
Adding Mods
Let's start with the basics. You open the game, head to the mod menu, and add a mod file. The game shows you a file explorer and asks you to select a file. What actually happens when you select a file?
What the game really wants from you is actually a file path. The path to the file you select is saved in the game's data for later, the mod is not loaded yet. Some basic checks are done here however. The game will check the basic structure of the mod file to determine if it can be loaded, though the actual data is not read.
All that happens here is a check to confirm the file is at least basically what the game expects and the file path is stored in the game's configuration data. The real action happens when the game is loaded, and this is why you are forced to restart the game after adding or removing mod files.
But before we discuss that, what's in these files anyway?
The SBC Files
SubC stands for SubtleCube and is the name of the custom game engine (and now tool set) used to make and run Succubus Stories. If you're curious about the name, Twine comes with multiple engines, and one of them is called SugarCube. SubtleCube is a fork of SugarCube with a view toward data compression for faster than normal play on the web, hence the "subtle" moniker. Subtle as in precise and narrow and small, but also hard to understand, as SubC games are not compatible with any standard Twine tooling. I internally call the engine SubC in the code and in other places, and the .sbc file extension is basically just a further shortening of that.
So what's in a .sbc file? Twine games use data that is in a custom HTML-style format. SubC files are this custom HTML, but compressed. The compressed strings are then wrapped in a JavaScript function made accessible to mods. The actual file data is just a single JavaScript function which is given the entire mod in the form of a compressed string as an argument. The concept is similar to how JSONP works in practice, wrapping data in a JavaScript function call.
If you aren't aware, Twine games are made up of nodes called "passages" which have names, tags, and source code. Each of these passages is a single screen or a single chunk of scripting. Normally Twine games can also accept some other types of data, but Succubus Stories mods are only passages, and all data is written in the form of passages. The compressed HTML data is essentially a series of custom HTML elements representing these passages.
Loading Mods
When the game starts up, after the engine and all normal game data is loaded, the mod file paths collected via the mod management menu are processed. Each file is loaded and executed as JavaScript code by the engine, which decompresses the mod's data back into the HTML passages mentioned above. These passages are then processed by the game engine.
Certain specially named passages have their contents parsed as JSON, a data format with native JavaScript support. This JSON can then be added to the already existing engine data. So for example, the data in the passage called _actions.areas.backstreets will be processed and added to the list of options presented in the backstreets area of the game.
The rest of the passages are treated as normal game passages and simply added to the game like any other passages would be. Again, these passages can represent a game screen the player will see, like a bit of story content or an area, or they can encapsulate arbitrary scripting, being used almost like functions or subroutines.
If there are conflicts in the mod data, for example the mod attempts to define a passage that already exists in the game, the game engine will generally throw an error, but try to continue loading the non-offending passages. This behavior may change as being able to replace default game passages could make for covert interesting mods, but at the risk of making the game much more fragile and making mod conflicts a real possibility.
Mod Tools When?
Since the basic structure of a mod is very similar to that of a Twine game, mod tools will probably leverage a lot of what already exists out there in terms of making said games.
The first step will be converting my current tooling into something more user-friendly, and releasing that as a command-line application. It will take Twee files (text files in a format used by Twine) and convert them into .sbc files.
The second step will hopefully be a completely custom Twine plugin that creates the .sbc files right from the normal Twine 2 program. This one will be more work, but will hopefully make modding more accessible to non-programmers.
As far as testing mods, since mod files are loaded on game start-up every time, you can actually compile the mod and then restart the game to quickly test changes. The in-game console, currently only available to patrons with cheat mode turned on, could also be a useful testing tool, and will probably have to come to the free edition alongside mod support for this reason. I actually think the state of testing mods is quite good, in the sense that it's rather easy to do and doesn't take much time to update a build and quickly test different code in problem areas.
I initially believed that I would need to create like an editor within the game or as a separate app that loaded the game's engine to make this easy to do, but the experience of making Convent has proven incredibly smooth even without these extra features, and I now believe they would be a waste of time better spent improving other things instead, like the in-game console.
Modding Documentation
I mentioned above that SubC is a fork of SugarCube, and that may lead you to believe that if you're familiar with that engine, you can easily make a Succubus Stories mod. And this is true, except that SubC is not just built on top of SugarCube, it is a deep modification of it; certain features have been changed or even removed. For example, SubC does not feature most SugarCube user input macros. SubC was also forked from a certain non-current version of SugarCube, meaning the latest features of that engine may not be present.
On top of this, SubC has tons of its own engine additions, and this goes far beyond macros and functions. For example, most tags in SubC have semantic meaning, and are used to execute various game functions, like controlling audio playback or character portraits.
The long and short of this means that I'll need to compile my own documentation and examples for making mods. This will take time. I do actually maintain internal documentation for my own use that will serve as the basis for modding documentation, so I don't need to start from scratch. However, my internal documentation is very basic and terse, and will require a great deal of expansion.
SubC as a Game Engine
"What about SubC as a general game engine?" I hear myself pretending you asked. "What if I want to make my own game, and not a mod? Will your engine work for that?"
No. Basically, this version of the engine is very dedicated and tied to Succubus Stories and is generally not user-friendly or general-purpose enough to make it viable as a game engine for anyone to use as some kind of replacement for, say, vanilla Twine. However, a massive restructure of the engine is something I want to do for the next game I make, assuming I make another game in this style. I have many ideas about how to make a better engine, and maybe if I do, I'll make it suitable for others to use, though I don't think I could make something good enough to compete with vanilla Twine, so I'm not sure it'd be worth the effort.