0 votes
by (270 points)


I am trying to build a character creation system, where the player can navigate several options of a specific trait with left and right arrows to choose the right option, something like.

Choose your hobby:   Swimming <  >

And the player can click "<" and ">" to navigate the options.

I am trying to implement like this (newbie here :))

1) In a passage tagged with "startup" I've created an array and a variable to traverse the array:

(set: $hobby to (array: "Swimming", "Football", "Stamp collector"))
(set: $i = 0)

2) Then, I've created a passage with the following code:

|hobby>[(print: $hobby[$i])] |nav>[(display: "Nav")]

 3) And in the "Nav" passage, I've started by placing the following, which works as long as you stay inside the limits of the array (not very useful, of course :))

(link-repeat: "< ")[(set: $i to it - 1)(replace: ?hobby)[(text: $hobby[$i])]]
(link-repeat: " >")[(set: $i to $i + 1)(replace: ?hobby)[(text: $hobby[$i])]]

4) To make the navigation limited to the size of the array, I was thinking about something like this, but, alas, it doesn't work (this is the code just for the left arrow)

(link-repeat: "< ")[(if: $i == 0)[(set: $i to $hobby's length - 1)](else:)[(set: $i to it - 1)](replace: ?hobby)[(text: $hobby[$i])]]

So the idea is to check the value of the index variable each time there is a click in an arrow. For the left arrow case, if $i is equal to 0, it should change to the last value of the array. If it's not 0, then it should decrease and move towards the beginning of the array.

But when I run the code, the passage starts fine showing element[0] of the array, but when I click on the left arrow I get this error: 

☕ Cannot read property 'varref' of undefined►There's nothing before this to do (else:) with.►

I don't really understand why this is happening. I would really appreciate your help!



1 Answer

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

WARNING: You are currently using Javascript Array element access syntax (eg. $variable[$index] ) to reference content stored within your $hobby story variable, and that is undocumented behaviour which could change/disappear in future releases of Harlowe 2. The documented syntax for accessing an element using an expression (like $index) is:

$variable's ($index)


The following is a modified version of your example.

1. Your startup tagged special passage.
I change the initial value to 1 because Harlowe Arrays are one-based.

(set: $hobby to (array: "Swimming", "Football", "Stamp collector"))
(set: $i to 1)

2. The passage to display the hobby selection in.
I corrected the element access syntax and removed the currently unnecessary named hook. 

|hobby>[(print: $hobby's ($i))] (display: "Nav")

3. The Nav passage.
I corrected the element access syntax, adjusted the base of array index, replaced the (text:) macro with the (print:) macro, and added Collapsing whitespace markup to the associated hooks of the link macros so that they don't add unwanted line-breaks when they are selected.

(link-repeat: "< ")[{
	(if: $i > 1)[(set: $i to it - 1)]
	(else:)[(set: $i to $hobby's length)]
	(replace: ?hobby)[(print: $hobby's ($i))]

(link-repeat: " >")[{
	(if: $i is $hobby's length)[(set: $i to 1)]
	(else:)[(set: $i to $i + 1)]
	(replace: ?hobby)[(print: $hobby's ($i))]


NOTE: Based on your examples it appears that you have a tendency to intermix Harlowe assignment / comparison operators (like to and is) with mathematical assignment / comparison operators (like = and ==) which can make the code slightly harder to read, also using mathematical assignment / comparison operators can lead to using assignment when you actually wanted comparison.

WANTED: (if: $variable == "value")[]

WROTE: (if: $variable = "value")[]


by (270 points)
It works perfectly. Thank you so much for the thorough explanations and corrections. A really great Twine lesson, Greyelf :)