Timed events - ThePix/QuestJS GitHub Wiki

Timer events happen at a certain time in the real world, as opposed to the game world. You should think carefully about whether they are a good idea. A useful discussion can be found off-site here.

If you want to handle events and time passing in the game world instead, you want this page.

The system in Quest 6 maintains a ticker that fires every second. Events can be registered to fire at a specific second.

There are two parts to creating a timer event. We have to do this in two stages to ensure the event state is saved when the user saves the game. Functions do not get saved, so the the first stage is to define the function that is going to be used. This must be done when the game is setting up, and so should be done in settings.js, in a dictionary called "settings.eventFunctions" - all your timer functions should go inside the same dictionary. Here are a couple of trivial examples, "sayNow" and "sayThen" that just print a message.

settings.eventFunctions = {
  sayNow:function() {
    msg("Now!")
    io.scrollToEnd()
  },

  sayThen:function() {
    msg("Then!")
    io.scrollToEnd()
  },
}

Note that they scroll the page after printing. This is not usually required in Quest 6, it just happens when the player takes a turn; it is required here because the player is not taking a turn.

To get an event to actually fire, we also need to register it with the ticker. This is what will get saved as part of the game. This can be done at any time, so you can start a timer in response to what the player has done. However, if you want it to be active from the start, it needs to go in settings.setup.

Creating a timer event uses the util.registerTimerEvent, which takes three parameters. The first parameter is the name of the function, as we just set up. The second is the number of second to wait until calling the function. The third is the number of seconds to wait until repeating the event, and can be omitted for a one-off event.

Here are a couple of examples that use the above functions (note that a function can be used numerous times). The first waits 7 seconds, then repeats every 4 seconds. The second waits 10 seconds, and does not repeat.

settings.setup = function() {
  util.registerTimerEvent("sayNow", 7, 4)
  util.registerTimerEvent("sayThen", 10)
}

Repeat until

This example adds a count to the event, and when it gets to a certain value, it returns true, telling Quest to stop it repeating. Note that if you reuse this function, this.count will remember its old value, as it is connected to the function, rather than the timer, so you would need to also reset that.

  sayOften:function() {
    if (!game.player.count) game.player.count = 0
    game.player.count++
    msg("Often! " + game.player.count)
    io.scrollToEnd()
    if (game.player.count > 3) return true
  },

This will fire four times, showing the numbers 1 to 4.

Notes

NOTE: Currently events, once created, last forever; even if they are not repeating, they are still in memory. If you only create a few dozen events, that should be no problem. If you have thousands, there may be an issue, as Quest will test all of them every second.

NOTE: You can change the timer interval by setting settings.timerInterval, which should be set to the number of milliseconds in the interval. This example will have it fire every half second:

settings.timerInterval = 500