I'm trying to implement a system where a particular negative variable is monitored during the player's playthrough and when it gets too high the player is taken out of whatever part of the game they're in and forcibly moved to a sequence giving them the opportunity to reduce it or lose. I'm not entirely sure the best way to put this into the game, and hopefully I'm making sense & explaining myself correctly, but any ideas?
Comments
It is definitely possible, yes—though perhaps not as cleanly as I'd like.
Question: When does this need to happen? Is on the transition to a new turn/moment sufficient or should this happen even in the middle of a turn. The former would really be better if that's acceptable.
Method 1. Check the passage name in a prehistory/predisplay task or the PassageReady special passage and force navigation to another passage. (disrecommended)
While I've seen people do this, I do not recommend this approach. It does not terminate the currently running navigation, so you're really just layering a new navigation on top. This can have consequences if the original navigation causes side-effects—e.g. variable modifications, etc. It also makes a hash of the history—which may or may not be an issue.
Method 2. Choose the destination at the link site.
Basically, you use a <<link>> to choose a destination, rather than having a hard coded one—it's also possible to do this with a wiki link if you use a function as a passthrough, but Twine 2's automatic passage creation ruins that method.
For example: The downside to this is that if you need to do this everywhere, all of your links become complex.
Method 3. Use the new Config.navigation.override callback (will be introduced in v2.13.0) to override the pending navigation destination.
The callback takes one parameter, the original passage name. If its return value is falsy, the override is cancelled and navigation to the original destination continues unperturbed. If its return value is truthy, the override succeeds and that value is used as the new destination of the navigation.
For example:
NOTE: The _followup temporary variable I used within the examples for methods 2 & 3 is there to allow you to forward the player to their original destination after the event if you need to.
EDIT: BTW, SugarCube v2.13.0 should be released within a day or two as of the date and time of this post.
passageName here refers to the new passage I want the player to be taken to when the threshold is reached, yes?
If so, I'm confused here:
Specifically, what is return "Dark Power Overflow"; intended to refer to? From my terrible javascript skills it reads to me that if darkPower is greater than 100 you're taken to a passage titled "Dark Power Overflow," but I'm not sure what the first passageName is supposed to be if that's the case.
I'll likely ignore State.temporary.followup = passageName; as I don't think it would be easy to capture where the player is when they trigger the effect, and I'm going for an impact akin to something like your wounds getting too high that you collapse unconscious; I wouldn't want the player to necessarily be able to pick up wherever they were right away and plan on taking them to a sequence of the game where they have to reduce/improve the negative stat until they can go back to normal again.
Correct. If the callback returns a truthy value, which "Dark Power Overflow" happens to be, that value is used as the new destination passage title.
That's exactly what that does. Well, depending on what you mean.
Specifically, it captures where the player is supposed to be going, because that's what passageName records.
To capture where the player actually was at the time they activated the link, you'd want to record the value of State.passage—or passage(). That probably seems counterintuitive, however, the callback is invoked before a new moment is created for the history, so at that point the player is still technically exactly where they were at the time they activated the link.
For example: (using Twee notation) When the player clicks on the "Go to Carol's house" link in the "Path" passage and the callback is invoked the following will be true:
You should, obviously, do whatever your plans dictate. I simply wanted the example to show that you could capture where the player was supposed to be headed, via the link they activated, so that if the override event allowed them to continue on afterward, you'd know where to send them.
is passageName something I have to replace myself? If so that's probably not going to do what I am after because the point of this is that it kicks in wherever the player is, whatever they're doing and overrides their progression. Not at hard-coded places. Unless I'm completely misunderstanding, which is also very likely!
As is I put that code in and got an error of "Error [tw-user-script-0]: Cannot set property 'override' of undefined." so I'm assuming I'm doing something wrong.
If you need v2.13.0 you can download a copy from the SugarCube 2 website, the instructions on how to add it to your Twine 2 application can also be found there.
ETA: Just deleted and redownloaded/reinstalled it so it's definitely being used as far as I can tell, still no dice.
ETA: I quit and relaunched Twine and it went from 2.13.0 being active to 2.12.1. Bug?
I think I know what's going on here. Let me send you a PM.
I'll also open an issue on Twine 2's issue tracker.
Perfect, after following your workaround this works perfectly and looks like it's exactly what I am after. Thank you!