nadvsh - New adventure shell


. nadvsh [ -noplay ] [ -safe | -nosafe ]

[ -strict | -semistrict | -nostrict ]


nadvsh is the new adventure shell. It is a shell extension that makes your shell environment act like a text adventure game. It features objects which you may take with you in your backpack, and which you may use; interaction with other users; and non-player characters (NPC`s), which may either be helpful or a nuisance. Theme files may be loaded in order to set up a specific environment with matching objects and NPC`s.


The -strict, -semistrict and -nosafe options make the shell behave as if a corresponding play [semi]strict or play nosafe command had been given. nostrict and safe are the defaults (see below under COMMANDS).

The -noplay option causes the shell to read all the required definitions, but to not engage in playing yet.


Movement and location-related commands

In the following commands, location denotes a valid directory.

The commands north, down etc. are intended for dedicated adventure directory hierarchies.

cd location
cd is aliased to a function when the user has engaged in the adventure.

close location
See open.

Redescribes the current location.

down, d
Go down, if there is a subdirectory with that name.

east, e
Go east, if there is a subdirectory with that name.

enter location
Identical to cd.

go location
Identical to cd; additionally, go back is identical to cd ..

Identical to cd ..

lock location
See open.

lo[ok] [ hard | [in]to location ]
Look around in the current location, or in another location.

open location
open, close, lock and unlock set permissions to restrictive or permissive. In filesystem terms, this means:
    open:       go+rwX
    unlock:     go+rX
    close:      go-w
    lock:       go-rwx

where X is a conditional x. Like in real life, lock implies close, open implies unlock, and a location may be unlocked and closed at the same time.

north, n
Go north, if there is a subdirectory with that name.

northeast, ne
Go northeast, if there is a subdirectory with that name.

northwest, nw
Go northwest, if there is a subdirectory with that name.

south, s
Go south, if there is a subdirectory with that name.

southeast, se
Go southeast, if there is a subdirectory with that name.

southwest, sw
Go southwest, if there is a subdirectory with that name.

Identical to southwest.

unlock location
See open.

up, u
Go up, if there is a subdirectory with that name.

west, w
Go west, if there is a subdirectory with that name.

Object-related commands

Note that if an object name is required, and the object name contains spaces, the spaces (or the entire object name) should be quoted.

buy object_class [ as object_name ] [ for amount ]
Buy an object (probably equipment) from the specified object class. You may buy an object and specify a distinct name for it at the same time using as. Your bid (specified using for) determines which quality you will get.

Allowed object classes are: weapon, 'missile weapon', missile, armor, helmet, shield, clothing, backpack, food, drink, or object for an ordinary item (for which the name should be specified). For user-friendliness, the object class name sword is also supported, as well as the use of a miscellaneous object name instead of object. The use of sword is discouraged.

Examples using object class:

    buy 'missile weapon'
    buy armor for 60
    buy food as 'emmenthaler cheese'
    buy drink as 'some milk' for 2
    buy weapon as 'orc slayer' for 40
    buy object as 'handpainted teapot'

Examples using object names:

    buy sword as 'dragon killer' for 30
    buy 'handpainted teapot'

destroy object
Destroy an object that you are carrying.

don object
Identical to wear.

drink object
Drink something. This will usually strengthen you.

drop object [ as object_name ] | amount currency
Take an object or money out of your backpack and drop it. An object may be given a new name at the same time. File permissions must allow the action. Money that is dropped changes into a money object. Picking it up will retransform it into real money (should this fail, then use the sell command to cash in the money object).

Note the difference between:

    drop '10 florins'

which will drop an object (probably a money object), and:

    drop 10 florins

which will drop some of your money in the form of a money object.

eat object
Eat something. This will usually strengthen you.

exam[ine] object
Displays the specified file. Files representing objects should contain their description. See FILES below.

Displays the contents of your backpack, the items you are wearing and wielding, and your current amount of money.

get object [ as object_name ]
Identical to take.

lo[ok] at object
Identical to examine.

put [ away ] object
Identical to stow away.

put on object
Identical to wear.

quaff object
Drink a potion. Effects may be beneficial or harmful. (Not implemented)

rename object to object
Give an object a new name. You must be carrying it.

sell object
Sell an object of your inventory (probably something valuable). You may accept or reject the amount offered.

Also, if you somehow get stuck with a money object in your inventory, you may cash it in with the sell command.

stow [ away ] object
Put an object which you are using in your backpack. Opposite of wear and wield.

take object [ as object_name ]
Pick up a portable object and put it in your backpack. The object may be renamed at the same time, e.g. if you are already carrying another object of the same type. File permissions must allow the action. If the object is a valid money object, it will not be picked up; instead, the amount will be added to your money.

take off object
Identical to stow away.

unwear object
Take off clothing. Identical to stow away.

unwield object
Identical to stow away.

use object
Fire a wand or read a scroll. (Not implemented)

wear object
Wear clothing, armor or ring. Opposite of stow away. You may only combine items of clothing if they belong to different clothing types (see Object classes below). You may wear at most two rings at any time (one on every hand).

wield object
Select your preferred weapon, or use a lightsource. Opposite of stow away. You may wield at most two weapons at any time (one in each hand).

Person-related commands

emote sentence
Describe yourself to the players in the same location (i.e. users that share the same current working directory). The sentence should be formulated without a subject, and in the third person. (Not implemented)


    emote sighs.

This produces on the terminals of the users who are present in the same location:

    Message from rene@ilturin on pts/3 at 10:23 ...
    Rene Uittenbogaard sighs.

exam[ine] person
Examine a person (user or NPC).

fight NPC [ with object ]
Identical to kill.

give person object
give object to person
Put an item in another person`s backpack, if allowed.

inv[entory] person
Displays the contents of person`s backpack. If the person is a user, also displays the items the user is wearing and wielding.

kill NPC [ with object ] | pid
Fight an NPC, or kill a process. You may specify any weapon in your possession, even if you are not wielding it. By default, you will attack with the best weapon you are wielding. Killing other users has not (yet?) been implemented.

lo[ok] at person
Identical to examine.

say to person sentence
say 'sentence' to person
Identical to tell.

shout 'sentence'
Shout (using wall(1)) a message to all users currently logged in.

steal object from person
steal from person object
Try to take an item from another person`s backpack, if allowed.

talk [to] person [ ttyname ]
Simple wrapper for talk(1).

tell 'sentence' to person
tell to person 'sentence'
write(1) a message to another user.

where [ person ]
Tells the whereabouts of the non-player characters.

Miscellaneous commands

If invoked with no arguments, displays J.R.R. Tolkien`s Shire calendar. See also date.

colors [ nocolor | . | colorname | escape_codes ] [ nocolor | . | colorname | escape_codes ]
Select colors to be used in the prompt string (PS1) and in location descriptions. You may specify . which leaves the color unchanged, nocolor to suppress the use of color, a colorname from the set black, blue, red, magenta, green, cyan, yellow or white, or an escape sequence, e.g.:
        colors . `tput smul`

Note that in the Korn shell, escape codes in the prompt string would mess up the command line being edited; therefore, prompt coloring is never used in ksh.

currency [ currency_unit_plur [ currency_unit_sing ] ]
currency [ currency_unit_plur/currency_unit_sing ]
If the currency of the land has changed, you may specify the name of the new currency, e.g. 'gold pieces', 'cubits' or even 'patiwani shells'.

If the singular form of the currency is not identical to the plural form with the final 's' removed, the singular form may be specified as an optional second argument. Example: currency markoi marko

It is also allowed to specify the plural and singular forms in one argument, separated by a slash. Example: currency markoi/marko

Without arguments, the command will print the current currency unit. See also ENVIRONMENT below.

date will print the Shire date, if perl(1) and Date::Tolkien::Shire have been installed (available on CPAN). See also cal.

debug command [ args ... ]
Run command in `set -x` mode. Primarily used for debugging, as you might have guessed.

Provides concise help on valid commands.

Turns all color use off.

Disengage from playing.

play [ [semi|no]strict ] [ [no]safe ]
Engage in playing. Variables are not reinitialized.

The semistrict option will disallow any cd to a directory with a slash / in the name. The strict option will additionally disallow any cd to the parent directory. In this way, a pre-setup directory tree can be turned into a closed world. Symbolic links to directories may be used to create exits from locations with no subdirectories. Additionally, strict will prevent the current working directory from being shown in the prompt string (PS1), when there is a description present. nostrict will impose none of these restrictions.

The nosafe option will allow evaluation of commands specified in a local .nadvsh file (see below under FILES). This could be a security problem, therefore, the default is safe.

Prints your score, then exits the adventure, cleaning up all variables, functions and aliases. Your Unix shell will not exit.

replay [ [semi|no]strict ] [ [no]safe ]
Restart playing (reinitialize variables). replay will require nadvsh to be in the user`s PATH. See also play for the use of the strict options.

Displays the user`s score, strength and money. Experience points are received for visiting locations, fighting monsters and collecting (valuable) objects.

theme [ default | new file | [add] file | write file ]
Read in the theme file specified. default is used to specify the built-in theme. The new option may be used to discard all existing location descriptions. With the add option (default) the new descriptions will be added to those already in memory. The write option will write out a new theme file (not implemented).

When nadvsh starts up, a default (builtin) theme is loaded. This theme may be overruled by a theme file indicated by the environment variable NADVSH_THEME.

Sleep in order to regain strength. NPC`s may move while you are sleeping.

wait [ jobid ]
Allows other users and non-player characters to make a move. If a jobid is specified, then it also wait(2)s for the child process to end.


Non-player characters may act in ways that are not dependent on your actions. They will, however, not drop objects when you are not around, to prevent filesystem pollution; and they will not take objects from directories, to prevent non-object files being picked up by mistake.


Identifies the pager with which to view text files. Defaults to less(1) for Linux systems or more(1) for Unix systems.

The name of your favorite currency, in plural, optionally followed by a slash and the singular form. See also the currency command.

Specifies whether color should be used for the location descriptions, and which one. Normally nadvsh tries to figure out if color is supported. You may override this check and force or suppress the use of color.

Valid values are: nocolor to suppress color, or a colorname or escape sequence as specified under the colors command (see above).

As NADVSH_DESCCOLOR, but used for color in the prompt string (PS1).

Specifies which theme file should be loaded at startup instead of the default (builtin) theme.


Backpack files

The directory $HOME/.nadvbackpack/ is the implementation of your backpack. You may choose to set the mode to very permissive, in order to allow other users to put things in your backpack or steal from you. This is, however, not recommended if you plan to take non-adventure files in your backpack.

The directory $HOME/.nadvwield/ is the implementation of the collection of weapons you are wielding, armor, clothes and rings you are wearing, and the wands and lightsource you are wielding.

Non-player characters have their home in /var/tmp/nadvsh (or /var/nadvsh, if set up by the super-user). Their backpacks are found in subdirectories below there, e.g. /var/tmp/nadvsh/edrion/.nadvbackpack.

Location description files

In any directory, a file .nadvsh may be created with a description of the location. These files are parsed line-by-line. There are several line types, each of which starts with a specific marker:

Lines starting with d: are supposed to contain the long location description. All d: descriptions are printed, with no newlines between them.

Optional f: lines contain location flags, separated by colons. Flags in multiple f: lines are cumulative. The following flags are supported (only those marked with a + have been implemented):
  + underwater        + dark
    surfacedeep       + darkbynight (e.g. outdoors)
    surfaceshallow    + obscured (e.g. misty or raining)
    nogravity           hot
  + noair               cold
    foulair           + radiation

Restriction: flags that concern vision, like dark, darkbynight and obscured should be placed before the description of the location, because the description is displayed while the file is parsed.

Lines starting with p: contain the short description (to be used in the prompt, and in the description given in response to the look into command). The short description should fit on one line and should not end with a full stop. Multiple p: lines are concatenated with spaces between them.

If the short location description requires a different intro than 'You are in', you may specify a custom intro with the h: (head) option. Multiple h: lines are concatenated with spaces between them.

Optionally, e: lines may be included. These may be eval()-ed by the shell. This gives the writer an opportunity to interact with the adventure variables and functions. A description file may contain multiple e: lines, and these may be intermixed with e.g. d: lines.

e: lines may be a security problem. Therefore, they are evaluated only if the following criteria are met:

If the file and directory permissions and ownership are correct, but the script is running in safe mode or the directory is not included in d_mode_safe_dirs, the string (..) will be appended to the location description, to indicate that additional information was available.

Repetitive eval() lines are not evaluated when the location is being described, but instead before every prompt. The restrictions applicable for e: lines also hold for r: lines. Multiple r: lines are allowed, and will be executed in the order specified.

In the following examples, the text in the e: and r: lines is supposed to occupy only one line.

Example 1

    d:You are in a laboratory with many erlenmeyer flasks,
    d:round-bottom flasks and a destillation apparatus.
    p:a laboratory
    e:test $(($RANDOM % 2)) -eq 0 && d_wrap_noeol "A whisp of
        smoke rises from a nearby beaker."

Example 2

    d:You are on the bridge. There is a large holographic
    d:projection screen on one wall, depicting the asteroid
    d:belt outside.
    e:test -z "$d_captain_awake" &&
        d_wrap_noeol "The captain has fallen asleep near
        the communications panel and snores quietly."
    h:You are on
    p:the bridge
    r:if [ -z "$d_captain_awake" -a $(($RANDOM % 4)) -eq 0 ];
        then d_captain_awake=1; d_wrap "The captain wakes up."; fi

Object files

Object files are plain text files containing a description of the object. They also must be marked as being an object, which means they should contain at least one line starting with an object class marker. These markers consist of an alphabetic character, an alphanumeric character, and a colon.

The description that follows the colon MUST immediately start with an alphanumeric character. This restriction was imposed to minimize the chance of finding a 'false positive' when checking a file (e.g. a tar file) on its object status. For the same reason, and for performance reasons, there is a maximum size to an object file, currently 2000 bytes.

In any description, the character sequence {pcurrency} may be used instead of a specific currency name. This currency marker will be replaced by the favorite currency of the player, when he/she examines it. Likewise, {scurrency} will be replaced by the singular form of the currency.

Furthermore, objects that are charged (wands a.o.) may contain the character sequence {chargecount} in the description, which will be replaced with the chargecount (in English).

Example 3

    fo:It is a crust of bread, and it looks quite wholesome.

The crust is of class fo (food). The marker makes the object edible for the 'eat' command.

Example 4

    w1:The dagger is made of polished steel and
    has a dark leather hilt.

The dagger is a class w1 object, in this case, a weapon with attack value +1. The example also shows a line which does not begin with a marker.

Example 5

    a1:This is a strong, but yet light metal helmet,
    c1:in the colors of the duke of Forstinea.

This item is armor which has +1 defensive value (a1 = class 'armor/+1') and which should be worn as a helmet (c0 = class 'clothing/helmet'). All armor objects should have an armor marker and a clothing marker. See the clothing types in the table below.

Example 6

    mo:12 {pcurrency}.

This is a money object, representing 12 currency units. This example demonstrates the use of {pcurrency}.

Example (wrong)

    ri:An aquamarine ring radiating a soft bluish light.

The problem with this object is that the class marker li (light source) is not followed with an alphanumeric character. Therefore, it does not count as a class marker. The solution is to break up the existing description across the two lines.

Object classes

  class description
  ----- -----------
  w1    melee weapon (+1 strength) (dagger, knife, club)
  w2    melee weapon (+2 strength) (quarterstaff, mace,
                                    short sword, spear)
  w3    melee weapon (+3 strength) (battle axe, scimitar)
  w4    melee weapon (+4 strength) (polearms, long sword)
  w5    melee weapon (+5 strength) (halberd, two-handed sword)
  --    --
  m0    firing weapon (rifle, arquebus, (laser) gun) (Not implemented)
  m1    missile weapon (o1 type missile) (sling)
  m2    missile weapon (o2 type missile) (light crossbow)
  m3    missile weapon (o3 type missile) (heavy crossbow)
  m4    missile weapon (o4 type missile) (short bow)
  m5    missile weapon (o5 type missile) (long bow)
  --    --
  o0    missile weapon (+1 strength) (dart, knife)
  o1    missile (+1 strength) (bullet)
  o2    missile (+2 strength) (light quarrel)
  o3    missile (+3 strength) (heavy quarrel)
  o4    missile (+4 strength) (flight arrow)
  o5    missile (+5 strength) (sheaf arrow)
  class description
  ----- -----------
  a1    armor (+1 defense) (helmet, gauntlets, small shield)
  a2    armor (+2 defense) (padded or studded leather, large shield)
  a3    armor (+3 defense) (scale mail, ring mail)
  a4    armor (+4 defense) (chain mail)
  a5    armor (+5 defense) (banded mail)
  a6    armor (+6 defense) (field plate armor)
  class description
  ----- -----------
  c1    clothing or armor worn on head (hat, cap, helmet)
  c2    clothing          worn on face (mask, glasses, goggles)
  c3    clothing          worn on upper body (jacket, vest, tunic)
  c4                armor worn over upper body (chain mail,
                                                bullet-proof vest)
  c5    clothing          worn over entire body (mantle, cape, robe)
  c6    clothing or armor worn on hands (gloves, gauntlets)
  c7                armor held in hands (shield)
  c8    clothing          worn on lower body (skirt, pants, trousers)
  c9    clothing          worn on feet (shoes, boots)
  class description
  ----- -----------
  v0    valuable object (     0-    10 gp)
  v1    valuable object (    10-    30 gp) (10 xp)
  v2    valuable object (    30-   100 gp) (20 xp)
  v3    valuable object (   100-   300 gp) (30 xp)
  v4    valuable object (   300-  1000 gp) (40 xp)
  v5    valuable object (  1000-  3000 gp) (50 xp)
  v6    valuable object (  3000- 10000 gp) (60 xp)
  v7    valuable object ( 10000- 30000 gp) (70 xp)
  v8    valuable object ( 30000-100000 gp) (80 xp)
  v9    valuable object (100000+       gp) (90 xp)
  --    --
  C#    charge count (# = nr. of charges, in range 0-9)
  D#    device       (# = type, in range 0-9)
  R#    rod          (# = type, in range 0-9)
  S#    staff        (# = type, in range 0-9)
  W#    wand         (# = type, in range 0-9)
  p#    potion       (# = type, in range 0-9)
  r#    magical ring (# = type, in range 0-9)
  s#    scroll       (# = type, in range 0-9)
  class description
  ----- -----------
  ba    backpack
  dr    drink
  fo    food
  li    light source
  mo    money
  mu    musical instrument
  ri    non-magical ring
  sc    scuba gear
  te    teleporter
  --    --
  ob    ordinary portable object
  nh    ordinary non-portable object (too heavy to carry)
  nf    ordinary non-portable object (fixed to wall, floor, ...)

Other object classes are under development.

Theme files

Theme files may contain descriptions of locations, objects and non-player characters. Theme files do not contain information about the whereabouts of objects. For specifications of object and location descriptions, see the descriptions under the respective headings in this man page. Theme files are read in by the theme command.

Records in a theme file may (and usually will) occupy multiple lines, and start with a line indicating the record type. There is no record separator: records start at a line beginning with the record marker. The following types of records exist:

A line beginning with loc: specifies (as an anchored regular expression after the colon) a location (directory) which is described in the following lines. The description may span multiple lines.

Also, when a location description file (.nadvsh) is read in as a theme file, an loc: line is implicitly created, and the file is read in as if it were part of a theme file.

This kind of record specifies an object. The obj: line should contain the item name, and the lines following should contain the object description (together with the object class markers). The description may span multiple lines.

Specifies a non-player character. After the npc: marker, the line must contain space-separated fields with data about the character. The fields may be quoted when they contain spaces.

Following the npc: data line, there may be (multiple) lines containing a description of the character.

Example 7

    d:The road curves to the east here.
    d:Cows graze calmly as you walk by.
    h:You have come to
    p:a curve in the road
    e:if [ $d_pc_strength -lt 5 ]; then d_wrap_noeol "The mere
        sight of the cows brings comfort to your heart.";
        let d_pc_strength+=1; fi
    obj:tungsten wand
    W3:This is a tungsten wand
    h3:with {chargecount} rubies
    inlaid in the shaft.
    npc:bobo 'Bobo Rockbiter' /home/rene/bobo m 6 8 10
    Bobo is quite tall, even for a Fallohide, and has red curly hair.
    npc:droid droid /usr/lib n 20 0 0
    The droid does not react to your presence at all, and
    continues performing system checks.


Portability is probably not optimal. Not all Un*xes have been tested.

Two nadvsh shells run by the same user are not independent. In particular, they share the backpack directories for the user and NPC`s.

Two nadvsh shells run by different users are not independent either: they share the NPC`s backpack directories.

The script makes a number of ``sanity assumptions'', and therefore it does not try to modify e.g. PATH, HOME, or the current nounset mode (set -u).

There are plenty opportunities for cheating. This, however, cannot be avoided in an implementation such as this.

The default theme does not provide a consistent adventure (the objects and location descriptions are from a different ``setting'' (medieval vs. contemporary)). This will be fixed later.


nadvsh has been tested on:

Linux 2.4.19-pre6 / pdksh-5.2.14-13
Linux 2.4.19-pre6 / bash-2.05a-13
Linux 2.4.19-pre6 / zsh-4.0.2-2
AIX 4.3 / ksh
AIX 4.3 / bash-2.01.0 (1)-release
HP-UX 11.11 / ksh
HP-UX 11.11 / bash-2.05b.0 (1)-release
Note: bash-2.05.0 (2)-release segfaults when sourcing the script. This seems to be caused by large multiline string constants.

SunOS 5.6 / ksh
SunOS 5.8 / ksh


This manual pertains to nadvsh version 1.85.2 .


The manual pages for ksh(1), bash(1) and zsh(1).


Written by René Uittenbogaard (feedback, comments, bug reports to: Location descriptions were taken from the mud-shell (see below), with kind permission from the author, Dean Swift.

nadvsh was inspired by the following original 'adventure' shells:

in Bourne Shell script, by Doug Gwyn (February 1984)

in C, by John Coker (April 1984)

in Perl, by Dean ``Gandalf'' Swift (March 2001)


This program is free software; you can redistribute it and/or modify it under the terms described by the GNU General Public License version 2.

nadvsh is distributed without any warranty, even without the implied warranties of merchantability or fitness for a particular purpose.