Showing a link if a passage has NOT been visited

Twine 2.3.5
Harlowe 3.1.0

I want to have a “hub” page, which shows links to the places the player hasn’t been to yet, but I’m having trouble getting Twine to understand what I mean.

The manual says: " (history:) contains “Cellar”` is true if the player has visited a passage called “Cellar” at some point."

So I should be able to invert that value, yes?

But


::station

The international train station has many interesting destinations.


(if: not (history: contains "Paris"))[
	(link-goto: "Go to Paris", "Paris")
]

<!-- produces the error "the number 0 cannot contain any values, let alone the string "Paris" " --!>



not (history: contains "London"))[
	(link-goto: "Go to London", "London")
]

<!-- produces the error "the number 0 cannot contain any values, let alone the string "London"►" --!>


(history: not contains "Hamburg"))[
	(link-goto: "Go to Hamburg", "Hamburg")
]


<!-- produces the error "I can only use 'not' to invert booleans, not an empty variable."  --!> 

So how, exactly should I phrase this?

I notice that the manual says it returns an “array”, so perhaps I’m going about this entirely the wrong way, but the entry on using the (history:) macro specifically says that it’s designed to obviate the need to use flags to detect whether a player has seen a passage, and flags are boolean. Surely I should be able to test whether OR NOT the player has seen a passage?

I’m confused.

BTW, I’m also suspicious of the code fragment in the manual. It doesn’t seem to be the standard Harlowe format of a macro in () with the tail tagged on with [ ].

The (history:) macro returns an array of passage names and its sole, optional, argument is a lamda that can be used for filtering the array.

As far the examples in the docs, many macros do not have an associated hook, so that’s not unusual.

Try something like the following:

<!-- Using (if: not).  Note the extra parenthesis. -->
(if: not ((history:) contains "Paris"))[
	(link-goto: "Go to Paris", "Paris")
]

<!-- Or, using (unless:). -->
(unless: (history:) contains "Paris")[
	(link-goto: "Go to Paris", "Paris")
]

EDIT: Fixed (if:) example, added (unless:) example.

1 Like

Unfortunately

(if: not (history:) contains "Paris")[
	(link-goto: "Go to Paris", "Paris")
]

only gets me the error: “I can only use ‘not’ to invert booleans, not an array.”

It says it’s returning the array (a:), but I’ve tried testing if the result of the array is equal to (a:) but that didn’t work either.

This doesn’t produce any errors:

(if: (history:) contains "London")[](else:)[
	(link-goto: "Go to London", "London")
]

But produces a broken (red, un-clickable) link.

(unless: (history:) contains "Paris")[
	(link-goto: "Go to Paris", "Paris")
]

Likewise produces no errors, but the link is red/broken and un-clickable.

Harlowe might require parenthesis around the array check—I’d have to test. That said, you can simply use the (unless:) macro instead of (if:) to invert the test.

For example:

(unless: (history:) contains "Paris")[
	(link-goto: "Go to Paris", "Paris")
]

EDIT: After testing. Yes, Harlowe does require parenthesis around the array check when negating the result with not. For example:

(if: not ((history:) contains "Paris"))[
	(link-goto: "Go to Paris", "Paris")
]

If you’ve actually created those passages, then I’d ensure that you don’t have whitespace around the name of the passages themselves as that will cause the issue you’re seeing.

Sorry, should have said: yes, I’ve created those daughter passages, and I’ve checked that capitalization and whitespace are not the issues. (Created 'em by copy-pasting to be sure.)

I’m stumped. Yet this is obviously such a useful storytelling tool that I can’t believe Twine won’t do it. I guess I’ll just have to say “screw it” and create a truckload of flags after all. Sigh.

Thanks for your help, buddy.

Do you have an archive or compiled file we could see?

I am officially an idiot. I had those passages named “Go to Paris” instead of “Paris” :laughing: :rofl:

Thanks, your “unless” code works! I will tick the “solution” box. Thanks a million!

(And I think the example of how to use “not” will be useful too.)