“Freezing” value of a variable

Twine Version: 2.10.0
Sugarcube: 2.37.3

I have a variable stored as part of a string. I’d like to set the variable, print the string in one place on the passage, then change the value, refresh the passage, and print it in another place. The problem is, doing this changes the value in the first place too.

Is there a way to “freeze” the first string with the variable’s initial value while printing the second string with the new value?

/*StoryInit*/
<<set $players to ["bob","jill"]>>
<<set $direction to "">>
<<set $bob = {
	name: "Bob",
	moveDescription: "",
}>>

<<set $jill = {
	name: "Jill",
	moveDescription: "",
}>>

<<set $walk = {
	name: "Walk",
    description: "You walk $direction.",
}>>
/*home*/
<<for _i to 0; _i lt $players.length; _i++>>
<<capture _i>>
<<set $name to State.variables[$players[_i]].name>>
<<= $name>>

<<button "Go West">>
	<<set $direction to "west">>
    <<set State.variables[$players[_i]].moveDescription to $walk.description>>
	<<goto "home">>
<</button>>

<<button "Go East">>
	<<set $direction to "east">>
    <<set State.variables[$players[_i]].moveDescription to $walk.description>>
	<<goto "home">>
<</button>>
<</capture>>

<<= State.variables[$players[_i]].name>> Move: <<= State.variables[$players[_i]].moveDescription>>

<</for>>



In this example, I want to be able to click “Go West” on Bob’s button and update his description to “You walk west.” Then I want to click “Go East” on Jill’s button and update her description to “You go east.” while leaving Bob’s as “You go west.”

Could you share the current code you have?

Sure. I’ve updated the question with my code.

You can set the variable like this:

<<set State.variables[$players[_i]].moveDescription to "You walk "+$direction+".">>

Thank you, but that doesn’t work for what I have in mind. I’d like to store the full description in the “walk” object for flexibility. I’m planning more moves that have slightly different grammatical constructions. For example, sometimes it will say “You walk $direction” and sometimes it will say “You run $direction at full speed.”

You could have an array in $walk.description like:

<<set $walk to {
     description: ["Variation 1", "Variation 2", ...]
}>>

Then in the button:

<<set $players[_i].moveDescription to either $walk.description>>

(that will make it random between all descriptions)

<<set State.variables[$players[_i]].moveDescription to $walk.description[1]>>

(1 or a different number if you want something specific)

You could also do it as a function:

<<set $walk = {
    name: "Walk",
    description: function(){ return "You walk "+$direction+"." },
}>>

and then

<<set State.variables[$players[_i]].moveDescription to $walk.description()>>

Perfect. Thank you!

@Prunesquallor and @svlin

Take care when adding functions as properties of a Generic Object, as under some conditions they may not survive the serialisation process that SugarCube uses when creating a Save.

see: the Non-generic object types guide in the SugarCube documentation.

1 Like