-- everything is a location, an object or a timer --
		This document gives a general overview  of the XVAN Interactive Fiction 
		Authoring System. It describes the basic concepts in terms of locations, 
		objects and timers and also addresses the vocabulary and actions. 
		Examples are throughout the text.
		A tutorial that describes how to create an XVAN story from scratch is 
		available in a separate document. 
		Apart from the tutorial there are (of course) a Cloak of Darkness 
		implementation and a medium-size sample story called Escape!. Escape! 
		Was entered in the Sprint Thing 2019 competition and received badges for 
		best NPC and best puzzles.
		
		Platforms – Linux, Windows and macOS
		Common Descriptions, Flags, Attributes and Triggers
		Wildcards with (common) triggers and verbs
		Predefined descriptions, flags, attributes and triggers
		XVAN is an interpreter-based interactive fiction authoring system. It is 
		a compiler, an interpreter and an authoring language.
		The XVAN compiler takes a story source file written in the XVAN language 
		and creates a binary game file. The interpreter reads the game file and 
		lets the user play the story.
		The XVAN 
		compiler is 
		a console application with a command line interface. The XVAN 
		interpreter comes 
		in 3 versions: a console version, a Glk version and as a back-end that 
		is used with a separate GUI: IFI-XVAN.
		The first version of XVAN was built in the 90’s of the previous century, 
		when internal computer memory was not sheer unlimited (my Atari has 1 MB 
		of RAM which was a lot back then). I therefore built it to be low on 
		memory requirements. A flag, for example, occupies 1 bit of internal 
		memory and XVAN has a mechanism for swapping objects and locations in 
		and out of internal memory.
		XVAN is written in C. The console version of compiler and interpreter 
		does not use any external libraries or interfaces other than the 
		standard C include files.
The Glk version of the interpreter uses the Glk libraries. Glk is mainly intended for applications with text user interfaces (like interactive fiction). It gives more possibilities than a console or terminal window. More information on Glk can be found at http://www.eblong.com/zarf/glk/.
		As of version 2.3.4, IFI-XVAN is available. This version of the 
		interpreter uses the IFI (Interactive Fiction Interface) to connect to 
		the Brahman GUI, which supports in-game graphics, graphical map display, 
		clickable links etc. Both desktops and mobile devices are supported. 
		More information on IFI and Brahman can be found at 
		
		
		Strandgames' blog.
		XVAN started its life on my Atari 1040st back in the 90s. After the 
		Atari went obsolete, I ported XVAN to Windows. I ran it on W95 and XP, 
		and currently on W7 and W10.
		I also made a version for Linux. I used the Linux Mint Rebecca 
		distribution.
		I made macOS versions on High Sierra.
		As of version 2.3.4, there is IFI-XVAN that runs on Windows, Linux, and 
		macOS.
		Binaries and save files are portable between the operating systems. What 
		you compile or save on one platform will work on the others.
		My sample game Escape! Was tested on windows with NVDA by a 
		vision-impaired person. I tested Escape! On linux Mint with the Orca 
		screenreader and it seems to work.
		XVAN is designed around Locations, Objects and Timers. In XVAN story 
		source files there is no main flow, it’s just the collection of a number 
		of locations, objects and timers in one or more text files. At playtime, 
		the user input is offered to each location and object that is in scope 
		and each decides whether and how to respond to the input.
		Locations and objects have a number of artifacts available that they can 
		use and manipulate:
		
		The XVAN world model is made up of a number of locations that can be 
		connected, so the player can travel through the world. Locations cannot 
		contain other locations but they can contain objects (for objects, see 
		below).  Anything tangible  that is not contained in something else is a 
		location.
		Example:
		$LOCATION l_kitchen
		 DESCRIPTIONS
		   d_sys   “the kitchen”, “the dining room”
		END_LOC
		l_kitchen is the 
		location identifier 
		that is used in the source code to refer to the kitchen. d_sys is the so 
		called 
		system description, 
		a list of friendly names for the location.
		Objects are items in the world that can be manipulated. Objects can be 
		moved around and may contain other objects. At the top level, an object 
		is contained in a location.
		Example:
		$OBJECT o_lamp
		 DESCRIPTIONS
		   d_sys   “the lamp”, “the flashlight”, “the brass lantern”
		
		 CONTAINED on o_table
		END_OBJ
		o_lamp is the 
		object identifier 
		that is used in the source code to refer to the lamp. The 
		contained line 
		tells which object or location holds the lamp. In this example, the lamp 
		object is 
		on the 
		table object. The table object is defined elsewhere in the source and is 
		referred to by its 
		object identifier here.
		XVAN has four predefined objects:
		
		Timers are used to trigger events at certain moments. The moment is 
		determined by a threshold value.  At the end of each turn, all timers 
		are updated according to the instructions stored with the timer. If the 
		threshold value is reached, the timer will trigger an associated chain 
		of actions.  Timer 
		ids have 
		format m_timername.
		
		m_battery
		   value 100
		   step 1
		   direction down
		   interval 1
		   state go
		   trigger_at 0
		   execute o_lamp.t_empty
		This timer will count down until it reaches zero and then executes the 
		lamp's t_empty trigger. 
		XVAN has no default start routine when the interpreter starts , but a 
		timer can be used to kick off the story.
		Create a timer with value 0 
		that triggers at value 1. After the interpreter starts the story, the 
		timers get updated and the timer initiates a series of actions that display 
		the opening screen etc. 
		
		   value 0
		   step 1
		   direction up
		   interval 1
		   state go
		   trigger_at 1
		   execute o_player.t_init
		Trigger t_init will print the game's opening message, start the moves 
		counter and perform other initial activities for the story.
		In order to run the game, locations and objects use Descriptions, Flags, 
		Attributes and Triggers.
		 
 
		Action records will be described later on in this document.
		Descriptions are blocks of text. A 
		description identifier is 
		used to refer to the description in the source code. 
		Description identifiers have 
		format d_descriptionname.
		Example:
		d_exa_locked "The old chest seems to be locked."
		About text strings
		So, as we are creating Interactive Fiction works, text will be an 
		important part of the story. Text strings can be long, which makes the 
		story’s  source code harder to read. XVAN has a number of mechanisms to 
		format text strings so the story source is easier to read, without 
		affecting the way how the string is printed.
		Each string must end with a “ or a /:
		All carriage returns and spaces after a ‘/’ will be ignored up to the 
		next non-<cr>-or-space character.
		Example:
| d_long_descr | " | This is a very very long description that / | 
| goes on and on and on over several / | ||
| lines in the source file, but it will print / | ||
| as one line on the screen.” | 
Will print as:
		This is a very very long description that goes on and on and on over 
		several lines in the source file, but it will print as one line on the 
		screen.”
		The same effect can be achieved by ending the string with an end quote 
		and start a new string on the next line. Consecutive strings will be 
		combined to 1 string.
		Example:
| d_long_descr | "This is a very very long description that” | 
| “ goes on and on and on over several“ | |
| “ lines in the source file, but it will print” | |
| “ as one line on the screen.” | 
Will print as:
		This is a very very long description that goes on and on and on over 
		several lines in the source file, but it will print as one line on the 
		screen.
		String formatting characters:
		The following string formatting characters are available:
		Example:
d_descr "This is a string with a \n, a \t, a \” and a \\ in it.”
Will print as:
		This is a string with a 
		, a , a “ and a \ in it.
A flag can be either up (true) or down (false).
		Flag identifiers have 
		format f_flagname. 
		Examples of situations where a flag would be used by a location or an 
		object to keep track of things are:
		
		Attributes are used to store information that is dynamically generated 
		during the game (i.e. not known at compile time) and that must be used 
		at a later moment in the game.
		Attributes can be used to remember different types of information:
		
		Attribute identifiers have 
		format r_attributename. 
		An attribute can remember all of the above types, but it will keep track 
		of the type that you put in.
		When an attribute is used as a parameter in a function, the interpreter 
		will check if the attribute type matches with the function parameter.
		Example:
		r_some_item = o_lamp
		move(r_some_item, o_player)    # moves the lamp into the player’s 
		inventory.
		
		r_some_item = 10
		move(r_some_item, o_player)    # will cause a runtime error
		Both lines will be accepted by the compiler because at compile time it 
		is unknown what will eventually be put in the attribute. It’s the 
		author’s responsibility to prevent runtime errors.
		Examples of the use of attributes are:
		Triggers are small programs – written by the story author or in a 
		library – that allow locations and objects to manipulate their flags and 
		attributes and print information.
		Locations and objects have  triggers 
		depending on the tasks they must perform.
		
		Trigger identifiers have 
		format t_triggername.
		An example of a trigger defined with an object:
		$OBJECT o_lamp
		 DESCRIPTIONS
		  d_sys   “the lamp”, “the flashlight”, “the brass lantern”
		  d_exa  “An ancient lamp made of brass.” 
		
		 CONTAINED on o_table
		
		 FLAGS
		  f_lit = 1
		
		 ATTRIBUTES
		  r_power_left = 100
		
		 TRIGGERS
		   “light [o_lamp]”  -> t_light
		
		  
		t_light
		     # the user has indicated he wants to light the lamp
		     IF testflag(f_lit) THEN
		       printcr("But the lamp is already lit!")
		     ELSE
		       setflag(f_lit)
		       printcr("Ok, the lamp is now lit.")
		     ENDIF
		END_OBJ
		Words like printcr, testflag and setflag are functions that perform 
		specific tasks.
		For example, the function setflag() sets the indicated 
		flag to value 1. XVAN has several functions that can be used to write 
		the story.  
		There is a separate document with detailed descriptions of the functions 
		that are available in XVAN. The functions document is quite large, but 
		it is intended as reference when you need information on how a specific 
		function works and what parameters it expects. It is not for reading 
		cover to cover, you may just flip through it to see what’s available.
		The same t_light trigger, but now combined with the earlier described 
		timer m_battery (bold italic parts), 
		to make the behavior of the lamp object a bit more realistic:
		t_light
		  # the user has indicated he wants to light the lamp
		  IF testflag(f_lit) THEN
		   
		printcr("But the lamp is already lit!")
		  ELSE
		    IF equal(m_battery, 0) THEN
		     
		printcr("Nothing happens. The battery must be empty.")
		   
		ELSE
		     
		setflag(f_lit)
		     
		starttimer(m_battery) 
		 # start draining the battery
		     
		printcr("Ok, the lamp is now lit")
		
		    ENDIF
		
		 
		ENDIF
		  agree()
		There are descriptions, flags, attributes and triggers for which it is 
		obvious that they will be necessary for all locations and objects. For 
		example, a description d_exa that contains the text to be printed when 
		an object is examined. Or a trigger t_look that allows an object or 
		location to print a description about itself when the user types ‘look’.
		Such common artifacts need only be defined once in a dedicated section 
		of the story file. The compiler will then add them to each object and 
		location. The definition is a default definition for all locations and 
		objects. When necessary a common definition can be simply redefined by 
		defining it again locally in a location or object. This 
		local definition 
		will then replace the 
		common definition.
		Locations and objects use triggers to respond to certain events. The 
		actual data for the event (which objects, which location, which 
		direction, etc) will be determined during play time. XVAN has the 
		possibility to use wildcards in trigger code that will be filled in with 
		the actual data when the trigger is executed. 
		Following wildcards are available:
		The %-character is to allow XVAN to tell the wildcards from normal 
		vocabulary words when used as function parameters. When used in a 
		string, wildcards must be put in [  ] and the '%'-sign may be omitted.
		Examples:
		move(o_subject, %this)
		"There is [a] [this] here."
		The following function example is not valid:
		move(o_subject, this) # this must be written as move(o_subject, %this).
		An example of using wildcards
		t_wildcard_example
		 
		# This trigger illustrates the use of wildcards
		 
		# This trigger is fired by all user input with syntax
  # “ask [o_fred] 
		about [o_specifier]”
		
		 
		# Suppose the user has entered the command
  # ‘Ask Fred about the dial, 
		then
		 
		# during execution of the trigger [o_specifier] will be
  # substituted with 
		‘dial’
		 
		# This makes that we only need to define the trigger 
  # once to work for 
		all objects.
		
		  IF equal (o_specifier, o_dial) THEN
		   
		printcr(“The keys with 3, 5, 6 and 9 are a bit more worn than the 
		others.“)
		  ELSE
		   
		printcr("I don't know anything about the [o_specifier]!")
		  ENDIF
		 
		agree()     # let other objects react
		XVAN has a number of predefined descriptions, flags, attributes and 
		triggers. They are used internally by the interpreter but are also 
		available to the story author.
		Following description is predefined:
		Following flags are predefined:
		Following attributes are predefined:
		Following triggers are predefined:
		To interact with the player, XVAN needs a vocabulary. It is best to 
		store  XVAN’s vocabulary of words in one or more separate files, so it 
		can be used with multiple stories by including the vocabulary files in 
		the story file. The idea is that this vocabulary file grows with each 
		new story that you write so XVAN will learn more words with each new 
		story and existing words can be reused.
		
		A word section starts with the section keyword, followed by the words. 
		E.g:
		$PREPOSITIONS
		at, behind, in, on, under
		A word section – and other sections as well – can be in any file, as 
		long as it starts with the section keyword.
		XVAN has an understanding of the syntax of English (and Dutch) sentences 
		so it is able to evaluate the user’s input.
		XVAN allows words to be of more than one type. For example ‘light’ can 
		be:
		When parsing user input, the parser starts with the first available type 
		for each word. In case a syntax error is encountered during the parsing 
		process, XVAN has a trial-and-error mechanism  to deduce a valid input. 
		It will go back one step and see if the conflicting word has another 
		type that might fit.
		So, for example,  the sentence “light light light” 
		is valid user input (meaning “ignite the not so heavy lamp”).
		For verbs, extra functionality can be coded. Verbs  may have their own 
		actions, comparable to triggers. These actions will be used as a default 
		scenario. In case none of the locations or objects responded to the user 
		input, the verb’s actions will be searched for a match.
		It is good practice to not refer to specific locations or objects but 
		use wildcards (this, actor, subject, specifier, etc) to ensure that the 
		vocabulary remains independent of specific stories.
		A verb can have a prologue. Before the user input is offered to the 
		locations and objects, the interpreter checks if there is a prologue for 
		the verb. If so, the prologue will be executed. A possible result of the 
		prologue is that the input will not be offered to the locations and 
		objects.
		Example of a prologue for the verb ‘look’:
		PROLOGUE
		  If not(islit(o_player)) then
		   
		printcr(“It is pitch black.”)
		   
		disagree()   # stop further processing user input
		  ELSE
		   
		agree()        # let locations and objects react
		A verb’s epilogue (if present) will be executed after all locations and 
		objects have had the opportunity  to respond to the user’s input.
		Example of an epilogue for the verb ‘close’:
		EPILOGUE
		  # they may have closed the object with the light source in it
		 
		IF not(islit(o_actor)) THEN
		   
		printcr(“It is now pitch black.”)
		  ENDIF
		  agree()
		In case none of the locations and objects respond to the user input and 
		there are no default actions defined with the verb, the verb may have a
		
		default 
		default action defined. The purpose of this default is to have a sort of 
		last resort response available so the user doesn’t get the feeling the 
		author forgot to implement something.
		In case the verb does not have a default section, the interpreter will 
		not print a response.
		Example of default section for the verb ‘charge’:
		DEFAULT
		  printcr(“I only understood you as far as wanting to charge 
		something.”)
		  agree() 
		
		$verb inventory SYNONYM i # 'i' may be used as a synonym for inventory
		 PROLOGUE
		   printcr(“You are carrying:”)
		   indent(2)  # from now on, the indent() function will print 2 white 
		spaces
		   agree()
		
		# after the prologue and before the epilogue, all locations and objects 
		will respond to the command
		
		EPILOGUE
		 indent (-2)                               # remove indent
		
		DEFAULT
		  # in case there were no responses, the default section will be 
		executed.
		  printcr(“Nothing, you are empty-handed.”).
		ENDVERB
		The location’s and object’s responses to the “inventory” command could 
		be coded in the story file as the following common trigger:
		
		  IF owns(o_player, %this) THEN
		    printcr(“[a] [this]”)
		  ELSE  # player is not carrying this object
		   
		nomatch()  # Return nomatch() to inform the interpreter to forget this 
		object had
		     # a matching action record. Otherwise the verb default code will not
		     # be executed.
		The above example shows that there's no loop or similar construction to 
		list the inventory. The prologue prints an opening message and then each 
		location and object will decide to contribute or not. If nobody 
		responds, the verb default section will respond.
		There is some hierarchy, however. The location will always be the first 
		to receive the user input and containing objects go before their 
		contained objects.
		XVAN wants to give full control to the author. But if you don’t want to 
		create your own framework and build everything from scratch, there is 
		the Library that contains predefined verbs, flags, triggers and 
		vocabulary words to handle most common tasks. 
		The Library is described in separate documents.
		As of version 2.3.2, XVAN also supports the Dutch language (next to 
		English). There are two keywords that you can use in story files to 
		select the language:
		XVAN_LANGUAGE tells 
		the compiler the language of the programming interface. If set to Dutch, 
		all XVAN keywords like if, then, else, prologue and functions like 
		IsLit(), CanSee(), Owner() are replaced by Dutch translations. Also, the 
		error messages are translated.
		STORY_LANGUAGE tells 
		the compiler and interpreter in which language the story must be played. 
		The story language is stored in the compiled file, so the interpreter 
		knows which state machine to select to parse input text.
		An example:
		# XVAN language sample
		
		TITLE “Sample to show language selection”
		VERSION “1.0”
		
		XVAN_LANGUAGE english # may also be eng or engels
		STORY_LANGUAGE nederlands # may also be nl or dutch
		
		XVAN consists of a compiler and an interpreter (and a language 
		definition).
		The compiler needs an input file with the story (locations, objects, 
		timers etc) and the vocabulary (verbs, nouns, adjectives etc). The 
		compiler supports multiple files, but one file must be leading.
		It is 
		advised to use separate files for things that can be reused with other 
		games. E.g, create a separate vocabulary file with generic verb 
		definitions that can be reused with new stories. Game specific code is 
		put in the main story file. In earlier versions from XVAN the separate 
		vocabulary file was mandatory.
		From the input file(s), the compiler creates an output  file that 
		contains the complete story in binary format. The output file can be 
		played using the interpreter.
		The interpreter reads the output file created by the compiler and offers 
		the user a prompt (‘>’) to enter commands to play the story. 
		
		For each 
		turn, the user will enter a sentence at the command line. E.g. "Open the 
		mailbox", "Take the leaflet", etc. This sentence will eventually cause 
		locations and objects to execute certain triggers to progress the game. 
		How do locations and objects know which trigger corresponds to the 
		user's input? This is where action records come in.
		When the story was compiled and the output file was created, the 
		compiler created and stored so called action records for the objects and 
		locations.
		An action record is a standard set of data with information about:
		
		Such information is of the format:
		"unlock [o_chest] with [o_key]” -> t_unlock
		
		In the above example the compiler will create an action record in the 
		output file with:
		and link it to the trigger t_unlock.
		This action record will be stored with the location or object.
		When playing the game,  the interpreter ‘disassembles’ (parses) the 
		user's input line and creates an  action record from it.
		
		The interpreter 
		will offer the action record to each location and object. The locations 
		and objects will search through their own set of action records and will 
		try to find a matching record. If a matching record is found, this 
		record will contain information on the trigger that must be executed.
		With this mechanism, XVAN can turn the user's input into a series of 
		triggers that will be executed by locations and objects.
		
The above is a simplified description of the mechanism; it explains the basics, but there's more to it.
		To elaborate a little bit, the 
		interpreter doesn't actually offer the action record to all locations 
		and objects from the story, only to those that qualify (are in scope). 
		An object may tell the interpreter to stop offering the action record to 
		other objects, an object or location may tell the interpreter to ignore 
		that it had a matching action record so a default trigger will be 
		called, etc, etc.
		Verbs also have action records. In case none of the locations or objects 
		respond to an action record, the interpreter will check the applicable 
		verb whether it has a matching action record with default code to handle 
		the user input in a more general way.
		It is advised to keep the verb 
		code as general as possible (default messages), so a verb can be used 
		with different story files.
		From the above examples, it shows that the interpreter imposes 
		priorities in executing the action record created from the user input. A 
		graphical representation  of the evaluation priority mechanism is 
		depicted in the Syntax document.
		In a bullet list, the evaluation priority is as follows:
		The interpreter will:
		Depending on the outcome of a step execution of further steps may be 
		cancelled.
		Sometimes the user input will contain insufficient information for the 
		parser to determine which object(s) the user is referring to: an 
		ambiguous command. In such a case, the interpreter will ask for 
		additional information so it can map the command to the right objects.
		Consider this:
		
		Which cube do you mean? The red cube, the green cube or the blue cube?
		
		> red
		Red cube: taken
		Nothing wrong with that. But now consider the following:
		
		There is a red cube here.
		There is a green cube here.
		
		> I
		You are holding:
		  a blue cube.
		  a yellow cube.
		  a lamp (providing light)
		
		> drop cube
		Which cube do you mean? The red cube, the green cube, the blue cube or 
		the yellow cube?
This makes less sense. The interpreter also asks about the red and green cubes although the player isn't holding them. We want some way to tell the interpreter that an item must be held before it can be dropped.
		This 
		is where disambiguation rules come in.
		Disambiguation rules are defined in the verb code..
		
		….
		 
		"[o_actor], drop [o_subject]"
		    DISAMBIGUATION_RULES
		     
		if owns(o_actor, o_subject) then score(5)
		    END_RULES
		    if not(owns(o_actor, o_subject)) then
		      printcr("But [the] [o_actor] is not holding [the] [o_subject].")
		    else
		     move(o_subject, owner(owner(o_subject))
		   
		endif
		…..
		ENDVERB
		
		If there are disambiguation rules, the parser will create one action 
		record for each possible actor, subject and specifier. In our cube 
		example, 4 action records will be created with different subjects.
		Each action record is then ran by the disambiguation rules. An action 
		record can earn points if it complies with the rules. In the end, the 
		action record with the most points wins.
		The number of created action records can be large. Suppose we have 2 
		possibilities for the actor, 3 for the subject and 3 for the specifier 
		then the parser will create 2 x 3 x 3 = 18 action records.
		In the example, the disambiguation rules tell the parser that a 
		situation where the actor holds the subject gets 5 extra points. If 
		there are more winners, the interpreter will ask the user, but only for 
		the winners (in our example only for the blue and yellow cubes).
		It is important to realize that the disambiguation rules will only be 
		executed in case the interpreter cannot decide which item the user 
		means.
		Again, in our example, if the user would type 'drop red cube' 
		although he is not holding it, the interpreter would not consult the 
		disambiguation rules, because it can map the text 'red cube' to one 
		unique object. That's why we still need the code after the END_RULES 
		keyword in the verb default code.
From version 2.5, XVAN supports plurality. Plurality implementation is based on the following starting points:
		
This defines oxen and cattle as plural for ox. All actions released on the oxen/cattle will be split up into actions for each individual ox. E.g, in case there are three oxen, “examine oxen” would be similar to “examine white ox, grey ox, black ox”.
		
		There is a red cube here
		There is a green cube here.
		
		> i
		You are holding:
  a blue cube.
  a yellow cube.
  a lamp (providing light).
		
		> get cubes
		red cube: taken.
		green cube: taken.
		
		> drop cubes
		blue cube: dropped.
		yellow cube: dropped.
		red cube: dropped.
		green cube: dropped
The disambiguation rules exclude the blue and yellow cubes from the ‘get’ action.
The 
		interpreter will always try to bind nouns and adjectives from the user 
		input to objects and locations in the story. If it cannot find a 
		matching object or location it will print a “You cannot see that here…” 
		message.
But what if 
		we have a valid expression whose noun cannot be bound to an object? E.g 
		“Get some rest”, “hit the road” (go on your way) or the like.
		
		We don’t want something like:
		
		You don't see that here.There is a green cube here.
		
		> 
		
So, in order 
		to deal with this we have:
		
		
		An example:
		
  if equal(%action, hit) and equal(r_unbound, road) and equa
     l(o_spec, %none) then
     printcr("Please use compass directions to move.")
    agree()
  endif
  if equal(%action, get) and equal(r_unbound, rest) and equa
    l(o_spec, %none) then
    printcr("Resting costs you 2 moves.")
    wait(2)
    agree()
  endif
  disagree()
		>
		
		This ends the explanation of XVAN’s basic concepts. In the Syntax 
		document, examples of a larger location, object and verb are included, 
		as well as the layouts for story files.
		A detailed description of all of XVAN’s available functions is available 
		in a separate document.
		
.