Restrictions, Messages and Reactions - ThePix/QuestJS GitHub Wiki

Quest 6 gives authors all the common features of a text adventure built-in, but inevitably authors will want to tweak these to do somethng different, to make their game different. A broad approach to doing that is with restrictions, messages and reactions.

When the user types a command, the parser will try to identified what the user wants to do and get the appropriate command. The command will then establish if, in general, this is possible. Quest will go through this process:

  • test any specific restrictions (and abort if necessary)
  • perform the action
  • print a message to let the player know
  • determine any following reactions

So restrictions prevent the player doing something. A hat cannot be picked up because it is nailed to the floor, or a belt cannot be removed because it is cursed. These are function attributes, with a name in the form test[Verb], such as testOpen or testDropIn; they should return a Boolean - true if the action is permitted, false if not. In addition, they should say why the action is not permitted if that is the case. This is only for your custom restrictions; you can assume Quest has done all the usual checks for this type of object.

Messages let the user know the command was successful. They are string attributes, and take the form msg[Verb], for example msgSwitchOn or msgWear.

Reactions occur when the player does something - and the user has already been told it was successful. The alarm goes off as the player enters the room, the crowd gasp in astonishment when the sword is picked up or the item dropped whilst flying is lost forever. These are function attributes, and are named in the form after[Verb], such as afterClose or afterRemove.

When the Character Moves

To restrict how a specific character, including the player, moves, give her a "testMove" function with the exit as a parameter; this is checked as long as the exit does not have a custom "use" function - and if it does, you should include a check for this, to ensure it works the same!

To restrict a specific exit, give it a custom "simpleUse" function.

To react to moving, give the character an "afterMove" script, which again has the exit as a parameter.

Further reactions when the player moves

When the player leaves a location, the afterExit() script on the location will trigger. Then, on entering a new location, various scripts on this location he enters can fire: beforeFirstEnter(), beforeEnter(), afterEnter(), afterFirstEnter(). None of these take parameters.

You could also use a custom "simpleUse" function to trigger when a specific exit is used.

The player's "afterMove" script will fire after all these.

When an Item is Manipulated

Most actions allow for a restriction attribute, a message attribute and a reactions attribute, though there are exceptions. For items, restriction attributes and reaction attributes both take one parameter; a dictionary of options. The message attribute, being a string, takes no parameters, but instead uses the text processor, and will have access to the same parameters.

Restrictions when an item is manipulated

There are a number of attributes you can set that will stop a character - usually the player - doing something with an item, depending on the verb. The table shows what is available, the "On" column indicates which item this should be an attribute of. The function will be sent a dictionary of options including "char", the character doing the action, and "multiple", a Boolean indicating if this is one of multiple items the command is handling. Other options are noted.

Function On Extra options
testTake Item count
testDrop Item container, count
testDropIn Location or container item
testTakeOut Location or container item
testWear Item
testRemove Item
testOpen Item
testClose Item
testSwitchOn Item
testSwitchOff Item
testCarry Item exit
testPurchase item
testSell item
testFill Item fluid
testEmpty Item fluid
testPostureOn Furniture posture
testGive NPC item

Here is an example that will stop the player dropping anything in this location.

  testDropIn:function() {
    return falsemsg("It occurs to you that anything you drop here will be lost forever.")
  },

Messages when an item is manipulated

These are used when the action is successful, as an alternative to the built-in message in the language file. These are all on the item itself, so note in particular that while testDropIn and afterTakeOut are attributes on the container, msgDropIn and msgTakeOut are attributes of the item going in the container.

Function Extra options
msgDrop
msgTake
msgDropIn container*
msgTakeOut container
msgWear
msgRemove
msgOpen
msgClose
msgLock
msgCloseAndLock
msgUnlock
msgSwitchOff
msgSwitchOn
msgPurchase
msgSell
msgIngest
msgPress

Here are three examples, the second uses the text processor directive to make it character-neutral. The third goes rather further. If this is not a special container called "bare_earth", the standard message is given, lang.drop_successful. It is the "bare_earth", we get a custom message the uses the "count" of the item, and the "excess" (this is true if the player tried to plant more seeds than she was holding).

msgClose:"You close the lid.",
msgClose:"{nv:char:close:true} the lid.",
msgDropIn:"{ifNot:container:name:bare_earth:" + lang.drop_successful + ":Mandy carefully plants {nm:item:count} in the bare earth{ifIs:params:excess:true:, wishing she had a few more}.}",

Note that the "msgDropIn" attribute can be a function that prints the message, taking the dictionary as a parameter. The reason for this is that the message can be dramatically different if you are putting the item on a shelf to inside a box - or even burying it in the ground.

Reactions when an item is manipulated

There are a similar set of function attributes that get called (if they exist) after the event. Note that a message saying this happened will already have been shown. The function will be sent the same dictionary of options.

Function On Extra options
afterExamine Item
afterMove Item toLoc, fromLoc, end
afterDropIn Location or container item
afterTakeOut Location or container item
afterWear Item
afterRemove Item
afterOpen item
afterClose item
afterLock Item
afterUnlock Item
afterSwitchOn Item
afterSwitchOff Item
afterCarry Item exit
afterPurchase item
afterSell item
afterFill Item fluid, source
afterEmpty Item fluid, sink
afterPostureOn Furniture posture
afterPress Item
afterIngest Item
afterAttach Item item
afterDetach Item item

Note that while TAKE and DROP are tested separately, there is a single "afterMove" that handles both, and possibly other scenarios too. There is no "afterGive" as it is assumed this will be handled on an individual basis anyway.

This example might be for a tree location. Anything dropped it will end up on the path below.

  afterDropIn:function(item) { item.loc = 'woodland path' }