There are a number of ways to track if something has occurred during the play-though of a project, one of the simplest is to use a Boolean variable.
1: Use the (set:)
macro to initialise the Boolean variable to its default state.
(Generally done within your project’s startup tagged Passage.)
(set: $hasLamp to false)
2: Update the current state of the Boolean variable then the “thing” has occurred.
(link: "Get Lamp")[(set: $hasLamp to true)]
3: Use one of the (if:)
family of macros to conditionally do something based on the current true or false state of the Boolean variable.
<!-- To check for true -->
(if: $hasLamp)[You see the contents of the room.]
<!-- To check for false -->
(unless: $hasLamp)[It is too dark to see!]
(if: not $hasLamp)[It is too dark to see!]
In the use-case where you want to do one of two possible things you would use a structure like the following…
(if: $hasLamp)[You see the contents of the room.]
(else:)[It is too dark to see!]
The validation of end-user input is a little more complex, especially within Harlowe which allows limited usage of JavaScript to force the end-user to enter a correct data-type.
Harlowe has two basic methods for allowing the end-user to enter a value:
1: The (prompt:)
macro.
Which delays the execution of any Passage content that proceeds the (prompt:)
macro until the end-user has interacted with the shown dialog, thus making it easier for that proceeding content to make use of the entered value.
(set: $code to (prompt: "Your code, please:", "", "Cancel", "Confirm"))
code: $code
valid: (if: $code is "abcde")[yes](else:)[no]
However there are a couple of issues with the above example:
- There is no way to force the end-user to actually enter a value.
eg. resulting in code equalling an Empty String (""
).
- The end-user may use letter casing different to what you expect.
eg. "AbcDE"
instead of "abcde"
- The end-user may include SPACE characters where you weren’t expecting them.
eg. " abcbe" or "abcde " or " abcde "
So you may need to “clean” the entered value, using macros like (trimmed:)
and (lowercase:)
, before you can make use of it.
(set: $code to (prompt: "Your code, please:", "", "Cancel", "Confirm"))
(if: $code is not "")[
(set: $code to (lowercase: (trimmed: $code)))
]
debug info:
code: $code
valid: (if: $code is "abcde")[yes](else:)[no]
2: The (input-box:)
macro.
Which does NOT delay the execution of any Passage content that proceeds the (input-box:)
macro so you need to find some means to introduce such a delay, like using one of the (link:)
family of macros.
notes: This input method has the same potential invalid data issues as the 1st, so you likely will need to “clean” that data. I’m making use of a Named Hook and (rerun:)
macro combination to allow for the dynamic updating of the “debug” information, which you likely won’t need in your implementation.
(input-box: bind $code, "X=", 1, "")
(link-repeat: "Check Code")[{
(if: $code is not "")[
(set: $code to (lowercase: (trimmed: $code)))
]
(rerun: ?debug)
}]
|debug>[
code: $code
valid: (if: $code is "abcde")[yes](else:)[no]
]