Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Loop bug? Twine uses last increment value?

I'm making a Stone Age tribe game, and you can send out a number tribespeople from the current population to do different tasks. Each link is supposed show a number (1 to 10) and when clicked, set $hunters to the value shown, and subtract that from $availPop. In my original passage I have:
<<set $huntLoop to 1>>\
<<set $availPop to 10>>\

<<huntLinks>>
Then, in my "huntLinks" passage, I have:
<<if $huntLoop <= $availPop >>\
[[<<$huntLoop>>|hunt][$hunters = $huntLoop; $availPop -= $huntLoop]]
<<set $huntLoop += 1>>\
<<huntLinks>>
<<endif>>\
It prints a list of links that are numbers 1 to 10 as I intended. However, it seems Twine throws whatever the last value of $huntLoop was into the expressions for EVERY link. ALL of the links set $hunters to 11, and $availPop to -1...

I've run into this problem before, before setter links existed in Twine. I'm guessing L knows exactly why Twine does this -- any workarounds, or bug fixes?

Comments

  • My guess would be that the link args are evaluated when the link is clicked, not when the passage is prepared for showing. All Twine variables are global, so I don't see a way to save the value there. JavaScript has local variables, but in JavaScript I wouldn't know how to create a link to another passage.

    SugarCube doesn't even show the links; it seems to perform the recursion twice, the first time without generating output. Therefore the second time the iteration variable is already past the end and the recursion ends immediately.
  • mth wrote:
    My guess would be that the link args are evaluated when the link is clicked, not when the passage is prepared for showing. All Twine variables are global, so I don't see a way to save the value there.


    Correct.  The set component of the link syntax happens on click, not at the moment of creation.


    mth wrote:
    SugarCube doesn't even show the links; it seems to perform the recursion twice, the first time without generating output. Therefore the second time the iteration variable is already past the end and the recursion ends immediately.


    The links show fine for me.  I assume you probably had a syntax problem.
  • TheMadExile wrote:

    mth wrote:
    My guess would be that the link args are evaluated when the link is clicked, not when the passage is prepared for showing. All Twine variables are global, so I don't see a way to save the value there.


    Correct.  The set component of the link syntax happens on click, not at the moment of creation.


    Do you know an easy way to capture the iterator's value, to create a kind of closure in Twine? Or a simple way to create links in JavaScript, which does support closures?

    TheMadExile wrote:

    mth wrote:
    SugarCube doesn't even show the links; it seems to perform the recursion twice, the first time without generating output. Therefore the second time the iteration variable is already past the end and the recursion ends immediately.


    The links show fine for me.  I assume you probably had a syntax problem.


    Indeed: I copy-pasted Strangelander's code and the <<$huntLoop>> syntax works in SugarCane but doesn't work in SugarCube. However, I didn't get any feedback on this error: no red text, no alert box, nothing on the JavaScript console log.
  • mth wrote:

    Do you know an easy way to capture the iterator's value, to create a kind of closure in Twine? Or a simple way to create links in JavaScript, which does support closures?


    The only easy way to capture the value of $huntLoop at the specific moment when the link is created, while still only assigning it to $hunters and $availPop upon click, is to evaluate it when you create the link.

    So, while not pretty, this should work: (assuming I'm understanding what he's trying to do here)

    <<print "[[<<" + $huntLoop + ">>|hunt][$hunters = " + $huntLoop + "; $availPop -= " + $huntLoop + "]]">>

    mth wrote:

    Indeed: I copy-pasted Strangelander's code and the <<$huntLoop>> syntax works in SugarCane but doesn't work in SugarCube. However, I didn't get any feedback on this error: no red text, no alert box, nothing on the JavaScript console log.


    Hmm.  The links are created just fine, there's simply no link text for them.  Odd.  I would have expected to see something like a literal "<<$huntLoop>>".  I'll have to look into it, but off the top of my head it's probably seeing the variable sigil and trying to get the value based on "<<$huntLoop>>", rather than simply displaying it since it's not a $variable.
  • Twine takes the first set of >> as closing the print macro, and shows the rest of the code in the story itself.
    <<print "[[<<" + $huntLoop + ">>|hunt][$hunters = " + $huntLoop + "; $availPop -= " + $huntLoop + "]]">>

    Any way to escape those >> characters or something? Backslash doesn't work, apparently.

    EDIT: the solution is to just get rid of the inner angle brackets altogether:
    <<print "[[" + $huntLoop + "|hunt][$hunters = " + $huntLoop + "; $availPop -= " + $huntLoop + "]]">>

    Thank you, that helped a lot, and knowing you can use quotes and pluses to concat stuff is great.
  • The <<print>> approach without the internal "<<" works for me. Thanks!
    (I was looking for a similar mechanism for my "23" game.)
  • Ah, yeah, sorry about that.  I forgot that the vanilla headers don't parse quoted closing angle-brackets properly.
Sign In or Register to comment.