0 votes
by (2.4k points)

Short version:

I'm trying to use a <<set>> macro inside a <<link>> block for updating the value of a pre-existing variable, but its value is not updated until I advance to the next passage. How can I force the variable to update right after clicking the link?

 

Long version:

I'm trying to make a somewhat interactive passage where you can talk with another character, choosing different options and such. For this I'm using lists of <<link>> macros with <<addclass>> and <<removeclass>> for hidding or showing different <div> blocks so the passage content updates as the conversation goes on. This works fine, but of course if the player saves and load the game in the mid of the conversation the passage goes back to its first state. So I thought of using a variable to track wich options where chosen in each part of the conversation and the check it in PassageDone to update the passage.

In the game passage:

<div id="000a_choices" class="choices">\
  <ul>\
    <li><<link "Choice 1">>\
      <<set $state_000a to 1>>\
      <<addclass "#000a_choices" "hidden">>\
      <<removeclass "#000a_choice1" "hidden">>\
    <</link>></li>
    <li><<link "Choice 2">>\
      <<set $state_000a to 2>>\
      <<addclass "#000a_choices" "hidden">>\
      <<removeclass "#000a_choice2" "hidden">>\
    <</link>></li>
  </ul>\
</div>\
<div id="000a_choice1" class="hidden">\
  <p>This is the Choice 1</p>
  [[Next1]]
</div>\
<div id="000a_choice2" class="hidden">\
  <p>This is the Choice 2</p>
  [[Next2]]
</div>\

In PassageDone:

<<switch passage()>>
  <<case "000a">>
    <<switch $state_000a>>
      <<case 1>>
        <<addclass "#000a_choices" "hidden">>\
        <<removeclass "#000a_choice1" "hidden">>\
      <<case 2>>
        <<addclass "#000a_choices" "hidden">>\
        <<removeclass "#000a_choice2" "hidden">>\
      <</switch>>
<</switch>>

The hidding/showing part in the game passage works fine, the problem is when saving after chosing an option the $state_000a variable is not properly saved and still shows its previous value, so when reloading the game PasageDone doesn't work. However, when going to the Next passage, the variable is properly updated.

Does anyone know how to make <<set>> update the value of the variable properly? Thanks!

1 Answer

+1 vote
by (156k points)
selected by
 
Best answer

The History system is only updated during the Passage Transition process, and a Save is basically a copy of the current state of the History system at the time that the save was created.

This means that any changes you make to the value of a story variable within the current passage, either directly within the passage or as a result of interactions made by the end-user, are not persisted to the History system (or storable within a Save) until the next Passage Transition occurs.

So the <<set>> macro is updating the current value of the story variable as expected.

If you want the updated value of $state_000a to be storage within a Save then the simplest way to achieve that outcome is to change your Choice links to something like the following which will result in the History system being updated.
(untested code)

<<link "Choice 1" `passage()`>>
	<<set $state_000a to 1>>
<</link>>

<<link "Choice 2" `passage()`>>
	<<set $state_000a to 2>>
<</link>>

 

by (2.4k points)
Thanks a lot, now it works fine. I've only needed to change the 'passage()' part of your <<link>> macros to the actual passage name, otherwise it kept looking for a passage named "passage()".

The only "problem" now is that it uses the passage changing transition when using the link insteand of being smooth like before, but that is a minor thing.

Thanks again!
by (156k points)

@Ralkai Shagtten
If you look closely you will notice that the quote type I used to wrap the passage() function calls in was a back-quote, and not a single quote.

As explained in the Macro Arguments section of the documentation, back-quote expressions are used when you need to execute code (like the passage() function) to obtain a value you wish to use as an argument for a macro.

by (580 points)
The Sugarcube documentation is not very clear about

<<link "do something" `passage()`>><<set $variable to [whatever]>><</link>>

It's an incredibly useful statement and no effort seems to be made to draw attention to those back quotes.
Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...