What is $variable.property, how to use it? and other beginner questions

Twine Version: 2.9.0
Sugarcube 2.36.1

Hi, I’m very new to programming, I read motoslave sugarcube documentation, and twinery cookbook , when I read most of the documentation, I don’t understand at all. I decided to ask here, and ask about the introduction. If there is a resource or tutorial that is beginner friendly please share me the link.

It is said that

Type:
Property access,
dot notation

Syntax:
$variable.property

Example:
$thing.name

I understand $variable and how to use it, but what is $variable.property?
I tried to tinker around, and I keep getting error…
It seems I misunderstood what it does…

How and when to use it in real case?
I see people using $variable.(insert text here).(insert text 2)

I don’t have a clue what they are setting for…

Second question,

Type:
Index/property access,
square bracket notation

Syntax:
$variable[numericIndex]
$variable[“property”]
$variable[$indexOrPropertyVariable]

Example:
$thing[0]
$thing[“name”]
$thing[‘name’]
$thing[$member]

What is $variable[“property”] ?
How and when to use it?

I remember about indexing and array [0] means first item of the list, so I think $thing[0] is like this?

<<set $thing either to (“gloves”,“hat”))>>

so if I write
“I forgot to bring my $thing[0]” become “I forgot to bring my gloves”

Is this correct?

Third question is about either.

I know how to use either, the logic.

<<set _fruit to either("apple", "cherry", "banana")>>
What fruit we will have today?
<<if _fruit is "apple">>
today we will have _fruit
<</if>>

This means, the fruit will be randomized (apple,cherry, banana), and if apple was picked, the text will be

What fruit we will have today?
today we will have apple

I don’t understand the example from the site…

Using arrays; given: $pies = [“Blueberry”, “Cherry”, “Pecan”]
either($pies) → Returns a random pie from the whole array

I copy pasted this into twinnery (web), it doesn’t yield anything… how to use this?

Is it <<set $pied= ["Blueberry", "Cherry", "Pecan"]>>

Today I will have <<print either($pies)>>
But I don’t think this code will run… it will create error.


Note: I know how to use set, if, elseif , and else, and set. (not expertly, but I have a clue what it does).
I know what this mean <<set $lampswitch to false>> → it means set lamp switch to turned off

Explaination in layman’s terms with example usage is greatly appreciated!

Thanks in advance.

Welcome Summerstarlight,
There are many types of variables, they all have their proper use, and each allow for some things other types do not allow.
The basic variable is by far the most straightforward: it’s a variable with one name and one value.
The object is a comfort variable: it’s a variable with many values. Each of these values is associated to a property and can be called by the property.
The array is a very clever one: it’s a variable with many values too. Each value is to be called by the index of the variable.

Here’s a sequence of how you can create and call all these three variables.

Basic variable
<<set $Name to "Josh">><<set $Age to 20>>
$Name
$Age

Object variable with properties
<<set $MC to {Name:"Josh",Age:20}>>
$MC.Name
$MC.Age

Array variable with index, note the first index is 0, not 1
<<set $Hero to ["Josh",20]>>
$Hero[0]
$Hero[1]
3 Likes

As for your “either” question, something like this should work.

<<set $pie to either ("Blueberry", "Cherry", "Pecan")>>
I'd like a <<print ($pie)>> pie!

Basically, in the first line you establish that the $pie variable can be any of the words/values you inserted in the brackets, then in second line with “print” you display one of them

1 Like

Here’s more of a big-picture overview of the concepts… there are a bunch of places where this is overly simplified, but it should get you started.

SugarCube’s scripting is a thin helper layer over JavaScript.

Javascript, like most languages, has both single values (numbers, strings/text, true/false) and two kinds of collections: “arrays” are lists of values where you access elements by their postion (starting at 0), while “objects” are like a dictionary where you look up elements by name.

JavaScript uses square brackets to create arrays, and curly braces to create objects.

So this creates an array of three elements:

<<set $pies = ["Blueberry", "Cherry", "Pecan"]>>

(note that this is only setting the value of $pies: it won’t display anything)

A second use of square brackets is to put them after a variable name to “index” into an array (or object), so you would get each of these values from the array with $pies[0] (“Blueberry”), $pies[1] (“Cherry”), and $pies[2] (“Pecan”).


To create an object/dictionary, you use curly braces, and give name/value pairs separated by a colon. The names are called “properties” of the object.

<<set $ages = {"Josh": 20,  "Tim": 35, "22Blue": 15}>>

And then you access them by name: $ages["Josh"] is 20, $ages["Tim"] is 35, and $ages["22Blue"] is 15.


Then the dot notation is a shortcut. In most languages, variable names can be made up of letters, numbers, and underscores, but can’t start with a number. If your property name fits that pattern, then you can write $ages.Josh instead of $ages["Josh"] and it’s a little less typing. But you’d have to get 22Blue with the bracket notation: writing $ages.22Blue would be a syntax error, since it starts with a number.


And finally, either() is a “function” (named piece of code that can take inputs and give a single output) that takes any number of things and randomly chooses between them.

BUT! It tries to be helpful and let you pass arrays of things as well as just passing the things individually. So if any of the “arguments” to either is an array, it’ll put all the array elements into its set that it’s randomly choosing from. So the following will choose from four different pies:

<<set $pies to ["Blueberry", "Cherry", "Pecan">>
<<set $pie to either($pies, "Lemon Meringue")>>
3 Likes

Thank you for the welcome souppilouliouma and thank you for taking time explaining to me.

I can understand it better with your example, it is easier to understand.

For
<<set $MC to {Name:“Josh”,Age:20}>>
$MC.Name
$MC.Age

If I <<print $MC.Name>>
The result will be Josh?

I see, so you used it that way. Thank you for answering my either questions Naarel.

1 Like

You don’t need to use <<print>> in this instance, this macro is better used for complex manipulations when there’s no need to create a new variable, but yes if you do that you’ll get Josh.

Hi Josh , thank you for taking time explaining to me.

Your explanation is easy to understand, I need to study your replies to understand it better.

I saw

<<set $pie=[]>> or <<set $pie=()>>

in someone’s starting code → from your explanation it is array related, but what does

[ ]

/blank symbolize? A randomized array? Declaring there will be a lot of number array in future code?

If want to create randomized conversations in one passage, but it failed… I tried the to use array, variable with set, if, and either.

Expectations:
I have topicAboutfruit, topic2 and topic 3 → similar to <<set $pie to either(apple,cherry)>>
I prepare to say I like either apple/cherry/kiwi if the topic is about fruit → similar to <<set $pie to either(apple,cherry)>>

I put it in StoryInit so it’s become reusable topic

When starting conversation the topic is randomized from list

I got fruit topic!

Then fruit topic is randomized from list

i got Apple, so I said I like apple

If I click Yes! again
It might give me another topicfruit but about cherry instead of apple.

Code

::StoryInit
<<set $topic = [topicAboutfruit, topic2, topic3]>> /*option topic to talk about*/
<<set $topicfruit = [apple,  cherry, kiwi]>> /*if topic is fruit then there's option to talk about apple, cherry and kiwi*/

:: startconversation 
What do you want to talk?
[[Yes!->startconversation]] /*this is to stay in the same passage, but how to hide 'what do you want to talk about + yes' after clicking Yes?*/

<<nobr>>
<<set _randomconvotemp to either ($topic)>>

<<if _randomconvotemp is $topicAboutfruit>>
<<set _convesationaboutfruit to either($topicfruit)>>
<</if>>
<<set $topicfruit []>>
<<if $topicfruit[0]>>
I like apple

<<elseif $topicfruit[1]>>
i like Cherry 
<</if>>

<</nobr>>

You might use [] or {} to declare an empty container that you’ll put stuff in later.

For instance, you can add things to the end of an array with <<run $pies.push("Pumpkin")>> and there are a bunch of other commands to manipulate them.

For objects, you can add properties at any time by setting them with the bracket or dot syntax. And <<run delete $ages.Josh>> should delete a property.


There are a bunch of details that are (probably?) wrong with your code:

<<set $topic = [topicAboutfruit, topic2, topic3]>>

I would expect this to give you an error: if you want topicAboutFruit to be a string, you need quotes around it ("topicAboutFruit"). If you want it to be the value of some other variable (which seems unlikely, but maybe?) you’d need $topicAboutFruit. Having the bare words seems unlikely to be correct.

Similarly with the next line, you almost certainly want quotes around each of the fruit names.

<<set $topicfruit = ["apple", "cherry", "kiwi"]>>

I’m not sure why you’re staying in the same passage: I’d probably go to a different one.

Every time you do the following it’s going to choose a new random fruit. So I suspect you want to do it once and save them in story variables ($conversationAboutFruit) rather than temporary ones (_conversationAboutFruit).

<<set _conversationaboutfruit to either($topicfruit)>>

<<set $topicfruit []>> - I don’t understand what this is trying to do?

<<if $topicfruit[0]>> - you don’t have a comparison here, so SugarCube/JavaScript will try to use $topicfruit[0] (“apple”) as a true/false value. And since it’s not false or undefined or 0 or the empty string, it’ll decide that it’s “truthy” and so this if statement will always be chosen and it will never get to the elseif.

I suspect you want <<if _convesationaboutfruit is $topicfruit[0]>> but if all you’re doing is saying “I like whatever fruit” then an easier way is just to write I like _convesationaboutfruit into your code (for variables, you can often just write their name instead of needing to write <<print _convesationaboutfruit>>)

Hope that helps!

A variable is a means to associated a name or identifier with a value, it’s the value itself that has a data-type.

eg. There are many types of values, or value data-types. :slight_smile:

2 Likes

Thanks for the clarification, @Greyelf. My daily use of variables as a statistician might have made me confuse the variable/value meanings from statistics to computer programming!

1 Like

I kinda grasping, kinda understand and not at same time.

I see, so when someone created
<<set _conversation to $about.pie.random()>>

or template code with function()

it means we could add or modify inside the ()?

Oh, I can use
<<run>>
to hide/delete.

If I want to hide “What do you want to eat?” After clicking yes, but it doesn’t work? Maybe i misunderstood the usage here…

:: startconversationeat
<<set $start to "What do you want to eat?">>
<<set $doyouwant to false>>

$start
<<linkreplace"No">>No, I'm sleepy<</linkreplace>>
<<run $doyouwant to true>>

<<if $doyouwant is true>>
<<run delete $start>>
<</if>>

I see, you need to add $ or “” or other symbol
In some part twinery doesn’t need to use “”, in some part they need label those as string.

The $ vs _ is confusing too
I know $ is permanent and _ is temporary only being used in that passage.
But I’m unsure/still grasping which one to use depending on context.

I need to learn the context usage :face_with_spiral_eyes:

It reminds me about learning how to cook, you know it’s egg, you could cook it and create cake with it. You watch video recipe and mimic it by cracking the egg on your own, its end up as chaotic mess unlike the video. :laughing:

After implementing your advice and tinkering here and there the code is working, thank you very much. :smiling_face:

I tried to implement and challenge myself by adding the second topic, it works after trial error here and there

I can’t delete the answer for pie if I got fruit topic, like wise I can’t delete answer for fruit when getting pie topic.

I tried the <<run delete $variable>> and <<run delete ("variable string"), but i don’t know why it doesn’t work…

The code


::StoryInit
<<set $topic = ["topicAboutfruit", "topicAboutpie", "topicHobby"]>> /*option topic to talk about*/
<<set $topicfruit = ["apple",  "cherry", "kiwi"]>> /*if topic is fruit then there's option to talk about apple, cherry and kiwi*/
<<set $topicpie = ["pumpkin",  "lemon", "mango"]>>
<<set $topicHobby = ["dancing",  "sleeping", "watching"]>>/*for now I don't add the third topic, since adding second option wasn't working*/
::
What do you want to talk?
[[Yes!->startconversation]] 
<<nobr>>
<<set _randomconvotemp to either ($topic)>>

<<if $randomconvotemp is $topicAboutfruit>>
<<set $convesationaboutfruit to either($topicfruit)>>
<<run delete ("topicAboutpie")>> 
<</if>>

<<if $randomconvotemp is $topicAboutpie>>
<<set $convesation2 to either($topicpie)>>
<<run delete ("topicAboutfruit")>> 
<</if>>

<<if $convesationaboutfruit is $topicfruit[0]>>
I like apple
<</if>>
<<if $convesationaboutfruit is $topicfruit[1]>>
i like Cherry 
<</if>>
<<if $convesationaboutfruit is $topicfruit[2]>>
kiwi is great too
<</if>>

<<if $convesation2 is $topicpie[0]>>
yummy
<</if>>
<<if $convesation2 is $topicpie[1]>>
i prefer other taste
<</if>>
<<if $convesation2 is $topicpie[2]>>
pretty good
<</if>>

<</nobr>>

About why I’m not using another passage, i heard if you reach (insert number) amount passages, the web twinery will slow down… so if i can, I’ll add it in one passage.

It’s not working because the code doesn’t automatically know what you want to delete “topicAboutpie” from. When you’re using array methods, you have to specify the name of the variable that holds the array, like this:

<<run $topic.delete("topicAboutpie")>>

1 Like

SugarCube includes an <<unset>> macro, whose purpose is to “delete” previously defined variables.

<<unset $start>>

On the other hand, if you want to remove a specific value from an Array, then use the <Array>.deleteAll() method if you’re using the new v2.37.0 release of SugarCube, which was previously named <Array>.delete() in ealier releases.

/* if using v2.37.0 */
<<run $topic.deleteAll("topicAboutpie")>>

/* if using an earlier release of SugarCube */
<<run $topic.delete("topicAboutpie")>>
1 Like

Oh! I thought they will automatically delete anything that contains "topicAboutpie" (from StoryInit or Current Passage).

So <<run delete>> is only for deleting arrays with property related, like the property itself <<run delete $property.variable>> and string inside property <<run delete $property.variable("text you want to delete">>? Is my conclusion correct?

Thank you Emery for helping me.

Oh! i read the <<unset>> in sugarcube documentation before, it just connect to me that I should <<unset>> in this type of situation too.

So each code has their own eraser…
When I want to erase array with property, I need to use <<run delete $property.variable>> or . <<run $variable.deleteAll("text you want to delete")>>

Thank you for explaining it to me Greyelf, it’s easy to understand.

I have questions, how to remove <<link>> and remove <<linkreplace>>?

When I search using keyword “unlink” “hide link” “delete link” in sugarcube documentation, I didn’t found anything…

No, <<run delete $ages.Josh>> is for a property of an object and <<run $topic.delete("topicAboutpie")>> (or .deleteAll() in the latest version) is for a member (or members) of an array. You can look back to the first reply in this thread for an explanation of the difference between them.

Also, <<run delete $ages.Josh>> isn’t searching through your variables; you’re telling it exactly what to delete: the Josh property of the variable $ages. So it’s not actually different from the .delete()/.deleteAll() array method in this way. Whenever you’re modifying the value of a variable of any type, you do have to use the name of the variable you’re modifying. It would be really inefficient for JavaScript to have to run through your entire project looking for a match.

1 Like

Oh, so it is different…
In this thread, in my thread?

I see, so the systems is like that, I thought it was like when we do a search in window explore, where files that contains “topicAboutpie” pop out, then using those as base, its delete it automatically.

Thank you for explaining it to me Emery, it’s makes me understand it better.

Yes, this comment explains the difference between an object and an array: What is $variable.property, how to use it? and other beginner questions - #2 by souppilouliouma

1 Like

Okay, thank you Emery.
I will review that post again.