Updating Object Properties Everywhere

Twine Version: 2.10.0
Sugarcube: 2.37.3

I’m trying to update an object’s properties from one passage and then display those values in another passage. It’s not working. Bill’s strength and agility always remain the same when I go back to the “home” passage. I think this is because each passage creates a new copy of the object in question? What’s the best way to change the value everywhere? Here’s my code.

Passage 1: “home”

<<set $bill = {
	name: "Bill",
	stats: {
    	strength: 8,
        agility: 7,
    	},
}>>

<<set $bob = {
	name: "Bob",
   stats: {
    	strength: 9,
        agility: 6,
    	},
}>>

<<set $sue = {
	name: "Sue",
    stats: {
    	strength: 10,
        agility: 5,
    	},
}>>

<<set $activePlayers to [$bill,$bob,$sue]>>

Bill Strength: $bill.stats.strength
Bill Agility: $bill.stats.agility

<<for _i to 0; _i lt $activePlayers.length; _i++>>
   <<capture _i>>
		 <<link $activePlayers[_i].name>>
         	<<set $target to $activePlayers[_i]>>
            <<set State.variables.target = $target>>
            <<goto "WhichStat">>
         <</link>>
   <</capture>>
<</for>>

Passage 2: “WhichStat”

Choose a stat to increase for $target.name:

<<set _statKeys to Object.keys($target.stats)>>
<<for _i to 0; _i < _statKeys.length; _i++>>
	<<link _statKeys[_i]>>
    <<capture _i>>
        <<set $target.stats[_statKeys[_i]] += 1>>
        <<goto "home">>
    <</capture>>
	<</link>>
<</for>>

You have several problems. First, you set $bill, $bob, and $sue to their default values at the beginning of the home passage. When you navigate back to home, that code will be executed again and reset the variables to their default values. You should move that code to another passage, ideally StoryInit.

The second is more subtle. Variables are cloned on passage transition. This means that if you set $activePlayers to [$bill,$bob,$sue], once you navigate to a new passages $activePlayers will no longer contain references to $bill, $bob, and $sue, but new objects, and similarly with $target. So changing $target in WhichStat won’t change $bill. Instead you can do this:

<<set $activePlayers to ["bill", "bob", "sue"]>>

then use State.variables, like this:

<<for _i to 0; _i lt $activePlayers.length; _i++>>
   <<capture _i>>
		 <<link `State.variables[$activePlayers[_i]].name`>>
         	<<set $target to $activePlayers[_i]>>
            <<goto "WhichStat">>
         <</link>>
   <</capture>>
<</for>>

and

Choose a stat to increase for <<print State.variables[$target].name>>:

<<set _statKeys to Object.keys(State.variables[$target].stats)>>
<<for _i to 0; _i < _statKeys.length; _i++>>
    <<print State.variables[$target].stats[_statKeys[_i]]>>
    <<capture _i>>
	<<link _statKeys[_i]>>
            <<set State.variables[$target].stats[_statKeys[_i]] += 1>>
            <<goto "home">>
	<</link>>
    <</capture>>
<</for>>

You also need to put <<capture>> outside the <<link>> in the second passage.

2 Likes