Heya, so I'm trying to create an event that appears after a certain amount of time in-game has been reached (using the Javascript shown
here).
For example: I would like that after 1 week in-game has happened, it will take the reader to a certain passage/event automatically. But... I'm not entirely sure how I can do that.
I've been looking through the forum and miscellaneous sites for some help but I can't really find anything that works so far.
Does anybody have any tips on how I can do this? Thank you !
Comments
Take the player when? The next time the player attempts to navigate passages, immediately, on some other criteria? For now, I'm going to assume that on the next navigation is okay.
If you're using SugarCube ≥v2.13.0, then you may use the Config.navigation.override callback to override the player's navigation.
For example, the following setup.eventOnDate() static method accepts the event passage and date as parameters and sets up a navigation override callback which compares the current game date to the event date and, if necessary, overrides the player's navigation—it also records the original destination passage in the _followup temporary variable, which you may use to send the player on after the event if you want: (Twine 2: goes in Story JavaScript; Twine 1: goes in script-tagged passage) NOTE: The above only allows one event at a time and assumes that you're using $now as the current game date variable.
Usage:
And yeah, the next navigation was what I was had in mind. Again, sorry for not being more clear about that.
So, I placed the setup in the Story JavaScript and attempted to activate the usage in the appropriate passage (with the correct name of the passage I wanted it to be TAKEN to and in the Usage code and all) aaand I got an error.
' Error: <<run>>: bad evaluation: Cannot set property 'override' of undefined '
I didn't really change anything (except for 'THE NAME OF THE EVENT PASSAGE' to the actual name of the passage with the event but I'm guessing that's probably not the problem here), so I'm not entirely sure what went wrong.
My apologies if the answer is super obvious or something, I'm pretty new to Twine and everything so if I'm being a dummins, I'm sorry!
Probably the simplest solution would be to update your SugarCube install, if possible.
It works fabulously, thanks you guys soooo much! You really are a lifesizer, thank you!
On a side note, I don't know if I should ask this in a separate discussion or not, but since it's kind of close to the original question I'll just ask it here:
Is there any way to use the Javascript's time as an expression in an If macro?
So if I wanted to, say, have an If macro activate but only at a certain time and in a certain location (so basically overriding them, but only if they go to a specific passage, not just one that activates regardless of where they're at like the code you guys helped me with), is there any way to do that?
Just in case I'm not making that much sense, what I'm asking to do would be like " <<if currenttime is so-and-so>> Text <<endif>> ". That expression wouldn't work obviously, but I wanted to visualize what I'm asking just in case.
Sorry if this is basic babby stuff I should probably know by now. It might've been a month since I've asked a question but I'm still not nearly as good at Twine as I wished I could be!
Do you put the time you want the If macro to activate in the (...) parenthesis on the first line (so like <<set _date to new Date($now, 'minutes', 15) or does something else belong there?
And should I just leave the () in the second line empty? Or does it need the same value as the parenthesis above too?
For example: That is likely not the date you'll wish to use.
It wasn't initially doing anything, regardless of how much tinkering I did/making sure all the numbers were right. But somehow changing the underscore in "_date" to a dollar sign ended up working for me. Huh, weird!
Still, I'm super happy I was able to get all of this to work (even though now I have a problem where I want the if macro to only activate once but meh)
Thank you so very much for your help, Exile!
If the time will match exactly, then you could change out the greater-than-or-equal (gte) operator for the equality operator (is). I would think that's unlikely to happen, however, so you'll probably have to use a sentinel variable to keep it from showing up again. For example:
Thanks again for all your help, Exile!
Sorry for constantly bringing this discussion up but I've got a new problem and I'm having some trouble trying to fix it.
So I figured out that if I wanted to, say, have any afternoon-focused If statements I could use something like <<if setup.changeDate ($now, 'hours', 12)>> <<set $afternoon to true>> <<endif>>, so that way I don't have to make like dozens of different dates for every afternoon in game.
It worked for the most part but now I'm in a bit of a snag.
I'm trying to make it so that if the player is in a specific room while $afternoon is true, they are taken to a different passage automatically (using goto "Passagename").
But, whenever they enter the passage that's SUPPOSED to take them to the afternoon event ONLY when $afternoon is true, but the goto activates at ANY time, even if it's no where near 12 hours. I've tried to fidget and fix this but it doesn't seem like anything I'm trying is working. Either it still takes the player to the passage AUTOMATICALLY, even if it's the right time or not, or nothing happens. It's pretty frustrating.
Does anyone have any ideas of how to do this WITHOUT making like tons of different new Dates for every day or without it activating the passage even though it's nowhere near the time it's supposed to trigger at?
Thank you!
Your example doesn't do what you think it does. The setup.changeDate() returns a new Date object. By using it as the sole part of the <<if>> macro's conditional expression, you're simply causing it to be coerced into a boolean. Objects are always truthy—i.e. when coerced to boolean, they always coerce to true. Thus your <<if>> will always be true and execute it contents.
You probably wanted to compare the new Date to some approximation of an "afternoon" range—e.g. 12:01–17:59.
SugarCube v1 example
Since v1 does not have temporary variables, the example uses story variables and unsets them at the end.
SugarCube v2 example
I'll start doing that from now on, thanks for the heads-up!
So, I used the example you gave and it works... kinda. The If statement DOES only trigger at the specific times like it's supposed to (thank you very much for helping me out there!) but when it does it's at midnight, or hour 0, not 12. I tried and fidget with the numbers a bit to try and get results but after swapping out the '12' for any other number the entire code just stops working.
Could it be that I'm setting/advancing the date wrong? I posted the two codes I'm using below:
(thanks for telling me how to put the code in the box thingy, it looks so much better and easier than just plopping it with the rest of the comment!)
First. Where are you running this code? In the PassageReady special passage?
Anyway. You were a bit scant on details, so I made the assumption that the new Date you were attempting to generate—i.e. current game time plus 12 hours—was when the event was to take place, so you could see if that time was in the afternoon block. If that assumption was incorrect, then yes, it probably isn't doing what you want.
If you simply want to know if the current game time is within the afternoon block, then there's no need to create a new Date. You will, likely, want to run the code automatically every turn, probably in PassageReady, and have it set $afternoon appropriately for either condition.
Here is a PassageReady-based code example—for SugarCube v1 and v2—and usage examples for the version of $afternoon set by the code example.
Also. The code examples—both the previous set and the following ones—define afternoon as: 12:01 ↔ 17:59 (24 hr) or 12:01 PM ↔ 5:59 PM (12 hr). Anything else is considered to be not afternoon.
SugarCube v1 example (goes in the PassageReady special passage)
Since v1 does not have temporary variables, the example uses story variables and unsets them at the end.
SugarCube v2 example (goes in the PassageReady special passage)
Usage of $afternoon (as set by the preceding code examples)
Checking for both afternoon and not afternoon. Checking only for afternoon. Checking only for not afternoon.