-
Notifications
You must be signed in to change notification settings - Fork 18
More on commands
There are a lot of options available to you when you create a command - so many that it may be over-whelming at first. This page presents some of the more obscure points, but first a list of what can be found on other pages.
- To learn more about command matching, see here.
- To learn about adding exceptions to commands and intercepting them, see here.
- For the values a command "script" function should return, see here.
- Meta-commands are discussed here.
- If you want to modify an existing command, see here.
- If you have no text input for your game, you will still be using commands via the side panes or hyperlinks. More on that here.
- There is a full description of the process of creating a complex command here.
- A shortcut for creating simple commands is here.
- To match things other than items, see custom parser types.
- To get a list of commands QuestJS recognises, type CMDS in a game.
In "dev" mode, you can use the PARSER command to see debugging information from the parser. This is useful if the parser is getting the wrong command or wrong item. You can check if it thinks your command is a match at all, and then see how it scores.
You can add a pre-processor to the parser - a function that will be run when the player types a command, but before anything else happens (except parser.override). This simple example just echoes the command to the console.
settings.parserPreprocessor = function(inputText) {
log(inputText)
return inputText
}
This could be useful if you have items with full stops (periods) in their name, as usually this will cause Quest to split the text into different commands. Let us suppose a character called Dr. Jones. The user might type LOOK AT DR. JONES. The parser will see that as two commands, LOOK AT DR and JONES. One solution would be to call him Dr Jones, but alternatively, you could strip the full stops from the input text. This example also does it for "mr." and "mrs.".
settings.parserPreprocessor = function(inputText) {
return inputText.replace(/dr\./g, 'dr').replace(/mr\./g, 'mr').replace(/mrs\./g, 'mrs').replace(/ms\./g, 'ms')
}
In some situations, an alternative to creating a new command is to create a new direction. For example, CLIMB is better done as a new direction as, like a direction, it is one word and moves the player. This is discussed in detail here.
Quest will track how often that command is used on an item - as long as the command uses the default "script". The count is only incremented if the function returns true
(or world.SUCCESS_NO_TURNSCRIPTS
).
The count will be added as an attribute with the standard name with "_count" added. For the EXAMINE command, the count is therefore stored in "examine_count".
Note that the attribute is only added when used, so is initially undefined
. If the command is used, but the function returns false because it fails, the value will be zero. The attribute will be set to zero, if necessary, before the function is called, but the value is not incremented until after.
Here is an example function for "talkto". The default "talkto" for NPCs checks if the player and the NPC can talk before this is called. Let us suppose we have a rabbit. The player tries to talk to the rabbit, and count will be set to zero. However, it fails because rabbits cannot talk, so the count is not incremented. But then the player casts a spell allowing talking, and again tries to talk to the rabbit. The "talkto" function notes that that is allowed, so calls the "talk" function on the rabbit seen below. At this point count is zero, so the conversation happens. Then "talkto" returns true
talk:function() {
switch (this.talkto_count) {
case 0 :
msg("You say 'Hello,' to the rabbit, 'how is it going?'");
msg("The rabbit looks at you. 'Need carrots.' It looks plaintively at it round tummy. 'Fading away bunny!");
break;
default: msg("You wonder what you can talk to the rabbit about."); break;
}
return true
},
If you want to check if something has been examined, you can use the fact that JavaScript considers both undefined
and zero to be false
. In this example, the code block will be executed if the rabbit has been examined (the count is 1 or more); it will not otherwise (the count is zero or undefined
).
if (w.rabbit.examine_count) {
//...
If you want your custom command to do this too, you need to have this line in the "script" function before deciding if the command can be used, to initialise the attribute (assuming the item is held in a temporary varible called "obj").
if (!obj[this.attName + '_count']) obj[this.attName + '_count'] = 0
And this line just before you return world.SUCCESS
.
obj[this.attName + '_count']++
If you want to handle multiple items, these need to go inside the loop where you iterate through them, at the start and end. It does get ratrher more complicated, and you should see how it is done in the default "script" function in lib/_command.js.
At the start of each turn, Quest will determine what is in scope - anything the player can see or reach, plus the current room. When a command is checked, Quest will use this reduced list of items to check against. Occasionally, however, you want to look further afield. To tell Quest to do that, set "extendedScope" to true
.
For example, the MAKE command requires the user to reference an item that does not exist yet - if the user types MAKE HAT, then presumably the hat is not present. We need to tell Quest to look outside the normal scope when searching for this object.
new Cmd('Make', {
objects:[
{scope:parser.isUnconstructed, extendedScope:true},
],
script:function(objects) {
const obj = objects[0][0]
return obj.build({char:player, item:obj}) ? world.SUCCESS : world.FAILED
},
}),
Quest has a number of one-word commands that are actually handled by one command behind the scenes. They all do nothing by default, but give a little message to the player. For the most part they are there because other games have hem, and some players expect them to be understood.
listen
smell/sniff
jump
sing
dance
whistle
pray
You can change the default response by modifying the string in lang
. This is "no_" with the verb appended. For example:
lang.no_smell = "{pv:char:can't:true} smell anything here.",
You can have a specific effect occur in a location by giving the location an attribute with the name of the verb.
createRoom("lounge", {
desc:'A curious room with an old settee and a tv. There is a tatty rug on the floor.',
smell:'There is a faint musty smell, with just a hint of polish.',
}
You can also give a region an attribute in the same way.
You can have NPCs react to these strange actions. NPC reactions are discussed here. The important point for us is that you can check the player's "_hasJust" attribute (note the underscore), which will be set to theverb for one turn.
{
name:'after dance',
test:function() {
return player._hasJust === 'dance'
},
script:function(params) {
msg("Kyle looks at you strangely.")
},
},
You can add your own one-word commands - though whether this is easier that creating new commands is debatable.
const cmd = findCmd("OneWord")
cmd.regexes.push(/^(act)$/)
lang.no_act = "You do a quick scene from Hamlet because... it seems a good idea?"
If you are adding several, the first line only needs to be done once. You can add synonyms too.
const cmd = findCmd("OneWord")
cmd.regexes.push(/^(act)$/)
cmd.regexes.push(/^(perform)$/)
lang.no_act = "You do a quick scene from Hamlet because... it seems a good idea?"
lang.oneWordSubsts.perform = 'act'
Now you can add "act" attributes to your locations, and have NPCs react as well.
You can use the verbify
function to convert a command name to its attribute; this will ensure consistency.
It converts to lower case and strip out all non-alphanumeric characters.
QuestJS allows the user to put in several commands at once, like this:
get book, then read it.e.drop book
Sometimes it is a good idea to interrupt that. Suppose reading the book inadvertently summons a demon? It is just possible the user will want to think again. Just add this line:
parser.abort()
The user will see a message saying which commands were skipped (so you might want to consider where you put the above line; I suggest it go after the message about the ravenous demon.
I appreciate this will require some careful forethought by the author; I am not entirely convinced any author will actually think to use it, but the option is there.
Tutorial
- First steps
- Rooms and Exits
- Items
- Templates
- Items and rooms again
- More items
- Locks
- Commands
- Complex mechanisms
- Uploading
QuestJS Basics
- General
- Settings
- Attributes for items
- Attributes for rooms
- Attributes for exits
- Naming Items and Rooms
- Restrictions, Messages and Reactions
- Creating objects on the fly
- String Functions
- Random Functions
- Array/List Functions
- The
respond
function - Other Functions
The Text Processor
Commands
- Introduction
- Basic commands (from the tutorial)
- Complex commands
- Example of creating a command (implementing SHOOT GUN AT HENRY)
- More on commands
- Shortcut for commands
- Modifying existing commands
- Custom parser types
- Note on command results
- Meta-Commands
- Neutral language (including alternatives to "you")
- The parser
- Command matching
- Vari-verbs (for verbs that are almost synonyms)
Templates for Items
- Introduction
- Takeable
- Openable
- Container and surface
- Locks and keys
- Wearable
- Furniture
- Button and Switch
- Readable
- Edible
- Vessel (handling liquids)
- Components
- Countable
- Consultable
- Rope
- Construction
- Backscene (walls, etc.)
- Merchandise (including how to create a shop)
- Shiftable (can be pushed from one room to another)
See also:
- Custom templates (and alternatives)
Handing NPCs
- Introduction
- Attributes
- Allowing the player to give commands
- Conversations
- Simple TALK TO
- SAY
- ASK and TELL
- Dynamic conversations with TALK TO
- TALK and DISCUSS
- Following an agenda
- Reactions
- Giving
- Followers
- Visibility
- Changing the player point-of-view
The User Experience (UI)
The main screen
- Basics
- Printing Text Functions
- Special Text Effects
- Output effects (including pausing)
- Hyperlinks
- User Input
The Side Panes
Multi-media (sounds, images, maps, etc.)
- Images
- Sounds
- Youtube Video (Contribution by KV)
- Adding a map
- Node-based maps
- Image-based maps
- Hex maps
- Adding a playing board
- Roulette!... in a grid
Dialogue boxes
- Character Creation
- Other example dialogs [See also "User Input"]
Other Elements
- Toolbar (status bar across the top)
- Custom UI Elements
Role-playing Games
- Introduction
- Getting started
- Items
- Characters (and Monsters!)
- Spawning Monsters and Items)
- Systema Naturae
- Who, When and How NPCs Attack
- Attributes for characters
- Attacking and guarding
- Communicating monsters
- Skills and Spells
- Limiting Magic
- Effects
- The Attack Object
- [Extra utility functions](https://github.com/ThePix/QuestJS/wiki/RPG-Library-%E2%80%90-Extra Functions)
- Randomly Generated Dungeon
- Quests for Quest
- User Interface
Web Basics
- HTML (the basic elements of a web page)
- CSS (how to style web pages)
- SVG (scalable vector graphics)
- Colours
- JavaScript
- Regular Expressions
How-to
Time
- Events (and Turnscripts)
- Date and Time (including custom calendars)
- Timed Events (i.e., real time, not game time)
Items
- Phone a Friend
- Using the USE verb
- Display Verbs
- Change Listeners
- Ensembles (grouping items)
- How to spit
Locations
- Large, open areas
- Region,s with sky, walls, etc.
- Dynamic Room Descriptions
- Transit system (lifts/elevators, buses, trains, simple vehicles)
- Rooms split into multiple locations
- Create rooms on the fly
- Handling weather
Exits
- Alternative Directions (eg, port and starboard)
- Destinations, Not Directions
Meta
- Customise Help
- Provide hints
- Include Achievements
- Add comments to your code
-
End The Game (
io.finish
)
Meta: About The Whole Game
- Translate from Quest 5
- Authoring Several Games at Once
- Chaining Several Games Together
- Competition Entry
- Walk-throughs
- Unit testing
- Debugging (trouble-shooting)
Releasing Your Game
Reference
- The Language File
- List of settings
- Scope
- The Output Queue
- Security
- Implementation notes (initialisation order, data structures)
- Files
- Code guidelines
- Save/load
- UNDO
- The editor
- The Cloak of Darkness
- Versions
- Quest 6 or QuestJS
- The other Folders
- Choose your own adventure