0 votes
by (150 points)
edited by

Hey, I started using Twine yesterday and I'm navigating Harlowe 1.2.4 and playing around with the code.

My aim is as follows. I am trying to obtain two different very simple endings to a "Santa checks on you" game, with text that displays conditionally depending on a variable, like so:

(if: $nice is >= 2)[Santa brings you presents.]
(if: $naughty is >= 2)[Santa brings you coal.]
[[Restart|Main]]

In my main passage I set the $nice and $naughty variables like so:

Santa is checking on you. 
(set: $nice to 0)
(set: $naughty to 0)
[[start|Check 1]]

Since I'm testing, I kept the choices that should make the variables grow extremely simple:

Check 1
[(set: $nice = $nice + 1)[[I've been nice|Check 2]] ]
[(set: $naughty = $naughty + 1)[[I've been naughty|Check 2]] ]

What I am trying to accomplish is making these two variables grow on click, i.e. when the player chooses whether they've been nice or naughty. What is happening instead is that the variables grow +1 immediately on passage opening. For example, in the above passage "Check 1", both stats are already at 1, while what I want is to have them at 0 and grow +1 when either option is clicked, so that in passage "Check 2" either $nice or $naughty will be at 1 and the other at 0.

Additionally, what happens when I proceed to the next passage is that $nice automatically sets at 2, while $naughty automatically sets at 3, no matter which option is clicked in "Check 1". This continues also for "Check 3", and when the test game is wrapped up it inevitably displays both conditional endings (given that $nice is invariably set at 3 and $naughty at 4).

Is it possible to make the game behave as I want it to with a different use of macros or whatever else?

 

1 Answer

0 votes
by (159k points)
selected by
 
Best answer

First some comments about your example:

1. The v1.2.4 version of Harlowe is no longer being developed and is only included with the Twine 2.x application so that older Projects or Story HTML files that were written using the 1.x series of Harlowe can be imported successfully.

I strongly suggest changing to the 2.x series (or maybe even the 3.x series when it is publically release) if you plan to use Harlowe for a new project.

2. Initialisation of story variables should ideally be done within your Harlowe project's startup tagged special passage, because that special passage is automatically processed before the first passage of your project is shown to the Reader.

3. When calling one of the conditional checking macros (like the (if:) macro) you shouldn't use the is operator if you are also using a mathematical comparision operator like >= or <=

<!-- GOOD comparison syntax. -->
(if: $number >= 12)[...]
(unless: $number < 6)[...]

<!-- BAD comparison syntax. -->
(if: $number is >= 12)[...]
(unless: $number is < 6)[...]

reason: The is operator represents the === (exactly equal to) mathematical comparision operator, so when you write something like $number is >= 12 you are writing the equivilent of $number === >= 12, which is stating that the current value of $number needs be both "exactly equal to" 12 and "greater than or equal to" 12 and that doesn't make sense mathematically.

The Harlowe TwineScript parser notices this contradiction and tries to resolve it by changing the original expression to $number >= 12 internally, but it is better if you do that yourself in your passage.

4. You used both the to operator and the = (equals) operation in your (set:) macros, you should try to be consisted with which assignment operator you are using.

I would suggest using the to operator, because a single equals sign = operator (which means assigment) is very easy to confuse with the double == (equal to) and triple === (exactly equal to) equal sign operators which can be potentually used for comparision.

5. When using a (set:) macro to increase or decrease a numerical value I suggest you use the special it reference in replace of the second instance of the variable name, this can reduce the risk of misspelling the second instance as well as reduces the typing needed.

(set: $number to it + 1)

is the same as

(set: $number to $number + 1)


6. You were trying to create what is commonly known as a Setter Link or a Link with Setter, which you do in Harlowe by combining a (link:) macro with a (set:) macro and a (go-to:) macro like so.

(link: "Link Text")[
	(set: $variable to "a value")
	(go-to: "Target Passage Name")
]


7. If I understand correctly only one of the two possible messages within the Check 2 passage should even be displayed to the Reader, which means that those two conditions are mutually exclusive. To achive that using (if:) related macros you need to change the second (or later) macro into either an (else-if:) macro or an (else:) macro depending on the exact circumstances.

(if: $number >= 10)[The number is "greater or equal to" ten]
(else-if: $number > 5)[The number is between five and nine (inclusive)]
(else:)[The number is less than 5]

or

(if: $nice >= 2)[Nice is "greater or equal to" two]
(else-if: $naughty >= 2)[Naughty is "greater or equal to" two]
(else:)[Neither Nice or Naughty is "greater or equal to" two]


Now on to the actual answer to your question...

1. Initialise your variables within your project's startup tagged special passage.

(set: $nice to 0)
(set: $naughty to 0)


2. Place the following in your Main passage.

Santa is checking on you.
[[Start|Check 1]]


3. Use Setter Links like the following in your Check 1 passage.

(link: "I've been nice")[
	(set: $nice to it + 1)
	(go-to: "Check 2")
]
(link: "I've been naughty")[
	(set: $naughty to it + 1)
	(go-to: "Check 2")
]


4. Use a series of condition checking macros like the following in your Check 2 passage.

(if: $nice >= 2)[Santa brings you presents.]\
(else-if: $naughty >= 2)[Santa brings you coal.]\
(else:)[Santa is still checking you.

[[Continue|Check 1]]
]

[[Restart|Main]]

You may notice I added an (else:) macro to your original example, this is because it was possible for both $nice and $naughty to be less than 2 at the same time, which means no message would of been displayed to the Reader.

by (150 points)
Thank you, this was very exhaustive and it certainly solved my issue.

My Check 2 is essentially the exact same thing as Check 1, simply building up the variables. Ideally, once reaching the Christmas passage, you've been forced to click on the $nice or $naughty link a maximum of three times to proceed to the final passage, having at maximum a 3 value on one variable and a 0 value on the other, and at minimum a 2 value on one and a 1 value on the other.

After using the (link:) macro + (set:) and (goto:) my counter behaves as expected, but thank you for the (else:) example too.
...