Home Creators Posts Import Register Favorites Logout

Content

When developing interactive fiction with Twine and SugarCube, it's often useful to have different UI layouts for different parts of your game, such as a fullscreen layout for immersive story moments and a sidebar layout for passages where you go through a daily routine.

This is something I haven't been doing efficiently in MindWare, but I now have a solution that (at least to me) seems fairly elegant and robust.

Basically, my solution uses Twine's passage tag system combined with JavaScript in the SugarCube StoryInterface special passage (used to create a custom UI):

:: StoryInterface

<script>

$(document).on(':passagestart', function (ev) {

var passage = ev.passage;

var tags = passage.tags;

var root = $('#ui-root');

if (tags.includes('fullscreen')) {

root.html('

');

} else if (tags.includes('sidebar')) {

root.html(`

Game Title

`);

} else if (tags.includes('split')) {

root.html(`

`);

} else {

// Default minimal layout

root.html('

');

}

});

</script>

When a passage loads, the system checks its tags and rebuilds the UI accordingly. Now you can create passages that use different layouts simply by adding tags:

:: Story Beginning [fullscreen]# Chapter One​The story begins in a quiet village...​This passage uses the fullscreen layout for an immersive reading experience.​[[Enter the tavern|Tavern]]​:: Tavern [sidebar]# The Rusty Dragon Tavern​You enter the bustling tavern. The air is thick with smoke and laughter.

​:: Notice Board [split]# Notice Board​Several parchments are pinned to the wooden board.

You can add new layouts by extending the JavaScript in StoryInterface:

else if (tags.includes('custom')) {

root.html(`

<!-- Your custom HTML structure. Remember that you need

because that's where the content of your passages is displayed -->

`);

}

When you save your game and then load the save, the layout system automatically restores the correct UI for the current passage. This happens because SugarCube fires the :passagestart event before the rendering of an incoming passage.

If you need certain UI elements to persist across layout changes (like a music player or notification system), place them outside the #ui-root:

:: StoryInterface

I'm not sure how many of my supporters are interested in Twine/SugarCube game development, but I hope this helps if any of you are.

Files

Comments

gg

First off, I have always been blown away with your UI/UX experience. I am planning to pick up SQ Cruise Ship which I helped with back in it's development days. I suspect that the developer passed away during Covid. In my programming days there's the quote (") and the squote (') for single quote. What is the backwards slanting quote? I guess it's important. If I do the Cruise game then I might build on your infrastructure. I also don't like how Girl Spy is incomplete. I might take on that when Female Agent is revised.

Subjunctive Games

Thanks so much! I really appreciate the kind words about the UI. The backwards slanting quotes you're seeing (`) are called backticks or grave accents. In JavaScript, they're used for template literals - basically strings that can span multiple lines and include variables or expressions directly inside them using ${variable}. They're super handy for building HTML strings like in my example, since you can write multi-line HTML without having to concatenate strings with + operators. That's sad to hear about the SQ Cruise Ship developer - I remember playing (and enjoying) the game, wishing there was more of it.