Change listeners - ThePix/QuestJS GitHub Wiki

Quest 5 has change listeners, and they are very useful in some situations. My view is that they are not needed in Quest 6 because you can readily return values from functions. But if you want to use a change listener, the capability is there.

You need to register change listeners. This adds them to a list, and at the end of each turn Quest will go through that list, before turn events are run, and again after they are run, and also after any timer events are run. Be aware that if a change listener itself changes a value that is being watched, when that change gets noticed will depend on where in the list the listener is.

Use util.addChangeListener to add a listener. This must be done before the game starts; you cannot add new listeners once the game is running due to how games are saved. The function takes three parameters, the object, the name of the attribute to watch and the function to fire when it changes.

The simple example just gives a message when the attribute changes.

util.addChangeListener(w.book, "watchedStringAttribute", function(o, current, previous) {
  msg("watchedStringAttribute changed from " + previous + " to " + current)
})

The triggered function takes four parameters; the object, the new value, the old value and the attribute name. Only the first three are used in the example.

You can add a fourth parameter to util.addChangeListener to give a custom test. This means your function could fire is different situations, for example, when an attribute falls below zero, as illustrated below. This resets the attribute to zero, ensure if effectively never goes negative, but it could be used to note the monsters is dead, for example.

util.addChangeListener(w.book, "watchedNumberAttribute", function(o, current, previous, att) {
  o[att] = 0
}, function(o, current, previous) {
  return current < 0
})

Because of how games are saved, you are limited to only watching number attributes and string attributes. Furthermore, because Quest guesses which is which when a game loads, and an attribute that is a string of digits will be taken as a number when a game is loaded, and will wrongly trigger a change, so is to be avoided.

If there is any chance that you will extend your game after you have released it (say adding a new region players can explore), I would advise putting the code that sets all your change listeners together. When you extend your game, add any new listeners after the others and you will hopefully find players can load games saved in the old version into the new version (but do test that!).