-- everything is a location, an object or a timer --
		
		Before we start working on our story we must define some basic stuff 
		that we can reuse with other stories. Things like:
			
			common descriptions;
			
			common flags;
			
			common attributes;
			
			common triggers;
			
			logging;
			
			save and restore functions (to store progress);
			
			regression testing;
			
			the player object;
			
			mechanism for starting the game;
			
			mechanism for moving the player between locations;
			
			looking around;
			
			scoring mechanism;
			
			verbose function;
			
			quit function.
		
		At this point it is helpful to read sections “locations objects and 
		timers” (2 pages)  and “location and object artifacts” (5 pages)  from 
		the XVAN Introduction document.
		
		Inputs for this part of the tutorial are files
		part1-end.lib and
		part2-start.xvn.
		
		Common descriptions are descriptions that each location and object has. 
		This is the reason they can be used with wildcards: it is guaranteed 
		that they can be found at a later time when the wildcard is linked to an 
		actual object or location.
		
		We will use the following common descriptions (apart from the predefined 
		descriptions):
d_longdescr long location or object description;
			
			d_shortdescr short object description;
		
		We make the following design decisions:
			
			For locations, d_shortdescr always is the location name only.
			
			Upon first visit of a location, the location's d_shortdescr and 
			d_longdescr are printed;
			
			With following visits only d_shortdescr is printed;
			
			For an object, with each visit only d_shortdescr is printed;
			
			For objects the “examine” command prints d_longdescr;
			
			For locations the “examine” command acts as the “look” command (see 
			further);
			
			We will also define a verbose() function to allow forced printing of 
			long location descriptions at all times.
		
		We will use the following common flags (apart from the predefined 
		flags):
			
			f_seenbefore to determine whether to print long or short 
			description.
		
		We will use the following common attributes (apart from the predefined 
		attribute):
r_be conjugation of verb ”to be” for location or object;
			
			r_have conjugation of verb “to have” for location or object.
		
		We must also define words for is, are, has and have in the vocabulary 
		file. I chose to define them as verbs so they can also be used in user 
		input (e.g. "where is the toaster"). If you only want to use them as 
		attribute values for printing, they may have any word type.
		
		Common triggers
		We will use the following common triggers (apart 
		from the predefined triggers):
t_i to print inventory
			
			t_exa to examine
		
		We make the following design decisions:
			
			When the player object enters a new location the predefined trigger 
			t_entrance will be executed for the new location and all its 
			contained objects;
			
			When the player object wants to exit from a location the predefined 
			trigger t_exit will be executed for the current location and all its 
			contained objects. If any of them responds with disagree() the 
			player will not be allowed to leave the location;
		
		We will now define the common triggers.
		
		t_i
		This trigger was already mentioned in part 1 of the tutorial. The 
		inventory verb will print the "You are carrying" message and each object 
		will print its description.
		
		Our t_i common trigger
		
		t_i
		  if owns(o_player, %this) then
		    indent()                                           # indent level 
		was set by the verb prologue
		    printcr("[a] [this]")
		  else
		    nomatch()
		
		Because this is a common trigger, each object and location will now have 
		this trigger (you don’t have to worry about memory space, the code is 
		only stored once). In case an object needs to print a different message 
		(e.g. add text like "being worn") it suffices to redefine the trigger as 
		a local trigger with the same name within the object body. Local 
		triggers take preference over common triggers with the same name.
		
		There's something new, here.  The function nomatch() generates the third 
		possible return code for a trigger (the others are agree() and 
		disagree() as explained in part 1). With nomatch() a location or object 
		tells the interpreter "forget that I had a match for this input". But 
		why do we need nomatch(), we can also print nothing and return agree(), 
		right? Wrong. If we return agree(), the interpreter would know there had 
		been a match and no verb default code would be executed. So if the 
		player carried nothing and all objects in the location would return 
		agree(), the default verb text "nothing, you are empty-handed" would not 
		be printed.
		
		Nomatch() is quite powerful. If you redefine a common trigger and the 
		local copy returns nomatch(). the interpreter will execute the common 
		trigger as well. I use this sometimes to let the object do a quick test 
		and if everything is ok, execute the common trigger after all.
		
		Our design decision states that we should print d_longdescr.
		
		Our t_exa common trigger
		
		t_exa
		  printcr(d_longdescr)
		  setflag(f_seenbefore)
		
		the interpreter will know for which object or location the common 
		trigger is executed, so it can locate the right description and flag. We 
		could also have said printcr(%this.d_longdescr) and 
		setflag(%this.f_seenbefore).
		
		As per our design decision, t_entrance is triggered when the player 
		object enters a new location. We want it to:
			
			print information about the location (long or short description);
			
			print information about the objects in the location;
			
			print information about objects in/on/under/.. other objects.
		
		Here we go, comments added for clarification.
		
		t_entrance
		  if not(islit(o_player)) then
		    printcr("It is pitch black.")
		    disagree()   # ready, exit
		  endif
		  if equal(%this, l_location) then
		    # l_location is wildcard for the current location
		    printcr(d_shortdescr) # print location name
		    if not(testflag(f_seenbefore)) then
		      # first visit
		      setflag(f_seenbefore)
		      printcr(d_longdescr)
		    endif
		  else
		    # it´s not the current location but an object in the location
		    if cansee(o_player, %this) then
		      if owns(owner(o_player), %this) then
		        # object is at the same containment level as player
		        setflag(f_seenbefore)
		        printcr(d_shortdescr)
		      else
		        if not(owns(o_player, %this, 0))  then
		          # it´s not (in) some object the player carries (0 means all 
		levels of containment)
		          setflag(f_seenbefore)
		          print("There is [a] [this] [r_preposition] [the] ")
		          print(owner(%this))
		          printcr(".")
		        endif
		      endif
		    endif
		 endif
		 # all the endifs are not necessary at the end of a trigger.
		
		So, what t_entrance does:
			
			check whether it's dark;
			
			check whether it's executed for the location (as opposed to an 
			object in the location);
			
			check whether it's executed for an object in the location that the 
			player can see;
			
			check whether this object is contained in another object not carried 
			by the player if the object is carried by the player, we don’t want 
			to mention it).
		
		Note: make sure to close the current IF-statement with an ENDIF when 
		starting a new if statement. If you find that parts of your trigger 
		should be executed but are not, you may have forgotten an ENDIF 
		statement. If you forget the first ENDIF (line 5), nothing of the 
		trigger will be executed when the player is lit because all lines will 
		be considered part of the if not(islit(o_player)) branch.
		
		In case the common t_entrance should not be executed for an object, 
		define an empty t_entrance trigger locally with the object. Empty as in 
		that it only contains an agree() function. We do this for example for 
		the player object.
		
		As per our design decision, t_exit is triggered when the player object 
		exits the current location. We want it to:
			
			check whether the player object is free to go.
			
			if not, it must return disagree()
		
		As leaving a location is game specific, in our basic definitions the 
		t_exit trigger will always return agree().
		
		t_exit
		  agree()
		
		But how does it work then? We'll come to that when we define the player 
		object, but here's a heads-up:  XVAN has a function called exit(par). 
		This function will call t_exit for par and all its contained objects. If 
		one of the t_exit triggers returns disagree(), the exit function will 
		return false and we know there's some object not allowing the player to 
		exit the current location. Likewise, there is also an entrance(par) 
		function that calls all t_entrance triggers.
		
		To log your game session, XVAN has the built-in transcript() function. 
		This function copies user input and the game's response to a file called 
		transcript.txt in the directory that the game is running from. Calling 
		transcript for the second time will turn off logging. We will define 
		transcriptas a verb in the vocabulary file so it can be used for all 
		games.
		
		VERB transcript
		  "transcript"
		    transcript()
		  DEFAULT
		    printcr(“use ‘transcript’ to log your session.”)
		ENDVERB
		
		To store and load game progress, XVAN has functions save() and 
		restore(). The save() function stores the current story progress in a 
		file called save.dat in the directory that the game is running from. The 
		restore() functions scans the directory for save.dat and loads it.
		
		In order to use the functions, we create verbs “save” and “restore” in 
		the vocabulary file. Restoring a game is pretty straightforward and 
		always allowed, so we will define the restore functionality in the 
		vocabulary file. The code for saving will be a local trigger in the 
		player object. Why? Well, there may be game specific situations when we 
		do not allow the user to save. For example in a maze or to prevent 
		trial-and-error guessing when solving a puzzle.
		
		$VERB save
		  # define your save functionality in the story file
		  DEFAULT
		    printcr(“Use ‘save’ to save your progress.”)
		ENDVERB
		
		$VERB restore
		  "restore"
		    restore()
		    printcr("restored.")
		  DEFAULT
		    printcr(“use ‘restore’ to restore a previously saved game.”)
		ENDVERB
		
		$VERB quit SYNONYM q
		 "quit"
		   print("Do you really want to quit? ")
		   if yesno() then
		     quit()
		
		 DEFAULT
		   printcr("use 'quit' to leave the game.")
		ENDVERB
		
		The yesno() function requires the user to enter "yes", "no", "y" or "n". 
		It is not case sensitive.
		
		The player object is mandatory in each XVAN story file. 
		
		Before we start, the player object in 
		part2-start.xvn looks like this:
		
		$OBJECT o_player
		 # The o_player object is predefined and represents the human player.
		 DESCRIPTIONS
		   d_sys  
		 CONTAINED
		 FLAGS
		 ATTRIBUTES
		 TRIGGERS
		END_OBJ
		
		For starters, we will:
			
			set the system descriptions (d_sys) to “you” and "me";
			
			set common attribute r_be to “are”;
			
			set common attribute r_have to "have";
			
			define the nouns "you"and "me" and the "are" verb in the vocabulary 
			file;
			
			override common triggers t_entrance and t_exit with local ones that 
			do nothing.
		
		$OBJECT o_player
		 # The o_player object is predefined and represents the human player.
		 DESCRIPTIONS
		    d_sys                   “You”, "me"
		
		 CONTAINED          # don’t know where the player starts  until we have 
		the game map
		
		 FLAGS
		
		 ATTRIBUTES
		    r_be = are     # you are
		    r_have = have  # you have
		
		 TRIGGERS
		    t_entrance
		      agree()
		
		    t_exit
		      agree()
		END_OBJ
		
		Next, we will define the following basic stuff in the player object:
			
			starting the game;
			
			moving the player between locations;
			
			looking around;
			
			keeping the score;
			
			save and restore commands to store progress;
			
			logging;
			
			verbose function.
		
		If we do nothing, the game will just start with a “> “ prompt. But we 
		want to print some introductory text when the game starts.  XVAN has no 
		default starting mechanism, so we make our own. We define a timer m_init 
		that reaches its threshold when the game starts. 
		
		m_init
		  init   0
		  step   1
		  direction up
		  interval   1
		  state go
		  trigger_at    1
		  execute o_player.t_init
		
		With the player object, we will define a trigger t_init and a 
		description d_init. The trigger prints the description.
		
		$OBJECT o_player
		 # The o_player object is predefined and represents the human player.
		 DESCRIPTIONS
		    d_sys                   “You”, "me"
		
		
		    d_init                  “*** XVAN tutorial ***”
		
		
		
		 CONTAINED          # don’t know where the player starts  until we have 
		the game map
		
		 FLAGS
		 ATTRIBUTES
		    r_be     = are     # you are
		    r_have = have  # you have
		
		 TRIGGERS
		    t_entrance
		      agree()
		
		    t_exit
		      agree()
		
		
		
		   t_init
		     printcr(d_init)
		     printcr("")
		     entrance(owner(o_player))
		
		
		END_OBJ
		
		After starting the game, timer m_init expires and triggers 
		o_player.t_init. This will print d_init, our opening message and 
		describe the player's initial location.
		
		XVAN has no default mechanism to let the player move between locations. 
		We will create our own mechanism. We will use several of XVAN’s built-in 
		functions to implement moving around. XVAN’s built in functions are 
		described in detail in a separate document.
		
		In order to move around the player we must:
			
			make the player object catch user input about moving around;
			
			check if the direction indicated in the user input is a valid 
			direction;
			
			check with all objects in scope whether the player may leave;
			
			move the player object to the new location and execute the 
			t_entrance triggers.
		
		This is our new player object
		
		$OBJECT o_player
		 # The o_player object is predefined and represents the human player.
		 DESCRIPTIONS
		    d_sys                   “You”, "me"
		    d_init                  “*** XVAN tutorial ***”
		
		 CONTAINED          # don’t know where the player starts  until we have 
		the game map
		
		 FLAGS
		 ATTRIBUTES
		    r_be     = are     # you are
		    r_have = have  # you have
		
		 TRIGGERS
		
		
		      "[dir]" -> t_move
		      “go to [dir]” -> t_move
		
		
		
		    t_entrance
		      agree()
		
		    t_exit
		      agree()
		
		   t_init
		     printcr(d_init)
		     printcr("")
		     entrance(owner(o_player))
		
		
		
		    t_move
		      if valdir(l_location, %dir) then
		        # it's a valid direction
		        if exit(l_location) then
		          # no object objects to the player leaving the room
		          move(o_player, %dir) # move updates current location
		          entrance(l_location)
		        endif
		      else
		        nomatch()  # let other objects or verb default code react.
		      endif
		      agree()
		
		
		END_OBJ
		
		What do we see here? Right below the TRIGGERS keyword we see two 
		possible user inputs that will fire the t_move trigger. In the t_move 
		trigger, the valdir() function checks if the direction is a valid 
		direction. If not, the t_move trigger returns nomatch(). In case none of 
		the other objects react, the default verb code will be executed which 
		will print “you can’t go that way”.
		
		If the direction is valid, the exit() function will execute the t_exit 
		triggers from all objects in the current location (and from the current 
		location itself). If all return agree(), then the player object will be 
		moved in the direction indicated by the user input. Finally, for  the 
		new location and all its contained objects, the t_entrance trigger will 
		be executed.
		
		You may have noted that move() accepts different kinds of parameters. 
		With the verbs take and drop, we used move(object1, object2) which moved 
		object2 in object1. With t_move we used move(object, direction) which 
		moved object to the location that is reached by going into the 
		direction. Possible parameters combinations are listed in the function 
		description document.
		
		To enable the player to look around we define trigger t_look locally 
		with the player object.
		
		This trigger will call the entrance() function for the player’s 
		location. This means that for the player’s location and each containing 
		object, the t_entrance trigger will be called.
		
		The player’s  t_look trigger
		
		t_look
		  if equal(owner(o_player, l_location)) then
		    clearflag(l_location.f_seenbefore)
		    entrance(l_location)
		  else
		    # the player is in some object. Print this information
		    print(“[[[prepos] [the] “)
		    print(owner(o_player)
		    print(“].”)
		    clearflag(owner(o_player).f_seenbefore)
    entrance(owner(o_player))
		
		Because we (ab)use the entrance() function in our look command, we must 
		clear the f_seenbefore flag before calling the entrance() function. The 
		reason is that the t_entrance trigger will check for f_seenbefore and if 
		it's set it will print the short description.
		
		Why are there 3 ‘[‘ in the print statement? We want to print something 
		like “[in the boat]”. However, for the compiler, a ‘[‘ in a string means 
		that a parameter will follow. We tell the compiler to print one ‘[‘ by 
		entering ‘[[‘. So, ‘[[[‘ tells the compiler to print a ‘[‘ and that a 
		parameter will follow.
		
		Note that just defining t_look does not mean that the t_look trigger 
		will be executed when the user enters “look”. We must yet link the 
		trigger to a user input. This is done at the beginning of the TRIGGERS 
		section in the player object:
		
		“look” -> t_look
		
		Now the interpreter knows that whenever the user enters “look”, it must 
		execute the t_look trigger.
		
		To keep track of the score, we define a local attribute r_score with the 
		player object. We also define a verb “score” in the vocabulary and a 
		local trigger t_score for the player object that prints the score.
		
		We create a local trigger t_save with the player object. Additionally, 
		we create a local flag f_no_save with the player object. The t_save 
		trigger will check the flag and if it is set, it will not save game 
		progress. This can be used to prevent cheating. For example, when the 
		player enters a maze, an object may set the o_player.f_no_save flag and 
		thus prevent the player from saving progress while he is in de maze.
		
		By invoking the verbose functionality, the t_entrance triggers will 
		always print the long location descriptions (d_longdescr). We define the 
		verb ‘verbose’ in the vocabulary file and a local flag f_verbose with 
		the player object. Next we change the common t_entrance trigger so it 
		will test for the f_verbose flag before printing the location 
		description.
		
		This is what we have right now:
		
		In the vocabulary file we’ve added:
		
		$VERB score
		  DEFAULT
		    printcr(“Use ‘score’ to get information about your score.”)
		ENDVERB
		
		VERB verbose
		  DEFAULT
		    printcr(“use ‘verbose’ to toggle long room descriptions.”)
		ENDVERB
		
		‘score’ and  ‘save’ will be handled by the player object. All other 
		input with these verbs will print the default message.
		
		Our player object with all the basic stuff we wanted:
		
		$OBJECT o_player
		 # The o_player object is predefined and represents the human player.
		 DESCRIPTIONS
		   d_sys                   “You”, "me"
		   d_init                  “*** XVAN tutorial ***”
		
		 CONTAINED          # don’t know where the player starts  until we have 
		the game map
		
		 FLAGS
		
		  
		f_no_save = 0
		  f_verbose  = 0
		
		
		 ATTRIBUTES
		
		   r_be     = are     # you are
		   r_have = have  # you have
		
		 TRIGGERS
		   "[dir]" -> t_move
		   “go to [dir]” -> t_move
		   “look” -> t_look
		
		
		   “score” -> t_score
		   “save” -> t_save
		   “verbose” -> t_verbose 
		
		
		
		  t_entrance
		     agree()
		
		   t_exit
		     agree()
		
		   t_init
		     printcr(d_init)
		     printcr("")
		     entrance(owner(o_player))
		
		   t_look
		     if equal(owner(o_player), l_location) then
		       clearflag(l_location.f_seenbefore)
		       entrance(l_location)
		     else
		       # the player is in some object. Print this information
		       print("[[[prepos] [the] ")
		       print(owner(o_player))
		       printcr("].")
		     endif
		     if cansee(o_player, owner(owner(o_player))) then
		       entrance(owner(owner(o_player)))
		     else
		       entrance(owner(o_player))
		
		   t_move
		     if valdir(l_location, %dir) then
		       # it's a valid direction
		       if exit(l_location) then
		         # no object objects to the player leaving the room
		         move(o_player, %dir) # move updates current location
		         entrance(l_location)
		       endif
		     else
		       nomatch()  # let other objects or verb default code react.
		     endif
		     agree()
		
		
		
		   t_score
		     printcr(“Your score is [r_score] points.”)
		
		   t_save
		     if testflag(f_no_save) then
		       printcr(“Saving at this point would be like cheating.”)
		     else
		       save()
		       printcr(“saved.”)
		
		   t_verbose
		     if testflag(f_verbose) then
		       clearflag(f_verbose)
		       printcr(“Verbose mode turned off.”)
		     else
		       setflag(f_verbose)
		       printcr(“Verbose mode turned on.”)
		
		
		END_OBJ
		
		And our common t_entrance trigger, adapted for verbose functionality:
		
		t_entrance
		  if not(islit(o_player)) then
		    printcr("It is pitch black.")
		    disagree()   # ready, exit
		  endif
		  if equal(%this, l_location) then
		    # l_location is wildcard for the current location
		    printcr(d_shortdescr)
		    if not(testflag(f_seenbefore)) 
		
		or testflag(o_player.f_verbose) then
		      # first visit 
		
		or verbose mode
		
		
		      setflag(f_seenbefore)
		      printcr(d_longdescr)
		    endif
		  else
		    # it´s not the current location but an object in the location
		    if cansee(o_player, %this) then
		      if owns(owner(o_player), %this) then
		        # object is at the same containment level as player
		        setflag(f_seenbefore)
		        printcr(d_shortdescr)
		      else
		        if not(owns(o_player, %this, 0))  then
		          # it´s not (in) some object the player carries (0 means all 
		levels of containment)
		          setflag(f_seenbefore)
		          print("There is [a] [this] [r_preposition] [the] ")
		          print(owner(%this))
		          printcr(".")
		        endif
		      endif
		    endif
		 endif
		 # all the endifs are not necessary at the end of a trigger.
		
		This ends part 2 of the tutorial. We’ve finished our preliminary work 
		that we can use as a starting point for future stories.
		
		Everything we did is in files part2-end.lib 
		and part2-end.xvn. These files are the 
		starting point for part 3 of the tutorial where we will write our sample 
		story.
		
		The files we created in part 2 will not compile to an XVAN story. This 
		is because part2-end.xvn is not yet complete. By the end of the next 
		part 3 we will have a playable story.
.