I’ve recently implemented a loading screen for an upcoming version of MindWare, and I would like to take a few moments to explain why and share the solution with you.
The Problem
One of the biggest and most persistent issues I’ve been dealing with (responsible for most bug reports I’ve received so far) has been missing or improperly initialized variables when starting a new game or loading a save. This can cause all sorts of weird behavior and frustrating bugs for players.
When a person with limited understanding of how the Twine engine works and virtually no experience with the creation of larger interactive fiction games sets out to create a game like MindWare, they may start by placing important variables in the StoryInit passage. All variables placed in this passage are initialized when you start a new game.
The same inexperienced developer may then add additional variables to the StoryInit passage, such as variables for a new part of the UI, and release a new version of their game. You then load your old save and are greeted with an error message because your save is missing the newly added variables. To fix the error, you would have to start a new game—not desirable at all.
The Solution
I’m not the first person in the world to have dealt with this problem (see here and here, for example), so my solution isn’t something groundbreaking, but I think that it’s polished and reusable enough that others might benefit from it. I also hope to receive feedback from those how are more knowledgable than me.
How it works:
When a new game starts or a save is loaded, a function is called.
This function navigates to a special variable initialization passage.
The variable initialization passage displays a loading screen and includes passages with variables to be initialized (being able to divide variables in to different passages makes it easier to stay organized).
A simulated loading process updates the progress bar.
Once “loading” is complete, the player is returned to either the previous passage (for loaded games) or the Start passage (for fresh playthroughs).
With this solution, I’m able to load variables (most of them anyway) that I have been very generously collected by a Discord user and MindWare supporter UnwrappedGodiva (thank you again!). These variables provide a solid starting point on which I can expand. More importantly, I now have a way to declare future global variables in a way that won’t break old saves.
The Code
This script sets up the logic for when to run the initialization process:
:: Scripts-StartingVariables [script]// Initialize a flag to track whether StartingVariables has runsetup.startingScriptsRun=false;// Function to run StartingVariablessetup.runStartingVariables=function(){if (!setup.startingScriptsRun) {State.variables.previousPassage=State.passage;setup.startingScriptsRun=true;}else{}};// Run for new games$(document).one(':passagestart',function(ev){if (ev.passage.title==="Start") {setTimeout(setup.runStartingVariables,0);}else{}});// Alternatively, you can delete the block of code above and call the runStartingVariables function directly from the Start passage like this:// <<run setTimeout(setup.runStartingVariables, 0); >>// Run for loaded gamesSave.onLoad.add(function(){setup.startingScriptsRun=false;setTimeout(setup.runStartingVariables,0);});
This is the actual loading screen passage:
:: StartingVariables<<nobr>><divid="loading-screen"><divclass="loading-content"><divclass="loading-bar-container"><divid="loading-bar"></div></div><divclass="loading-text">INITIALIZING...</div></div></div><</nobr>>// Include as many passages with variables as you want here// You can also add your variables directly here <<include"UI Variables">><script>(function() {// Simulate loading processvarprogress=0;varloadingBar=document.getElementById('loading-bar');varloadingInterval=setInterval(function(){progress+=Math.random() *10;if (progress>=100) {progress=100;clearInterval(loadingInterval);setTimeout(function(){// Return to the previous passageSugarCube.Engine.play(SugarCube.State.variables.previousPassage||"Start");},500);}loadingBar.style.width=progress+'%';},100);})();</script>
If you’ve noticed any mistakes or areas that could be improved, please share them with me here or on Discord. Any feedback I receive is greatly appreciated.