+2 votes
by (270 points)

On the SugarCube v2 wiki, it says that when creating widgets, the passage should have a widget tag and that widgets should never be used in special passages. What is the reason for this? I've tested it and it seems to work fine.

WARNING: Widgets should always be defined within their own separate widget-tagged passage—any widgets that are not may be lost on page reload. Do not add a widget tag to any of the specially named passages and attempt to define your widgets there.

2 Answers

0 votes
by (8.6k points)
selected by
Best answer

There is a certain order in which passages are being parsed and ran.

First, everything in the script and widget passages is being processed (and the stylesheet ones too, but those shouldn't contain any active code anyway). This ensures their contents are available before any actual game passage which might use them.

Then comes some special passages like StoryInterface and possibly StoryAuthor, StoryBanner, StorySubtitle and so on. Those define the UI elements and their contents and shouldn't do anything else.

Then, if and only if you start the game anew, comes StoryInit. If you're already mid-game and hit the browser's "reload" button, this passage isn't run and nothing you put in there will be used.

And then your starting passage is run, along with all the task object code and their corresponding special passages.

You want your widgets and macros to be defined as early as possible and you want them to be defined no matter what the player does with the game, so you should put them in the widget and script tagged passages.

That said ... if you need a macro (doesn't work with widget as well from what I saw) in just a single passage, you can also define it right there. Just make sure you do so before you use it.

    if(!Macro.has("myMacro")) {
        Macro.add("myMacro", { handler() {
            new Wikifier(this.output, "Some more code here.");
        } });


by (68.6k points)

That said ... if you need a macro (doesn't work with widget as well from what I saw) in just a single passage, you can also define it right there. Just make sure you do so before you use it.

It will work with a widget exactly as it does with a normal JavaScript macro—widget macros are internally constructed via the Macro API.  That said, you should never do that.  Always define your macros and widgets in the appropriate places.

The main problem with defining macros and/or widgets within normal passages is how the history and saves interact—which is a topic I've no intention of getting into here.  Save yourself a future headache and just don't do it.

by (2.7k points)
Additionally, it appars the "Widget" passage is deleted when the widgets have been defined. Try making a widget-tagged passage called widget, and then putting "<<goto "Widget">>" inside the first passage. It returns an error (passage dos not exist).
by (68.6k points)
Adding commentary to a eight month old question that was already answered is not helpful, especially when your comment is factually incorrect.

Widget passages are not deleted.  You cannot cannot navigate to a widget passage because you're not supposed to be able to do that.  Like script and stylesheet passages (depending on the compiler), they are meant only to define code.  They are kept completely separate from the normal passage store.
0 votes
by (159k points)

The warning you quoted explains a reason you don't define widgets in specially named passages, because under certain conditions the macros they define may not be re-created if the page is reloaded.

Different special passage types are validated and stored differently, and the different special passage types are executed in a particular order with StoryInit being one of the last special passages to be executed.

But the main reason you don't define widgets within the StoryInit special passage is because the developer's documentation tells you not to, and you would think that the person designing the story format would know how best to do things. Just because something appears to be working correctly doesn't mean it is.