How can I return a value from a widget as a conditional?

Twine Version: Using Tweego
Sugarcube Version: 2.36.1

Is there any way to return information from a widget as a true/false value? The methods I’ve tried seem to either:

  • Take the name of the widget as the conditional, which returns the error:
    bad conditional expression in <<if>> clause: Unexpected token '<<'
  • Wrapping this in `s causes the if clause to take the string result, which ALWAYS evaluates to true

Preferably, I would like to avoid creating variables in the widget, because I use this widget a lot, up to 50 instances of such variable would need to be created…

Code (Case 1)

<<if <<neckExposed $player>>>> is exposed!<<else>>remains safe..<</if>>

Code (Case 2)

<<if `<<neckExposed $player>>`>> is exposed!<<else>>remains safe..<</if>>

Example Macro Code:

v2 - not fully tested, not in use.
<<widget "neckExposed">>
	<<= _args[0].armour.neck.length == 0>>

v1 - original, works as expected.
<<widget "neckExposed">>
	<<if args[0].armour.neck.length == 0>>true<<else>>false<</if>>

Any help would be appreciated, including suggestions that could replace my code.

For clarification, I’m either looking for an alternative to my (admittedly bad) code.

Or preferably a way to pass a boolean value from a widget to an <<if>> statement without assigning a variable inside said widget.

I don’t know SugarCube… yet, but I found this relevant Reddit post.

SugarCube setting variable to the output of method

And here’s another post about setting up functions to return values.

How to return a value from a javascript function to a sugarcube variable

I know it’s not exactly what you were asking for, but maybe this will provide some clarity for you. It seems like widgets can’t return values, but JavaScript functions can. Seems like it would be a very handy feature for a widget though, but from what I gather, widgets are processed during the rendering stage that outputs the HTML… and not preprocessed beforehand.

Hope this helps.

1 Like

The Widget and Custom Macro features are designed to:

  • execute TwineScript, Macros, and Widgets.
  • inject content directly into the web-page.

And nether feature returns a value, so they can’t be used as an argument when calling a Widget or Macro, which is why your test cases are resulting in errors. Custom Functions on the other hand can return a value.

You can define custom functions on the special setup variable within the Story > JavaScript area of your project…

setup.neckExposed = function (actor) {
	return actor.armour.neck.length === 0;

…and then use that custom function like so in a Passage…

<if setup.neckExposed($player)>>is exposed!<<else>>remains safe..<</if>>

warning: the above examples have not been tested.


SugarCube’s Macros (whether created with <<widget>>, built in, or added with Macro.add()) are not functions, and cannot return values. Even if they could be nested (like in your first example), your code wouldn’t work, because they can output to the screen, but not return values.

As @Greyelf said, a Javascript function can return a value, and you can use it in your code in the way you were hoping to use a macro.

If, however, you have no Javascript skills, or would prefer to write your functions with normal twinescript, I have a <<function>> macro that does this for you.

An example:

<<function "hello">>
    <<set _return to "Hello " + _args[0]>>

<<print tw.hello("Hituro")>>

If this would be of interest, check the github page for installation and usage instructions.


@Hituro I’m surprised your widget isn’t built into SugarCube. Awesome job!

I wonder if Snowman can do this return function stuff more seamlessly since it’s primarily just JavaScript.

Hard to say. Snowman is indeed just JS, so it will work pretty easily with functions. On the other hand it doesn’t have the same variety of useful in-passage stuff like macros, so you are rolling your own anyway. Which is better? Most people choose SugarCube, but if you are a skilled JS-dev already just looking for a framework to build from, then Snowman clearly has its uses.

1 Like

It’s not a built-in macro because it’s a fairly terrible way to accomplish its goal.

EDIT: To be fair, the goal is noble, but that <<function>> macro is like using a dragline to dig a hole in your yard to plant a single tulip bulb.

Since, at this point, we’re talking about actual JavaScript functions, no. Every story format I know of, save Harlowe, makes using functions fairly trivial.

Okay… then the JS function call is the preferred method? …or am I missing something, like the need to use it in this way is flawed?

Of what, specifically?

If you meant of returning a value, then yes. I mean, obviously, since no other method exists.

If you meant of constructing a function, then, in general, yes. The <<function>> macro allows one to create functions via macros and markup, which can be nice in the same way widgets are, but is overcomplicated for what it accomplishes. Aside from the “I don’t need to learn anything else” angle, it will always be inferior to using a regular function.

If you meant something else, please elucidate.



That’s pretty much what I meant (the returning a value thing). Thank you for taking to time to answer my question.

I just meant, maybe there was a different way of approaching the same result. Returning values makes for cleaner code in some cases. I wasn’t sure if there was another way to tackle it. Functions are the best way. I understand that now.

There’s been some confusion about the above statement.

To be clear. I wasn’t saying there was anything wrong with @Hituro’s <<function>> macro specifically.

The only issue is that the functions it creates are, by necessity of the APIs it uses, rather roundabout at doing what they do. Simply using an intermediate temporary variable or a regular JavaScript function would be better. I don’t want to overstate that though, using <<function>> would probably be fine in many cases if it makes you comfortable.

1 Like