Howdy, Stranger!

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

Help using recursive loop with (datanames:) and (datavalues:) to browse a (datamap:) in Harlowe

Hello! I'm trying to use a recursive loop to make a way for the player to explore a datamap which will collect all the knowledge they've gained about the world. So, for example, I'd initialise the datamap with something like this:
(set: $knowledge to (datamap:
"people", (datamap:),
"world", (datamap:),
"history", (datamap:),
))

(set: "people" of $knowledge to it + (datamap:
"Traveller's Friend", "A woman wrapped in winding sheets who brought you to this place",
"Arbiter", "Those whose rigid governance maintains the order upon which your old life was built"

))

And then in the story, you could browse it using something like this:
People:
(print: (datanames: "people" of $knowledge).join("
")) 
(set: $peopleNumber to (datanames: ("people" of $knowledge))'s length)
(set: $i to 0)
(display: "PeopleKnowledgeLooper")

with the PeopleKnowledgeLooper page looking like this:
(if: $i < $peopleNumber)[
(clickappend: (string: (datanames:"people" of $knowledge)[$i]))[(print: " - " + (string:(datavalues: "people" of $knowledge)[$i]))]
(set:$i to it + 1)(display: "PeopleKnowledgeLooper")]

My desired endpoint would be a system where all the names of the characters you have met are displayed in a list as links, and when you click on them they are appended with whatever you know about them. At the moment, clicking on the names only appends them with " - ", but the string from the (datavalues:) macro comes out blank and empty, and I can't quite see why that should be happening. The code works fine when I drop a static value in instead of my iterator variable, and even when I use $i to iterate through the loop the code inside the (clickappend:) macro works fine (the names become links). The problem is with the code inside the hook, but as that code is practically identical then I can't see where I'm going wrong. Any advice appreciated!

Thanks,

Ed

Comments

  • There are three main issues with your example, two of them you have already seen the effects of and the third you will notice once you add a couple of more items to your collection.

    1. Harlowe does not support Javascript's Array element syntax. eg. $array[index]

    You will need to use it's own $array's (index) syntax instead.

    2. A variable referenced with the associated hook of macro's like (click:) is not evaluated until after the link is clicked, so the variable's value will be whatever it equals now not what it equalled at the time the link was generated.

    eg. The value of the $i variable within each of the (clickappend:) associated hooks will be whatever it equals at the end of the looping code, which is 2 in your example.

    One way to resolve this issue is to use a (print:) macro to dynamically generate the (click-append:)
    (print: '(click-append: "the text")[current value of i is: ' + (text: $i) + ']')
    


    3. As explained here the variation of passage recursion you are using to simulate looping will result in a web-browser nesting error once you add a couple of more items. There is another variation of passage recursion that does not have the same issue.

    a. Example of generic code used to setup and start the loop.
    (set: $index to 0)
    (set: $length to 10)
    [(display: "Loop Logic")]<loop|
    

    b. Example of generic Loop Logic passage.
    (if: $index < $length)[
    .... Do something .....
    (set: $index to it + 1)
    (replace: ?loop)[(display: "Loop Logic")]
    ]
    


    Based on the above the second and third passages in your example would look something like the following:

    a. And then in the story, you could browse it using something like this:
    People:
    (print: (datanames: "people" of $knowledge).join("
    "))
    
    (set: $peopleNumber to (datanames: ("people" of $knowledge))'s length)\
    (set: $i to 0)\
    the text
    (print: '(click-append: "the text")[current value of i is: ' + (text: $i) + ']')
    [(display: "PeopleKnowledgeLooper")]<loop|
    

    b. with the PeopleKnowledgeLooper page looking like this:
    (if: $i < $peopleNumber)[\
    (set: $name to (datanames: "people" of $knowledge)'s ($i))\
    (set: $value to $knowledge's ("people")'s ($name))\
    (set: $link to '(clickappend: "' + $name + '")[ - ' + $value + ']')\
    (print: $link)\
    (set: $i to it + 1)\
    (replace: ?loop)[(display: "PeopleKnowledgeLooper")]\
    ]
    
  • Hey, that's wonderful! Sorry it's taken me such a long time to reply. Very grateful. I'll try and implement this later. Thanks again for the considered reply!
  • This works perfectly. I'm simply bowled over by your generosity in this response. We'll certainly credit you in the finished game. Thank you so much!
Sign In or Register to comment.