XaiJu
Subjunctive Games
Subjunctive Games

patreon


Dynamic UI Layouts in SugarCube

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

<div id="ui-root">

<div id="passages"></div>

</div>

<script>

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

var passage = ev.passage;

var tags = passage.tags;

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

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

root.html('<div id="passages"></div>');

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

root.html(`

<div id="ui-container">

<div id="ui-sidebar">

<h2>Game Title</h2>

<div id="ui-stats"></div>

</div>

<div id="ui-main">

<div id="passages"></div>

</div>

</div>

`);

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

root.html(`

<div id="ui-split">

<div id="ui-left">

<div id="ui-header"></div>

<div id="passages"></div>

</div>

<div id="ui-right">

<div id="ui-info"></div>

</div>

</div>

`);

} else {

// Default minimal layout

root.html('<div id="passages"></div>');

}

});

</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(`

<div id="custom-layout">

<!-- Your custom HTML structure. Remember that you need <div id="passages"></div> because that's where the content of your passages is displayed -->

</div>

`);

}

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

<div id="persistent-ui">

<div id="audio-controls"></div>

</div>

<div id="ui-root">

<div id="passages"></div>

</div>

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.

Comments

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.

Subjunctive Games

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.

gg


More Creators