Visual Novel Markup Language - Hex Devlog #2 (Patreon)
Content
Hex’s visual novel markup language is a simple, but fairly powerful way for me to quickly write and implement VN scripts. The game can call scripts from individual Twine passages, or can be given the name of a playlist, in which case it pulls a random passage from the playlist to read as a script.
The markup language used to write scripts is simple, but there are a number of shortcuts built in. Sending a basic message is as simple as typing it in; any line without any special markup at the start is interpreted to be a message and is displayed in the textbox interface as HTML with some minor beautifying (like turning “<3” into a heart symbol, or “--” into a proper em-dash). You can also type a single ">" (greater-than sign) to indicate a message, and the command “msg>” also works. For messages that may contain the “>” character in the text itself, you need to start the message with it to make sure it isn’t interpreted as a command.
To set a speaker name, you can use the speaker command “speaker>” which can be shortened to “s>” or “:>”. Once a speaker is set, all messages following will be from that speaker until a new speaker is set. Not having a speaker by setting the speaker to nothing can also be done for narration; the speaker box will just be blank. Message text is automatically colored for common speaker names, including things like “Man” or “Woman,” and it appears in white for narration or for miscellaneous speakers.
There is also a combined format for giving a speaker and message in one line, for conversations with a lot of back-and-forth. “Meila:> Hi there!”, for example, would set Meila as the speaker and have her say the message “Hi there!” As with setting the speaker in other ways, messages without set speakers following this will be from Meila too until a new speaker is set.
Other commands are denoted with the format “command> data” where the command portion is the name of a valid command and the data portion includes optional data on what the command should do. For example, to set sprites, you use the “portrait>” or “p>” command, followed by data on each sprite you wish to set in brackets sort of like arrays: “p> [player, horny, center-left] [meila, angry, center-right]”. The sprite data brackets are organized like this: “[characterName, expression, position, dim, nude]” the “dim” and “nude” parameters are optional, and are passed in as booleans (true or false). By default, most characters will appear dressed and the player character will appear in whatever state they were in last, but their nudity state can be overridden. To pass a nudity state you need to pass the dim state as well. Dimming sprites just makes them darker and removes their shadow effect a bit, which can be useful when they aren’t speaking in a scene or shouldn’t be emphasized.
Here’s a list of commands currently in the engine:
- “curtain>” This command calls the “curtain,” which is a quick animation to change scenes or locations.
- “cg> filepaths” This command clears sprites, dims the background with an overlay, and displays CGs. A list of file paths to PNG resources can be provided; multiple file paths will be stacked in order from first to last to create layered images.
- “cg> clear” If you pass “clear” as the data for the CG command, the CG will be removed and the overlay will be hidden.
- “bg> filepaths” This command changes the background behind the sprites. Multiple files can be stacked, as with CGs. This will be set according to the game state if not specified.
- “clear>” Clears sprites/portraits and from the scene.
- “time> day/night” Changes the appearance of the scene to match the indicated time. At night, backgrounds are darkened and sprites are slightly grayscaled with a filter. Doesn’t change the game’s actual internal time. If neither “day” nor “night” is passed, the time is toggled. This will be set according to the game state if not specified.
- “rain> start/stop” Starts or stops the raining effect. If neither “start” nor “stop” is passed, the effect is toggled. This will be set according to the game state if not specified.
- “comment>” or “//>” creates a comment, which is a line the engine will simply ignore.
Other commands I may add in the future:
- Branching paths and interactions both require the game to return to “text mode” and then start another VN scene. So far I think this isn’t going to be an issue for me, but I do think a way to offer choices and branch to different scenes from within the VN mode would be a smart idea.
- Likewise, music can’t be changed in VN mode very easily. It’s not impossible, but it is inconvenient. You have to either run a macro command as part of a message, or stop the current scene and start a new one with different music. Again, I don’t feel like I need this feature, but I should probably add it.
- Arbitrary scripting is not possible in VN mode right now. I am considering adding a “run>” command or similar to allow either JS code or silent macro code (not sure which, maybe I’ll do two commands). Again, I probably sound like a broken record, but I don’t personally have many use cases for this in mind, but I feel like I should probably add it in.
- You can’t transition directly from one scene to another, you have to stop in text mode first at this time. I plan to actually fix this with a “scene>” command or something as I think this is something I’ll need.
A look at some of the things that are "beautified" in messages:
- "<3" is converted into ♥
- "<33" is converted into ♥♥♥
- "#" is converted into ♪
- "#!" is converted into ♫
- "*" is converted into ☆
- "..." is converted into …
- "--" is converted into —
- Straight quotes are converted into curly typographic versions
I may add more of these in the future. In Succubus Stories I painstakingly write out the HTML entities for everything, and I'm not doing that anymore!
In addition to my additions, SugarCube's default markup, like double slashes for italics "//I'm italics!//" and such are still included, and I can also fall back to pure HTML if needed, since messages also go through SugarCube's "wikifier."
I'm just talking shop in this post, but I did want to show off my markup language a bit. When and if Hex gets mod support, modders will write scenes in this markup language, but at that time I'll provide official documentation.