I am using SugarCube 2.7.2 on Twine 2.0.11
I've narrowed down my error to this odd 'feature'/bug, and recreated it in a fresh story.
<<set $First to {A: 0, B: 0}>>
<<set $Second to $First>>
<<set $Second.A to 1>>
$First.A
$First.B
$Second.A
$Second.B
This is the only thing this story contains.
The output from this passage is:
1
0
1
0
$First.A is set to 1, and I cannot see why.
If I move the line "<<set $Second.A to 1>>" to another passage, $First.A remains 0.
Am I going crazy? Or is this a bug/'intended feature' in either Twine or SugarCube?
Comments
When you do the following <<set $Second to $First>> within the same passage as the initial assignment you are assigning the object reference stored in the First variable to the Second, so now both variables are referencing the same object and any changes to that object effect both variables.
This behaviour changes after traversing to a new passage because during the traversal the current state (values) of all the known variables is copied and it is this copy which is made available to the next passage being shown. The copy procedure causes any variables that were referencing the same object to each now reference their own new copies of the original object, the new copies have the 'same value' as the the original.
Is the solution therefore to have some form of initialisation/startup passage as the starting point of your story, with the sole purpose of establishing every variable you use and 'locking' them in by traversing to a new passage? And avoid assigning one object to another and editing the latter object in the same passage.
I found a second instance of this issue. I tried to fix it by isolating the change in $Second.A in another passage. In simplified terms, the following is happening:
This produces the same result as in my OP. If <<display is changed to <<goto. this one problem is solved, but that workaround causes a whole host of other issues regarding my story structure. Is there a better solution?
If you want to make copies of simple generic objects, you may use the JavaScript native Object.assign() method. For example: