Include Vorple by Juhana Leinonen.
The Vorple core extension defines the basic structure that's needed for the story file to communicate with the web browser, as well as other low-level rules and phrases that other extensions use to add more features to Vorple.
Every Vorple story must include at least one Vorple extension and the custom web interpreter.
Include Vorple by Juhana Leinonen. Release along with the "Vorple" interpreter.
All standard Vorple extensions already have the "Include Vorple" line, so it's not necessary to add it to the story project if at least one of the other extensions are used.
In contrast to previous versions that were only for Z-Machine, version 3 of Vorple is for Glulx only. The project's story file format must be set to Glulx in Inform's Settings pane.
At the time of release of the current, third version of Vorple, the latest Inform release 6M62 includes the older version 2 of Vorple which is not compatible with the new extensions. The latest Vorple interpreter template is in the same package as these extensions.
Also note that old Vorple extensions are not compatible with the current version of Vorple. If you get en error message about an extension being for Z-Machine only, the project is trying to include an old extension.
Compatibility with offline interpreters
Even though Vorple can accomplish many things that are plain impossible to do with traditional interpreters, it's always a good idea to make the story playable text-only as well if at all possible. There are many players to whom a web interpreter or Vorple's features aren't accessible, and it's the Right Thing To Do to not exclude people if it's possible to include them.
A story file can detect if it's being run on an interpreter that supports Vorple. The same story file can therefore be run on both the Vorple web interpreter and other interpreters that have text-only features and display substitute content if necessary. We can test for Vorple's presence with
if Vorple is supported:
Instead of going north: if Vorple is supported: play sound file "marching_band.mp3"; otherwise: say "A marching band crossing the street blocks your way."
(The above example uses the Vorple Multimedia extension.)
The say phrase in the above example is called a "fallback" and it's displayed only in normal non-Vorple interpreters.
All Vorple features do nothing by default if they're not supported by the interpreter, unless otherwise stated in the extension's documentation. If substitute content is not necessary, we don't need to specifically check for Vorple compatibility:
Instead of going north: play sound file "marching_band.mp3".
Many Vorple features can be replicated at least to some extent on standard Glulx interpreters, but in general Vorple extensions don't try to use those Glulx features as a default fallback, but opt to printing plain text where applicable or doing nothing at all. Authors can use their choice of Glulx extensions and the above mentioned "if Vorple is supported" checks to make fallbacks that are most suitable for their story.
The command prompt
To gain more control over the command prompt, Vorple replaces the built-in prompt with its own. The process should be completely automated: changing the
command prompt variable should change the Vorple prompt as well, apart from some fringe cases where the source text or an extension does something exotic with the Glulx prompt. The prompt and the player's command are printed on the screen with custom techniques so they will not be included in the usual story output flow. It means that Glulx extensions that capture output text will not be able to read them.
The extension Vorple Command Prompt Control offers features to manipulate the command prompt and the interpreter's line input in general.
Embedding HTML elements
We can embed simple HTML elements into story text with some helper phrases.
place an "article" element; place a "h1" element called "title"; place a block level element called "inventory"; place an inline element called "name";
The previous example generates elements equivalent to this HTML markup:
<article></article> <h1 class="title"></h1> <div class="inventory"></div> <span class="name"></span>
The element's name should be one word only and a valid CSS class name. It's safest to only use letters, numbers, underscores and dashes.
Text content can be added on creation:
place a "h1" element called "title" reading "An exciting story"; place a "h2" element reading "Story so far:";
...or after the elements have been created:
say "You shall be known as "; place an inline element called "name"; display text "Anonymous Adventurer" in the element called "name";
This technique can be used to modify the story output later (see example "Scrambled Eggs").
If the text is included at the same time when creating the element, the default behavior in non-Vorple interpreters is to print the text normally. Text added later will not do anything. In other words,
place a "h1" element called "title" reading "An exciting story" will print "An exciting story" in all interpreters, but
display text "Anonymous Adventurer" in the element called "name" will not print anything in anywhere other than the Vorple interpreter.
In the above examples element contents should be plain text only. Trying to add nested tags or text styles will lead to erratic behavior. For longer and more complex contents the tags can be opened and closed manually:
Report reading the letter: open HTML tag "div" called "letter"; place "h2" element reading "Dear Esther,"; say "I'm writing to tell you..."; close HTML tag.
When there are multiple elements with the same name, only the last element will be updated. This is to accommodate repeat actions and specifically UNDO which can easily generate duplicate content. To modify all elements, use the following phrase:
display "Hello World!" in all elements called "greeting";
We can also test whether an element exists or not, or count the number of elements:
let n be the number of elements called "greeting"; if an element called "greeting" exists: ... if an element called "greeting" doesn't exist: ...
The extension Vorple Element Manipulation contains more tools for working with the HTML document.
Finally, the Vorple interpreter uses a concept called "output focus" to decide where it should print the story text. Any HTML element* can have the output focus, and any text coming from the story will be appended to the end of that element. For example we can have a separate element where the player's inventory is printed:
(* The element that has output focus must be able contain child elements, so void elements, for example
<hr>, can receive output focus but any output is ignored.)
Before taking inventory: set output focus to the element called "inventory". After taking inventory: set output focus to the main window; continue the action.
Set output focus to the main window returns the focus back to the default location.
Scrolling to elements
The page can be scrolled to bring a named element into view:
scroll to the element called "target";
The page then scrolls so that the target element's top is near the browser window's top. If the element is already fully visible on the page and its top position is on the top half of the window, the phrase does nothing.
A similar phrase can be used to scroll to the bottom of the page:
scroll to the end of the page;
There's also a shorthand phrase for testing for boolean return values:
The type of the return value can be retrieved with
Since version 3.1, the command must explicitly return a value with the "return" keyword for the expression's value to be readable in Inform. If the command returns nothing or undefined, the value of the last command that explicitly returned a value is still what you get when you query it with a
The above code will print "foo", because the second line doesn't explicitly return anything. In versions 3.0 and before the same code would have printed "bar".
To escape text we can prefix it with "escaped", which adds backslashes before characters that might cause problems inside strings:
By default escaping removes newlines. If we want to turn them into, for example, HTML line breaks, or just preserve them:
Remember to use
Escaping also turns Unicode characters (basically any characters that aren't letters a-z, numbers or common punctuation) into
\uXXXX format so that they can be passed to the browser intact. We'll have to escape any strings that contain e.g. accented characters:
Non-escaped Unicode characters show up in the output as question marks or empty squares.
User interface setup and updates
Vorple provides a separate rulebook called Vorple interface setup rules for setting up the user interface on the browser side. It runs during startup before the when play begins rules. The rulebook is meant for rules that build or initialize the user interface that has to be ready before the story does anything else.
The following example sets up a click handler that adds a custom CSS class to the command prompt. Depending on the CSS rule it might flash the prompt to draw attention to it.
There's a mechanism in place that prevents the interface setup rules from running more than once during one session, even if the player restarts the story. In other words the interface setup rules run only when the web page loads. This guarantees that we can't add duplicate event handlers by mistake or otherwise run things twice that should only be run once.
For keeping the web interface up to date there's a rulebook called Vorple interface update rules that's run at the end of every turn and after undoing a turn, restoring a save and restarting the game.
Blocking the user interface
If at some point we need to wait for a network request or some other asynchronous operation to finish before continuing with the story, we can prevent the player from doing anything in the meanwhile by blocking the user interface. When the user interface is blocked the player can't type or click on anything, but they can still scroll the page normally. The phrases to block and unblock the user interface are:
block the user interface; unblock the user interface;
vorple.layout.unblock() call, but the Inform 7 phrase is provided for cases where the script executes a parser command that causes the story to continue normally.
Note that manually blocking the user interface is necessary only in asynchronous operations, most notably network requests via Ajax. Normal synchronous code already blocks the user interface so the turn can't end before all code has been executed.
The example "The Sum of Human Knowledge" shows one use case where we might want to block the user interface: it takes some time for the request to Wikipedia to finish and we don't want the player to continue before the response has been shown on the screen.
Even though typing is disabled while the user interface is blocked, the command prompt is still visible by default (if the story is waiting for line input). In the extension Vorple Command Prompt Control there are phrases to hide the command prompt which can be used together with or instead of blocking the user interface.
Displaying the inventory styled as a HTML list
We'll display the inventory listing using HTML unordered lists ("ul"). It might not be immediately obvious why one would want to do this, but if the items are displayed in a proper HTML structure it's possible to use CSS to style them further.
Hints that are initially shown obscured and revealed on request
The hint system works by wrapping scrambled hints in named elements. Their contents can then be later replaced with unscrambled text.
The Grandfather Clock
Setting the story time to match the real-world time
The Sum of Human Knowledge
Retrieving and displaying data from a third party service
Here we set up an encyclopedia that can be used to query articles from Wikipedia. The actual querying code is a bit longer so it's placed in an external encyclopedia.js file, which can be downloaded here. Put the file in the project's Resources folder to include it with the release.
Note that the pause between issuing the lookup command and the encyclopedia text appearing on the screen is caused by the time it takes to send a request to and receive a response from Wikipedia.