[SugarCube] How does Twine variables work in JavaScript?

Twine Version: 2.6.1
SugarCube version: 2.36.1

Hello!
I can’t wrap my head around how the Twine variables work in SugarCube.
Basically I am working on a simple class that, let’s say stores a variable name varname.
I want to have control over this variable by setting it and getting its value from JS code.
I successfully created a class and implemented its necessary methods as shown in https://www.motoslave.net/sugarcube/2/docs/#guide-tips-non-generic-object-types.

My problem is best shown by examples:
Let’s say my class has the name MyClass, it has a single member, called varname that stores a string variable name. It can be created by var myobj1 = new MyClass("$$myvar"); or <<set $myobj1 to new MyClass("$$myvar")>> (notice the double “$” because of escaping. )
I want to have convenience methods like myobj1.set(true) or myobj1.set(1) or myobj1.get(). The set() is implemented using State.setVar(varname,value), no problem with that. BUT the get is implemented using State.getVar(varname) and THIS is where it gets tricky, because it just doesn’t work. Let’s say my custom variable $myvar is true.
String evaluations:

var str = "" + varname; //becomes $myvar
var val1 = State.getVar(varname); //Becomes 'undefined' because 'varname' is evaluated as 'true'.
var val2 = State.variables[varname];   //Same happens, it is 'undefined'.
var val3 = State.getVar(""+varname); //You would think it would work, but nope, it is Still 'undefined'.
var str2 = varname.substring(1); //Becomes 'true' not the expected 'myvar'. It gets evaluated somehow.
var str3 = varname.substring(2); //Becomes 'myvar' for some reason.
State.setVar(varname,false); //Correctly sets the '$myvar' to false. No problems.

I searched all the forums I could find for the solution without any solutions. (Yes I registered here just because of this).
I tested it so much, but to no avail. Does anyone know how this works and how to do it right?

Thanks in advance.

You can use variables().Veriablename in a <<script>> passage (Should also work in the Story Javascript passage) to get a Sugercube variable you saved in any other passage as long it’s not temporary

:: StoryInit
<<set $hasPhone to true>>
<<set $phoneModel to "Random">>
<<script>>
if (variables().hasPhone) {
Code!
}
console.log(variables().phoneModel);

// (Editing the Variable is also possible this way):
let phone = variables().hasPhone;
phone = false;
console.log(phone);

<</script>>

By accessing the Variable from Sugercube you won’t have to hassle yourself with its return so it can be used in other passages.

Hope this helps, this is a direct link to its place in the Documentation
Sugercube2 Docs Variable Function

I have probably misunderstood what your trying to achieve

1 Like

Hmm. I don’t get those results. I wonder… where is this $$ escaping coming from? SugarCube doesn’t do that inside a string, I don’t think. So I suspect that ""+varname is actually $$myname and you’re only seeing $myname because of how you’re displaying it. I’d try <<run console.log(str)>> to see.

Also, how are you evaluating these strings? Because SugarCube does different things in macro evaluations vs. script tags, so that could affect the results too.

State.getVar(varname) should work if varname is set to "$myname".

State.variables needs the name without the sigil, so State.variables["myname"] should work, but State.variables["$myname"] (or equivalently State.variables[varname]) wil not work.

2 Likes

““I wonder… where is this $$ escaping coming from?””

I got it from: SugarCube v2 Documentation (motoslave.net)

Using the double dollar-sign markup (which escapes the $-sigil)

You were right, it works as intended. I was confused, because I tried printing the variables to the passages and thought that the problem was in the variable system and not in my interpretation of how the printing works. Thanks to your advice about using console.log.
So I can use <<set $myobj1 to new MyClass("$varname")>>.
I just need to be aware of how I print it out.

2 Likes

Also thank you for your answers. I am glad that this forum is this active.

Hehe I am few days late, but the $$ is from this part of the docs:

/* Using the double dollar-sign markup (which escapes the $-sigil): $$ */
The variable $$name is set to: $name

It is very misleading as its meant for text in your Passages

you can use $$name to display $name as normal text in the passage instead of displaying the value of $name. I haven’t found the need to incorporate this into any Story/Game unless it’s a story trying to explain how your own twine code works for others.