It's come up a
couple different
times in the forum, but there's not been a super-simple example of basic
loops in Twine.
Loops are basic fundamental programming and can be used for many, many different things in Twine. I'll leave their use to your imagination.
In Twine, loops are passages. To run a loop, you display a loop passage. In versions of Twine earlier than 1.4, or for passages with titles of more than one word, passages are displayed like this:
<<display 'Passage Name'>>
In Twine 1.4+ for passages with single-word titles, we can simply do this:
<<Passage>>
Part of what makes a loop passage a loop is that it displays itself. It "loops" from its end back to its beginning over and over.
For example:
[quote]
Passage<<Passage>>
As can probably be guessed, displaying Passage inside Passage will cause an infinite loop in a "hall of mirrors." Eventually, it will crash with the error, "Too much recursion."
So, we need to add a counter so that it displays itself only as many times we want it to do so.
Let's take a look at how to do that.
[quote]
Start<<loop>>
We're done!
Again, "<<loop>>" is not a predefined macro. It is the name of a passage. It can be whatever you want to name the passage that executes the loop. It will work the same if <<display 'loop'>> is used.
Now, let's look at the passage titled "loop."
[quote]
loop <<if $i lt 10>>
Hello!
<<set $i = $i + 1>>
<<loop>>
<<else>>
<<set $i = 0>>
<<endif>>
First of all, in Twine 1.4+, all variables are set to '0' by default. So, since we have not set $i, its value is '0.'
When the loop begins, the if conditional branch checks to see if the generic variable $i is less than 10. You can set the number higher or lower, but it will continue to "loop" until the variable reaches that number.
At first, the variable is 0, which is less than 10, so it will execute the code. In this case, the code is "Hello!<<set $i = $i + 1>><<loop>>" so it will print "Hello!" on the screen, then increase the generic variable, $i, by 1. Then, it will display the "loop" passage again from the top.
The "loop" passage will display ten times, thus printing "Hello!" ten times and increasing $i by 1 each time.
At that point, the if conditional branch will return false, because $i is equal to 10 and thus not less than 10. The passage will then set $i back to '0' (that's the "<<else>><<set $i = 0>><<endif>>" code) so the loop can be ran again if needed.
Of course, if you change "<<if $i lt 10>>" to "<<if $i lt 20>>", it will print "Hello!" 20 times.
That's it! Pretty simple, basic stuff, but it can be used for powerful effects.

Attached is an example TWS and HTML file.
Hope this helps someone!
Comments
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?
<<while CONDITION>>
the looped code
<<endwhile>>
Secondly, I know I should be able to figure this out myself, but I'm having trouble wrapping my head around it. At various points in my game I want to set a variable to a value from an array (I figured that part out! :P), and then loop until that value doesn't match either value chosen the last 2 times this happened. I think I need to store a variable for the last one and the one before and check the current one against them in a loop, just struggling to actually code it.
Hope this makes sense, it's 3:20am here and I'm a little fuzzy.
Right now, I don't have time to give you a full answer, but remember there is "neq", meaning "not equal to."
So, "do this until $a is neq $b or $c". Something like that should get you going.
If not, I'll be around tonight.
In my StoryInit (in Sugarcube, or Start in Sugarcane) passage: Then in my CheeseTime passage: And in the ChooseCheese passage:
No! "do this until $a is neq $b or $a is neq $c"
In my opinion the best way to loop in Twine is in JavaScript.
An alternative CheeseTime: Or do it as a macro in a script passage (but note all these variables are local to the script: