-
Notifications
You must be signed in to change notification settings - Fork 17
Tutorial 8 ‐ Commands
... Continued from Locks.
So we want a battery charger in the garage, and we want the player to CHARGE BATTERY... we need a CHARGE command. This will be a very simple command, for more complicated commands, see this page.
There are two parts to this. First the command itself, and second the response for the torch.
The code for the command looks like this.
new Cmd('Charge', {
regex:/^(?:charge|recharge|power) (.+)$/,
objects:[
{scope:parser.isHeld}
],
defmsg:"{pv:item:'be:true} not something you can charge.",
})
The code needs to go in the "code.js" file (I suggest keeping commands together, either at the top or bottom of the file; it just makes it easier to find them when your game gets big).
What the code does is create a new command, giving it a name and a dictionary of data - just as we do when creating objects. The dictionary has three elements; "regex", "objects" and "defmsg". The "regex" is a regular expression; what Quest matches to the text the user typed. The regular expression has two bits in brackets, "(?:charge|recharge|power)" and "(.+)"; these are called capture groups, and allow Quest to match against different texts. The first will match "charge", "recharge" or "power". The bit at the start, ?:
says this is a capture group we are not interested in it - capture it and then throw it away.
The second part will match anything (the dot indicates any character, the plus indicates one or more of them).
The "objects" attribute tells Quest what to do with each capture group it has not discarded. In this case it is an object, and for an object, we need to tell Quest where to look for it. parser.isHeld
is a built-in function; this will look for objects the player is holding first. Note that if a command fails to match an object in the scope you give, it will default to trying to find a match from all the visible objects, so you cannot assume an item is in a certain place just because you set its scope that way - it is just suggesting where to look first.
By default, a command will look for an attribute in the object that is the same as the name of the command, but lower case, so in this case "charge" (you can override this by setting "attName"; this is useful if your command's name is more than one word, as the attribute has to be a single word). We will add a "charge" attribute to the torch later, but we also need the command to handle any object that does not have a "charge" attribute, this is what the "defmsg" function is for. This is a string telling the player the item cannot be charged. It uses a text processor directive - "nv" - to modify the text depending on the item; eg "The book is not something you can charge." or "The boots are not something you can charge." (more on that here).
So now we should be able to type CHARGE TORCH, but it will say it cannot be charged. We need to go to the torch and give it its own charge response. We can add this after the "power" attribute (and I am only showing the torch from there downwards):
power:3,
charge:function() {
if (player.loc != "garage") return falsemsg("There is nothing to charge the torch with here.")
msg("You charge the torch - it should last for hours now.")
this.power = 20
return true
},
})
A good general approach to writing functions for commands is to think of all the ways that would stop the player being able to do it. We know the user has specified the torch at this point, but she might be in the kitchen, and therefore unable to charge the torch. The first thing the code does, therefore, is check where the player is. If she is not in the garage, we print a message and exit the function, returning a value of false
. Quest 6 allows us to do all that in one line.
Sometimes there can be half a dozen different possible reasons why a command might fail, and it should go though each one in turn. But if the situation is right we get to the second half of the function. This typically does three things, as illustrated here - tell the user it worked, modify something in the game world, and then return true
to let Quest know a turn has passed.
In the next section we will look at how to implement talking to NPCs, but before that it would be cool if we could tell an NPC to do our custom command. For simple commands involving a verb and an object, we can get Quest to do that for us. Just flag the command with the "npcCmd" attribute.
To get it to work properly - that is, have appropriate responses - you need your scripts to handle a "char" parameter, which could be the player or the NPC. In the "default" function below, we use the "sb" text processor directive to insert the subjective pronoun of the character into the string.
new Cmd('Charge', {
npcCmd:true,
regex:/^(?:charge|power) (.+)$/,
objects:[
{scope:parser.isHeld}
],
defmsg:"pv:item:'be:true} not something {sb:char} can charge.",
})
And also in the response. Now we need to use the "options" parameter that Quest will send. This is a dictionary with various attributes we can access, the important ones being "char", the character doing it, and "item" the object being manipulated.
power:3,
charge:function(options) {
if (options.char.loc != "garage") return falsemsg("There is nothing to charge the torch with here.")
msg("{pv:char:charge:true} the torch - it should last for hours now.", options)
this.power = 20
return true
},
})
Finally, it is worth mentioning that you can modify the "getAgreement" function on the NPC to determine whether the NPC agrees to do it or not, though we will not bother in this tutorial.
Continue to Complex mechanism...
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