0 votes
by (300 points)
Hello again friends.

I'm having a bit of an issue figuring out how to make a timer that starts in one passage, then continues to count down in multiple other passges until the time runs out, or until the player reaches the end of the timed sequence.

I do know that you can make a footer timer, however, that counts down from the beginning of the game and I need the timer to start in a specific passage.

For example:

In passage 12, the timer begins. Then, in passage 20, the timer stops if it hasn't run out already. And if the timer runs out before the player reaches passage 20, it automatically takes the player to another passage that says "Game Over", or something along those lines. I need the timer to be visible in every passage until the end of the sequence.

What I usually use for my timers is:

 

(set: $counter to 10)

(css: "color: red; font-size: 250%")[|amount>[$counter]]

 

(live: 1s)[

(set: $counter to it - 1)

(if: $counter is 0)[(go-to: "Next Passage")]

(replace: ?amount)[$counter]

]

 

Any advice would be amazing, thank you!

2 Answers

+1 vote
by (158k points)
edited by
 
Best answer

The timer created by the (live:) macro is attached to the current Passage and that timer is destroyed whenever a Passage Transition occurs.

This means it's not possible to have a single countdown related (live:) timer that stays active across multiple passages. So to get around this behavour you will need to create a new countdown related timer within each of the passages you want your countdown to be active in.

The following solution used a $countdownActive variable to track if: the countdown has been activated; or if the countdown is still active. It uses a $countdownCounter variable to track the progression of the countdown, and a $countdownPassage variable to indicate which passage the countdown sents the player to upon completion.

1. Initialise the countdown variables within your project's startup tagged special passage, you will need to change the values of $countdownCounter and $countdownPassage as needed.

(set: $countdownActive to false)
(set: $countdownCounter to 10)
(set: $countdownPassage to "Next Passage")


2. Create a new header tagged special passage in your project to display the countdown counter in. You can name this passage whatever you like, I named mine Countdown Header to indicate the header's purpose.
You can change the message being displayed to whatever you like, however the existance of the two named hooks (countdown and counter) is important as they are targets for later code.

{|countdown)[Countdown: |counter>[$countdownCounter]<br><hr>]}

note: the above example includes a HTML <hr> element to draw a horizontal line between the countdown message and the contents of the current passage. You can safely remove that element from the message if you don't want such an effect, but if you do decide to keep it as part of the message then you will need to place the following CSS within your project's Story Stylesheet area to get around a design flaw in Harlowe's Passage Transition Effect.

hr {
	display: inline-block;
	width: 100%;
}


3. Create a new footer tagged special passage in your project to contain the code used to run the countdown. Again you can name this passage whatever you like, I used Countdown Footer as my name.

{
<!-- Is the countdown active? -->
(if: $countdownActive)[
	<!-- Is there any 'time' left on the countdown counter. -->
	(if: $countdownCounter > 0)[
		<!-- Refresh and reveal the displayed counter. -->
		(replace: ?counter)[$countdownCounter]
		(show: ?countdown)

		<!-- (Re) start the countdown timer. -->
		(live: 1s)[
			<!-- Has the countdown been manually deactivated? -->
			(if: not $countdownActive)[
				(stop:)
			]
			(else:)[
				(set: $countdownCounter to it - 1)

				<!-- If 'time' has run out move to the next passage. -->
				(if: $countdownCounter <= 0)[
					(set: $countdownActive to false)
					(go-to: $countdownPassage)
				]
				<!-- otherwise refresh the displayed counter. -->
				(else:)[
					(replace: ?counter)[$countdownCounter]
				]
			]
		]
	]
	<!-- No 'time' left on the counter so stop the countdown. -->
	(else:)[
		(set: $countdownActive to false)

		<!-- Move to the next passage if not already there. -->
		(if: (passage:)'s name is not $countdownPassage)[
			(go-to: $countdownPassage)
		]
	]
]
}

note: the above example includes a number of comment lines (the lines that start with <!-- and end with --> ) which try to explain what is happening. These comment lines, as well as any blank lines, can be safely removed.

4. Place the following somewhere in 'Passage 12' to activate the countdown.

(set: $countdownActive to true)

note: you could also change the values of the $countdownCounter and $countdownPassage variables at this time.

5. Place the following somewhere in 'Passage 20' to deactivate/stop the countdown.

(set: $countdownActive to false)


The above solution has been designed so that the countdown can be used multiple times within the same project, however only one 'instance' of the countdown can be active at any one time. To restart the countdown you simply need to reinitialise the relevant variables to the required values within the passage you want to start the countdown in.
eg. If in Passage 100 you want the a new 20 tick countdown that fails to Other Passage then add the following to Passage 100.

(set: $countdownCounter to 20)
(set: $countdownPassage to "Other Passage")
(set: $countdownActive to true)

 

by (300 points)
Thank you so much! The countdown works well, however, when the countdown ends, it doesn't go to a new passage, instead it says:

(goto:)'s 1st value is the number 0, but should be a string.

â–ºThe (goto:) macro must only be given a string.

I'm unsure of how to solve this.
by (158k points)

You will see that error message if you haven't assigned a Target Passage Name to the $countdownPassage variable, which my previous comment did in point 1.

by (300 points)
Oh! Sorry, I must have misread what you wrote. It works perfectly now. Thank you so much, I really appreciate the help!
+1 vote
by (880 points)
Have you considered using conditionals within the footer?

E.g. set the variable "timerAlpha" to be true in a passage where you want the timer to start

Then, in the footer, if "timerAlpha" is true, increment "counterAlpha"
Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...