I am trying to create a series of dynamic links in the sidebar based on elements from an array.
So far, as I stumble through learning JavaScript, things have been progressing, however I've hit a bit of a roadblock.
I have succeeded in producing the appropriate sidebar links, however Twine is refusing to acknowledge the existence of passages which do indeed exist. What am I doing wrong?
The link code (in a passage called Recruit which is <<display>>ed in the side bar) is:
<<if $TeamMembers > 0>>\
[[<<$Recruits[0]>>|<<$Recruits[0]>>]]
[[<<$Recruits[1]>>|<<$Recruits[1]>>]]
[[<<$Recruits[2]>>|<<$Recruits[2]>>]]
[[<<$Recruits[3]>>|<<$Recruits[3]>>]]
[[<<$Recruits[4]>>|<<$Recruits[4]>>]]
<<endif>>\
Which works fine in displaying the appropriate text, however it is generating the following error:
[quote]This passage does not exist: Elton Caravaggio
But this passage most certainly does exist as it contains the code line which resulted in "Elton Caravaggio" being pushed into the $Recruits array.
<<if $Recruits.indexOf($Char2.passage) lt 0>>[[Recruit <<$Char2.passage>>|TeamSelection][$Recruits.push($Char2.passage); $TeamMembers += 1]]
Where $Char2.passage is the name of both the Twine passage and the recruit character (in this example, Elton Caravaggio).
The $Recruits array is defined in my Start passage as:
<<set $Recruits = [] >>\
I am using the default Sugarcane format in Twine 1.4.2.
What am I doing that is preventing Twine from recognising a correctly-named passage link? Any help and insight would be greatly appreciated.
Comments
Try this instead:
note:
a. I moved the variable initialization into the StoryInit passage, which is what it is for.
b. I kept your variable names though gave them my own values. I have attached a sample story file containing the above code.
note:
If you were using the SugarCube story format you could use it's <<for>> macro to replace the hardwired <<print>> macros. Your StoryMenu would end up looking something like the following.
Try this: The space in there after the
$Recruits[0]
is required (otherwise the triple closing square-bracket would be ambiguous to the parser).And there's actually no reason, in the code you've shown, to use the link text component, since you're using the same thing for both the link text and passage, so you could simply do this: greyelf's suggestion: Also works, if you prefer that. It also has the advantage of being what you have to do, in cases where you need the $variable to be evaluated early (which isn't required by your current code, but it's something to keep in mind).
Actually. There are two macro shorthand macro syntaxes in the vanilla headers. One calls
<<print>>
, while the other calls<<display>>
. The one used by Freebooted is the<<print>>
calling version. His code was failing because of the reason I outlined above.The
<<print>>
calling version is used when the shorthand identifier starts with the Twine variable sigil, the dollar sign ($). The<<display>>
calling version is used when the shorthand identifier matches the name of an existing passage.The logic goes something like this, as I recall: (pseudo-code)
How silly and confusing. I hope the documentation is clear that the functionality changes based on the context.
So, if you wanted to display the contents of a passage using a variable to indicate which passage, you would have to name the variable without a "$"?
More or less. The wiki page for each,
<<display>>
and<<print>>
, does describe their shorthand forms, however, neither mentions that there's another macro with a similar shorthand form (I'm unsure if there's another wiki page that might). So, that might be a nice addition.IIRC, you cannot do so directly, the current code simply doesn't allow it. You'd have to force the early evaluation of the variable to do so, in which case you're better off simply calling the non-shorthand form of
<<display>>
: Currently, the only time it might make sense to use indirection here is if you wanted to call a pseudo-macro with arguments. For example: Though, I wouldn't expect that need to come up very often (and there are other ways to do it besides).I found amending the syntax of the code in my Recruits passage as per TheMadExile's advice from my original: to Did indeed resolve the problem of the broken link, however it also caused the unpopulated array elements to display, resulting in a series of errors stating that $Recruits[1-4] do not exist (which they wouldn't until further characters were recruited). This didn't happen with the earlier code which couldn't execute the link, but which successfully displayed text from populated elements while ignoring unpopulated ones.
The solution also produces an 'undefined' error for each empty element.
The middle ground which successfully enables the link without unpopulated elements generating errors seems to be: Which means I can now recruit and dismiss team members successfully and display their names in the sidebar without empty team slots producing errors. I'm happy with the results, even if I'm still not entirely clear as to why it works.
Thanks again for all the help, it's very good of you to take the time.
(and thanks to Greyelf for the housekeeping tip regarding StoryInit)
It "works" because the broken links generated by that code, and it does generate broken links, are "invisible" because
<<print>>
emits nothing in the case of anundefined
value. Inspecting the DOM will show the broken links clearly.I didn't realize $Recruits might not contain as many recruits as you're trying to print. Since I now do, I'd probably suggest something like this: Which doesn't emit invisible broken links.
PS: If your
$TeamMembers
variable is simply a count of the team members you currently have and $Recruits only contains recruits (none of the array elements contain empty values of any kind), then you should be able to replace it with$Recruits.length
.My use of $TeamMembers was a bit of a throwback to an earlier version which relied far less on JavaScript. I had been using $Recruits.length elsewhere but had failed to replace $TeamMembers in some instances. Thanks, I've now addressed that too and things are starting to look a lot tidier.