+3 votes
asked by (370 points)
edited by

I am using Twine 2.1.3, Sugarcube 2.18, and Harlowe 2.0.1! In the old forum, I don't remember or was able to find the Harlowe 2's version of Sugarcube 2's version of meeting the minimum of points for certain events to occur. 

Here is an example of Sugarcube 2's version:

\\ i put this code into a passage called StoryInit
<<set $kiyokoAffection to 0>>

\\ i put this code in a passage that is suppose to increase the stat called kiyoko's affection
<<set $kiyokoAffection to $kiyokoAffection + 5>>

\\ i put this code in a passage where the events happen because of accumulating enough points to trigger an event
<<if $affection gte 75>>
I love you!
<<elseif $affection gte 50>>
I like you.
<<elseif $affection gte 25>>
I don't like you
I dislike you

I was wondering if it was possible to do so with Harlowe 2.

2 Answers

+2 votes
answered by (370 points)

You can more or less do the same thing in harlowe, yes.


Your set functions are more or less identical to sugarcube with a different syntax:

\\ For your StoryInt Passage.
(set: $kiyokoAffection to 0)

\\ For your passage where affection accumulates.
(set: $kiyokoAffection to $kiyokoAffection + 5)


When you come to calling the variable and displaying different text, it works with a slightly different syntax as well. Harlowe uses a system of macros and hooks. Your macro is the (if:), (elseif:) and (else:) commands. The hook is denoted through square brackets. Each macro must have a hook.


The 'gte' is replaced with simple mathematical notation: >, <, =.

(if: $kiyokoAffection is >=75)[I love you!]


However, the 'gte' will not work in this scenario, as it will match a number of lines to being 'true' to the (if:) macro. So, you have to set a range of values, like so:

(elseif: $kiyokoAffection is >=50 and <75)[I like you.]


In the above, we have given the correct hook for the given variable. We don't use '<=75' as the value of 75 would conflict with the two. The rest are like clockwork.

(elseif: $kiyokoAffection is >=25 and <50)[I don't like you.]
(else:)[I dislike you.]


You can alternatively set an if statement for the value after, instead of a simple (else:)

(elseif: $kiyokoAffection is <25)[I dislike you.]


The (elseif:) command wont work unless you've set the variable initially, but since you have, it wont be a problem. If you want it all to be shown on one line so that it doesn't give large gaps in your passage, then it would look like this:

(if: $kiyokoAffection is >=75)[I love you!](elseif: $kiyokoAffection is >=50 and <75)[I like you.](elseif: $kiyokoAffection is >=25 and <50)[I don't like you.](elseif: $kiyokoAffection is <25)[I dislike you.]


Hope this helps.

commented by (60k points)

However, the 'gte' will not work in this scenario, as it will match a number of lines to being 'true' to the (if:) macro.

How do you figure? As long as the if/elseif/else commands are ordered correctly, there's no need to define a range like this. 

(elseif: $kiyokoAffection is >=25 and <50)[I don't like you.]
(else:)[I dislike you.]


You really shouldn't use 'is' with other operators. This will work in harlowe 2.x but return an error in 1.x. Even though 2.x will attempt to fix this error for you, it still isn't recommended. 

Using 'and' without restating the variable or using the 'it' keyword is similar; harlowe 2 tries to work out your intent, but harlowe 1 will show an error. I think it's still generally better to write it out and not rely on the parser to guess correctly, even though harlowe tends to be pretty reliable when the values aren't booleans. 

Finally, I don't believe you mentioned the 'startup' tag, which is (sort of) Harlowe's version of the StoryInit special passage; though I might have just missed it. 

I'm not trying to be pedantic, this is a good answer, I just want to make sure it's as accurate as possible for future readers. 

commented by (370 points)
Sorry, I might have missed a few things. I know harlowe reasonably well enough but I'm not as much of an expert as some.
+1 vote
answered by (137k points)
edited by

Some slight changes/extensions to birdpup's answer.

1. The Harlowe equivalent to the StoryInit special passage is the startup tagged special passage.
Simple create a new passage and give it whatever name you like, then assign it a tag of startup and place the code to initialise your story variables within it like so.

(set: $kiyokoAffection to 0)

2. As explained in the (set:) macro's documentation there are two main syntax's you can use to increase the numerical value of a variable.

(set: $kiyokoAffection to $kiyokoAffection + 5)

(set: $kiyokoAffection to it + 5)

... I prefer to use the second as it requires less typing.

3. If you add the following converted (if:)/(else-if:)/(else:) macro structure

(if: $kiyokoAffection gte 75)[\
I love you!
](else-if: $kiyokoAffection gte 50)[\
I like you.
](else-if: $kiyokoAffection gte 25)[\
I don't like you
I dislike you

 to the Harlowe passage editor it will highlight that there is an issue with the gte keyword, and if you use the Test option to view that passage then the resulting page with include error messages suggesting what the problem with the gte keyword is and how to fix it.

If you follow the error message's suggests you will end up with code like the following, which should function the way you want it to.

(if: $kiyokoAffection >= 75)[\
I love you!
](else-if: $kiyokoAffection >= 50)[\
I like you.
](else-if: $kiyokoAffection >= 25)[\
I don't like you
I dislike you

4. You should not use the is keyword with the mathematical notation comparison operators.

BAD: (if: $kiyokoAffection is >= 75)[I love you!]

GOOD: (if: $kiyokoAffection >= 75)[I love you!]

...while Harlowe 2.x has been modified to support people doing this it is the same as saying that the variable's value must exactly equal 75 while also saying that it must be greater-than-or-equal-to 75 at the same time, and that doesn't make logical sense.

5. You need to restate the variable name when doing multiple comparisons, even if they are on the same variable.

BAD: (elseif: $kiyokoAffection is >= 50 and < 75)[I like you.]

GOOD: (else-if: $kiyokoAffection >= 50 and $kiyokoAffection < 75)
ALSO: (else-if: $kiyokoAffection >= 50 and it < 75)

 ... in the BAD example you are relying on the Harlowe parser to guess what you wanted and it could guess wrong, always tell it exactly what you want. Also there are situations (eg. boolean values) where the guess may seem to work correctly but it will probably be working for the wrong reasons.


6. Use CSS like the following in your Story Stylesheet area to hide any visual output generated by the startup tagged passage.

	display: none;


commented by (370 points)
Thanks for pointing out the changes. Hopefully the original requester will be well informed.


Sorry for my rather backwards/messy harlowe coding.
commented by (370 points)
Sorry for the late reply! I forgot to thank everyone for helping me figure all of this out! Thanks again everyone!
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.