0 votes
by (170 points)

Hi, I'm having a little problem

I start to use Twine very recently for a university work, I watch some tutorials to learn how to use sugarcube to do some stuff and found a method to make an inventory with objects, arrays, and loops.

I have something like this

<<set $katfood = {

name: "Kat Food"

amount: 5

}>>

<<set $inv=[$katfood]>>

then I use a loop  to show the objects inside the inventory

<<for $i=0; $i<$inv.length; $i++>>

<<set $item=$inv[$i]>>

$item.name - $item.amount

<</for>>

the problem comes when y change the amount value, in the loop doesn't change

<<if visited() is 1>>
<<set $katfood.amount++>>
<</if>>

$katfood.amount //this change

<<for $i=0; $i<$inv.length; $i++>>

<<set $item=$inv[$i]>>

$item.name - $item.amount //this does't change

<</for>>

 

Someone know why this is happening? I search for a solution but didn't find anything.

PS: sorry for grammar mistake, I'm from Chile and my english it isn't very good, also if there any variable with the wrong name is because I translate them to english here

1 Answer

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

I am going to assume that you are initialising your $katfood & $inv story variables in one passage...

<<set $katfood = {
  name: "Kat Food",
  amount: 5
}>>
<<set $inv = [$katfood]>>

... and you have your loop & value changing code in another passage...

<<if visited() is 1>>
  <<set $katfood.amount++>>
<</if>>
$katfood.amount   /* this changed */

<<for _item range $inv>>
  _item.name - _item.amount   /* this does't change. */
<</for>>

... and that you want to know why changing the value of the amount property of object in the $katfood story variable doesn't effect the instance of the object within the $inv Array.

Each time the story transitions from one passage to another (can be the same passage) the current state (values) of all known variables is cloned. The original copy of the state is added to the History systems, and the cloned copy is made available to the passage that is about to be shown. This cloning process results in each object reference now referencing their own unique copies of the original objects.

eg. In your first example you had the $katfood story variable and the first element of the $inv Array both referencing the same object. After the passage transition $katfood would now reference one copy of the original object and the first element of the $inv Array would now references a different copy of the original object.

The way you get around this behaviour is to store a reference to either an index or a key within the Array, instead of an object reference.

1. Initialise a single instance object and store a copy of it's key with the $inv Array.

<<set $items = {
  "kat-food": {
    name: "Kat Food",
    amount: 5
  },
  "dog-food": {
    name: "Dog Food",
    amount: 5
  }
}>>
<<set $inv = ["kat-food"]>>


2. Use the "kat-food" key to reference the single instance of the associated object.

<<if visited() is 1>>
  <<set $items["kat-food"].amount++>>
<</if>>
$items["kat-food"].amount   /* this changed */

<<for _id range $inv>>
  $items[_id].name - $items[_id].amount   /* and so did this */
<</for>>

 

by (170 points)
Thank you so much, it works perfectly

I assumed had something to do with changing the object instead the array, but had no clue on how to fix it
...