-
Notifications
You must be signed in to change notification settings - Fork 17
Using Neutral Language
Often when creating a text adventure you will find you do not know what you are talking about! This is often the case with a command. Let us suppose we have an ATTACK command. In the command’s script, you have an object the player wants to attack, but what is it? It could be any item in your game!
You need your command to work - and the resultant text to read properly - whether the user did ATTACK ZOMBIE, ATTACK CROWD or ATTACK MARY - and even then we are assuming the script has already decided this is something you can attack. If the response is “You attack it. It looks angry.” for all three, the user will not be impressed. We need to make our response language neutral.
By default, items in QuestJS are referred to as "it", NPCs as "he" or "she" (depending on whether you use NPC(false)
or NPC(true)
) and the player as "you", but you can easily change any of them as it suits you by setting the "pronoun" attribute of the object.
It needs to be set to a dictionary that contains all the various forms of the pronouns. Here is an example:
pronouns:{
subjective:"I",
objective:"me",
possPro: "mine",
possAdj: "my",
reflexive:"myself",
handleAs:'me',
},
In fact, all the standard ones are built-in to Quest 6, so we can instead do this:
pronouns:lang.pronouns.firstperson,
Here is the full list (and I appreciate it is not comprehensive).
lang.pronouns.firstperson
lang.pronouns.secondperson
lang.pronouns.thirdperson
lang.pronouns.massnoun
lang.pronouns.male
lang.pronouns.female
lang.pronouns.nonbinary
lang.pronouns.neNem
lang.pronouns.veVer
lang.pronouns.spivak
lang.pronouns.xeXem
lang.pronouns.perPer
lang.pronouns.zeHir
lang.pronouns.zheZhir
lang.pronouns.zeZem
lang.pronouns.faeFaer
lang.pronouns.aeAer
lang.pronouns.plural
This first example is set to use "they":
createItem("boots", WEARABLE(),{
loc:"lounge",
pronouns:lang.pronouns.plural,
examine:"Some old boots.",
})
A mass noun is something that is a little odd; the pronouns are the same as third person singular, but it does not use "a" or "an" for the indefinite article.
createItem("underwear", WEARABLE(1, ["lower"]), {
loc:"bedroom",
pronouns:lang.pronouns.massnoun,
examine:"Clean!",
})
Here is a "non-binary" character who prefers to be referred to as "they". Note that the reflexive is "themself" and verb conjugation will be as for the third person singular.
createItem("Leslie", NPC(),{
loc:"lounge",
properName:true,
pronouns:lang.pronouns.nonbinary,
examine:"They looks happy to see you.",
})
You can add additional pronoun sets by adding to the lang.prounouns
dictionary.
lang.prounouns.xheXhir = {
subjective:"xhe",
objective:"xhim",
possAdj: "xher",
possPro: "xhers",
reflexive:"xhimself",
handleAs:'it',
}
The "handleAs" attribute will cause verbs to be conjugated as they would for "it".
Because of how QuestJS saves games, you have to use the "changePronouns" function to change the pronouns of an NPC (or indeed any item) while the game is underway.
w.Kyle.changePronouns(lang.pronouns.female)
Traditionally interactive fiction uses the second person ("you"), but literature uses first person ("I") or more commonly third person ("he or "she"). By default QuestJS follows the standard convention, using the second person, but you can change that in exactly the same way as above.
createItem("Buddy", PLAYER(),{
loc:"lounge",
properName:true,
pronouns:lang.pronouns.thirdperson,
examine:"Looking good!",
})
You should also change the room template. For example.
settings.roomTemplate = [
"#{cap:{hereName}}",
"{terse:{hereDesc}}",
"{objectsHere:She can see {objects} here.}",
]
With that out of the way, we can now look at how to give our commands language-neutral responses.
We can set the response to:
"You attack " + object.pronouns.subjective + "; " + object.pronouns.objective + " look angry.”
Now if the player attacks the crowd, she will see "You attack them; they look angry."
When you want to refer to an object’s name, use the "lang.getName" function, which will sort out exactly what it should be called, according to the options you give it. The most important option is "article", which can be "DEFINITE", to have "the" added, or INDEFINITE, to have "a" added - but only if appropriate for the object.
To illustrate, here are three objects.
Name | teapot | shoes | Zoe |
---|---|---|---|
alias | Zoë | ||
pronouns | thirdperson | plural | female |
INDEFINITE | a teapot | some shoes | Zoë |
DEFINITE | the teapot | the shoes | Zoë |
So back to attacking the crowd and Mary, we can now do this:
"You can see " + lang.getName(object, {article:INDEFINITE}) + "."
-> You can see a crowd.
-> You can see Mary.
"You attack " + lang.getName(object, {article:DEFINITE}) + ". " + object.gender + " look angry."
-> You attack the crowd. they look angry.
-> You attack Mary. she look angry.
We need a capital at the start of the second sentence. We can use the sentenceCase
function.
"You attack " + lang.getName(object, {article:DEFINITE}) + ". " + sentenceCase(object.gender) + " look angry."
-> You attack the crowd. They look angry.
-> You attack Mary. She look angry.
We also need to conjugate the verb so it is of the correct form. Quest has the lang.conjugate
function for that, it takes the object that is doing the verb, followed by the verb as a string (use "be" for the verb "to be", by the way).
"You attack " + lang.getName(object, {article:DEFINITE}) + ". " + sentenceCase(object.gender) + " " + lang.conjugate(object, look) + " angry."
-> You attack the crowd. They look angry.
-> You attack Mary. She looks angry.
Because we often want to start a sentence with the object doing the verb, Quest has a lang.pronounVerb
function that will get the gender of the object and add the conjugated verb. Setting the third parameter to true
capitalises the phrase for us.
"You attack " + lang.getName(object, {article:DEFINITE}) + ". " + lang.pronounVerb(object, "look", true) + " angry."
Having said all that, a better way - in my opinion - is to use the text processor. So why did I bother writing all that? Well, the text processor uses those same constructs in the background, and I think it is easier to understand the directives if we work our way to them slowly.
Here is what it looks like:
"You attack {nm:object:the}. {pv:object:look:true} angry."
The first directive is "nm", which inserts the object's name, with the option "the". The second directive is "pv", which inserts the pronoun and verb, and requires the object, the verb (in the infinitive form). Both of these optionally take "true" as a last parameter if we want it capitalised.
More details here; there are a lot of directives available to hopefully cover all eventualities.
For this to work, you need to send the text processor some parameters - it needs to know what the object is. This is done as a dictionary of name-value pairs, and can be done in the msg
command. There is only one entry in this case, but you can have as many as you like:
msg("You attack {nm:object:the}. {pv:object:look:true} angry.", {object:object})
Sometimes it is more convenient to set up the params at the start of the command script, so it can be used in several responses. Numerous built-in commands do this:
const tpParams = {object:object}
msg("You attack {nm:object:the}. {pv:object:look:true} angry.", tpParams)
The verb "to be" is a bit odd in English in that the conjugated forms are very different. You may be tempted to do this:
msg("{nv:object:is:true} carrying a rabbit.", {object:object})
Quest is going to see "is" and conjugate it as a regular verb, and you will get something like "Mary isses carrying a rabbit." You need the infinitive form, i.e., "be" for this to work properly.
msg("{nv:object:be:true} carrying a rabbit.", {object:object})
You can use an apostrophe to indicate you want a verbal contraction. This example will give "She's carrying a rabbit.".
msg("{pv:object:'be:true} carrying a rabbit.", {object:object})
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