(Harlowe Tech Issue) Live Number Inside a Click-Append Breaks Other Clicks

Twine Version: 2.5.1
Story Format: Harlowe 3.3.3

Hey everyone. Just started using Twine this week and thought I’d try a silly little story to test what I’ve been learning. But I’ve come across a weird issue when trying to create a Live number inside of a Click-Append.

Issue:
I left the code in the passage as is, but the part I’m struggling with is the Click-Append “watch”. The number currently updates live as intended, but if the reader clicks on the “watch” first, all other Clicks break. (Note: the “Nah, I’m Good” works fine.) The image below is a screenshot of what happens. All circled links are suddenly white and do not work.

Testing:
The best solution I’ve found so far is to assign a second or millisecond value to the Live macro immediately before my $time variable. The problem there is, it causes the other Clicks to flash every time the Live macro triggers, or if I assign it the same second value as the Set macro that increases my $time variable, it might not be there when the reader first clicks on it. (It also still flashes all Clicks, which I’m guessing just isn’t avoidable.)

Any ideas? I’ll take any help I can get, though I would prefer to avoid JavaScript for now. Thanks in advance for your time and efforts.

Code:

It's a warm starry night as you walk up the steps to the restaraunt.

While it *is* your first time here, you've received a personal recommendation from a trusted friend, so you have at least some hope that this won't be a terrible experience.

As you stand before the door, you ask yourself if there's any last things you should check.

Your watch?
Your tie?
Your zipper?

(link-reveal-goto: "*Nah, I'm good.*", "Entrance") [(set:$conf to it + 1) (set: $noun to "person"))]

(click-append: "restaraunt") [ (text-colour:grey)[(a fine establishment, with a brick facade and wide glass widows which are warmly lit from the overhead lamps inside)]]

(set: $time to 55)
(click-append: "watch?") [ It's 8:(live:) [$time]{(live: 15s) [(set: $time to it + 1)]} right now. The event starts at 9:00.] 

(click-append: "tie?") [ It's a little loose. You could tighten it if you want to.] 

(click: "tighten") [(set: $cool to it + -1, $smart to it + 1)]

(click-append: "zipper?") [ It was down?! You quickly fix it. Thank goodness!]

Welcome FoxyBeard,

I don’t know why it does not work. However it looks like you expect an increase of the minutes each time the reader clicks on the “watch”, “tie”, “tighten” or “zipper” links.

I offer this solution, based on three things different of what you tried. First, I got rid of every (live:) macro you tried.
Second, I’ve added +1 to the $time variable for each click on one of the four aforementionned links.
Last, I use a named hook and a (rerun:) macro to evaluate the minutes at each click.

It's a warm starry night as you walk up the steps to the restaraunt.

While it *is* your first time here, you've received a personal recommendation from a trusted friend, so you have at least some hope that this won't be a terrible experience.

As you stand before the door, you ask yourself if there's any last things you should check.

Your watch?
Your tie?
Your zipper?

(link-reveal-goto: "*Nah, I'm good.*", "Entrance") [(set:$conf to it + 1) (set: $noun to "person"))]

(click-append: "restaraunt") [(text-colour:grey)[(a fine establishment, with a brick facade and wide glass widows which are warmly lit from the overhead lamps inside)]]

(set: $time to 55)
(click-append: "watch?") [(set: $time to it + 1) It's 8:|min>[$time] right now. The event starts at 9:00.] 

(click-append: "tie?") [(set: $time to it + 1) It's a little loose. You could tighten it if you want to. (rerun: ?min)] 

(click: "tighten") [(set: $time to it + 1)(set: $cool to it + -1, $smart to it + 1) (rerun: ?min)]

(click-append: "zipper?") [(set: $time to it + 1) It was down?! You quickly fix it. Thank goodness! (rerun: ?min)]

I believe it should work as intended.

1 Like

Hi Souppilouliouma!

Thanks for helping me out with this. My initial intent was to have a ticking clock so the player could run out of time. I would still like to know why the other Clicks break with the Live macro, and if there is a way around that, but the solution you’ve given me works for the purpose of what I’m trying to do. So I’ll use your code unless a solution for the Live macro shows up.

Thanks again for your help!

note: There is (at least) two syntax errors in your example:
1: The Hook associated with the (link-reveal-goto:) macro call has an additional close parentheses after the 2nd of the (set:) macro calls.
eg. (set: $noun to "person")) <!-- an additional close parentheses -->

I find formatting my code makes it easier find such errors, and to read.

(link-reveal-goto: "*Nah, I'm good.*", "Entrance")[{
	(set: $conf to it + 1)
	(set: $noun to "person")
}]

2: You are adding a negative number (eg. it + -1) when you could simply do a subtraction.
eg. (set: $cool to it - 1, $smart to it + 1)

Now for a little background on how specific macros work internally, and why alternatives are often advised…

1: The (click:) family of macros wait until all of the content of the Passage being visited has been processed before they scan the entirety of the current HTML page looking for instances of their related targets, and each found instants is converted into a “link”.

This scanning & replacement process is re-executed each time the HTML elements of the page are dynamically updated by a macro call, like what happens when macros like: (live:); (click-append:); (append:); (replace); (show:); (rerun:); are called. This re-execution can be briefly seen if you click the “tie” link of your example, the word “restaraunt” in the 1st sentence will briefly flash white before becoming a link again.

This is one reason why it is generally advised to use the (link:) family of macros instead whenever possible.

2: The (live:) family of macros interfere with the end-user’s ability to interact with the page each time either: the contents of their associated Hook is processed/executed; or (in the case of (event:) & (after:)) the conditional expression is evaluated; which is why it is generally advised to use these macros sparingly and to have as few of these macros active at the same time as possible.

The processing of the associated Hook also causes the dynamic updating of the page’s HTML elements, which will cause any of the (click:) family of macros to re-execute their “scanning & replacement” process again.

The above may be the reason why the “click” related links break when the “watch?” link is selected, because it results in a (live:) macro without a delay argument being called, which means that (live:) macro’s associated Hook is being processed/executed every 50 milliseconds (20 times a second).

1 Like

Hey Greyelf,

Thanks for investigating this for me! I appreciate the advice, and your theory on the broken “click” links makes a lot of sense to me. It would be as if they are processing (flashing) faster than the eye can see.

I’ll also try to adjust my coding habits to make cleaner passages moving on. Thank you so much for your help!