How to make a universal passage which works if condition is true?

Twine Version: 2.4.0
Story Format: 2.36.1

Is there any way to create a passage which gets forcefully linked whenever a condition is met?

I am trying to make a day/night system. I wish that whenever it is ‘Late Night’, the player is automatically forced to ‘sleep’ before ending the day.

Unfortunately I can not think of any other method other than pasting a condition to check the time in the end of each passage.

Is there any better and more efficient way for doing this?

Thank you!

Hi there,
You can add something like this to a Special Passage (like PassageFooter, PassageHeader, PassageDone or PassageReady):

<<if $var is 5>>
    <<goto "Passage">>
<</if>>
1 Like

Alternatively, you may want to take a look at the Config.navigation.override function
(SugarCube v2 Documentation) if you want to force all of your links to lead to a certain passage if a condition is met.

In the following example, if $time == "Late Night", all links will lead to the “Fall Asleep” passage (the code goes into Story JavaScript):

Config.navigation.override = function (dest) {
	var sv = State.variables;

	
	if (sv.time == "Late Night") {
		return "Fall Asleep";
	}
};
3 Likes

Thanks for the reply.
I tried using it but it doesn’t work…
It shows an empty passage and after reloading shows an error “Cannot convert undefined or null to object”

Thank you for the response.

I tried using it in javascript however I am using Chapel’s cycles for the day/night system Custom Macros (twinelab.net)
I tried to get a variable to use in the code but I couldn’t get a variable which would update its value after every change in the cycle…
I also tried using a function which fetches the cycle’s current value but you can’t use functions in js…
I tried tweaking the js code by Chapel at end of the site for resetting cycles but it didn’t go well either…

You shouldn’t need a separate variable to update after every change in the cycle. I think you want to use the Cycle.check() method instead. If you want to redirect the player to the “Fall Asleep” passage whenever the cycle hits Late Night, you would put something like this in (as @manonamora said) in a special passage:

<<if Cycle.check("time", "Late Night")>>
    <<goto "Fall Asleep">>
<</if>>

(Replace “Fall Asleep” with whatever the name of your “sleep” passage is.)

If instead you want your “hub” passage that displays your options for what to do today to display only the “Fall Asleep” link, you could put the following on said hub passage:

<<if Cycle.check("time", "Late Night")>>
    <<[[Fall Asleep]]>>
<<else>>
    (list of regular daytime options here)
<</if>>

note: The purpose of the PassageHeader and PassageFooter special Passage is to pre-pend/append visual content to that generated by the “current” Passage being visited.

And generally it isn’t a good idea to cause an automatic re-direction when the current Passage is being processed, because that results in a useless Moment (that represents the current Passage) being added to History.

It is far better to do that re-direction in whatever code caused the Passage Navigation request in the first place, which will generally be the end-user selecting a link.

So you can either place the “Time to Sleep” logic within the link itself…

<<link "choice that causes time to advance">>
	/* do actions relating to this choice */
	<<set $variable to "value">>

	/* Advance the time */
	<<advancePeriod 1>>

	/* check what the current period is */
	<<if $now.period is 'Late Night'>>
		<<goto "Bed Time">>
	<<else>>
		<<goto "Some Other Passage">>
	<</if>>
<</link>>

…or you can use a Config.navigation.override handler like suggested by @agat .

You could even place the “Time to Sleep” logic within the code that is causing the Period to advance, which in my above example is the <<advancePeriod>> widget/macro.

1 Like

The above doesn’t take the use of the Cycles system into account, so with that in place, how you’d do it in a link would be

<<link "link text here">>
   <<if Cycle.check("time", "Late Night")>>
      <<goto "Fall Asleep">>
  <<else>>
     <<goto "some other passage">>
  <</if>>
<</link>>

But I’m not quite knowledgeable enough about JS to figure out how it would interface with the Config.navigation.override option or how you would integrate it into the code for advancing the phase. (I’d advise against messing with the Cycles JS if you don’t fully understand how it works, anyway.)

1 Like

Thanks for the response but the same error keeps popping up…
I am now just pasting

<<if Cycle.check("time", "Late Night")>>
      <<goto "Sleep">>
<</if>>

at the end of each passage.
It works fine I guess. It does have its own pros that is, now I have more freedom to control responses of actions of players at that time and can change resultant paragraphs for different paragraphs…

Thanks for the reply.

Rather than a choice, I would allow player to be at most of the places before the ‘Late Night’.
I just wanted that whenever it is ‘Late Night’, they are forced to sleep before the next day arrives.
Advancing time by link would not be possible for me because some of the choices would be available at other periods of day as well and I do not want to force player to sleep whenever they click the choice and it is not ‘Late Night’.

I am now just pasting

<<if Cycle.check("time", "Late Night")>>
      <<goto "Sleep">>
<</if>>

at the end of each passage.