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>>
<</widget>>
v1 - original, works as expected.
<<widget "neckExposed">>
<<if args[0].armour.neck.length == 0>>true<<else>>false<</if>>
<</widget>>
Any help would be appreciated, including suggestions that could replace my code.
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.
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…
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.
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.
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.
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.
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.