Twine Tuesday: Dynamically Adding Passages

[At the beginning of this month, I started writing a series of tutorials covering different tools for creating interactive fiction. The first of these was on Twine and, through three different parts, I wrote nearly 30 pages (of mostly pictures) beginning with the Start passage up through writing macros to go along with the four videos I made too. However, I haven’t written anything here about Twine.

That is going to change right now as I’ve decided to start posting different macros, functions, and CSS tricks I’ve picked up along the way — and even some I’ve created myself. I’m not sure if I will be able to maintain a schedule of a new post every week, but all these will be part of the category ‘Twine Tuesday‘.]

Normally, for passages to exist in Twine, they have to be created within the editor and produced as part of a HTML file. Some branching can happen between passages, but it is driven by variables and conditional statements. Everything has to be made beforehand.

Through the Twee API, it is possible to access the Tale object (which holds the passages) and use its functions to get() and loopup() different passages. However, while this allows a developer to change content in existing passages, there isn’t a method to add passages to the Tale object after the HTML file is produced. That is what this code does.

By using the prototype property of all JavaScript objects, the Tale object can be augmented to have the addPassage() function. Through adding an element to the page and then to the passages array within the Tale object itself, a new passage can be added to the story dynamically. However, this does not change the content of the current passage.

To do that, a macro is needed. By calling “addLink” with the parameters of the new passage’s title and its content, the addPassage() function can be called on the current instance of the Tale object and the new passage can be added to the page. By making a new Wikifier object, a link can be added in place of the macro in the passage which invoked it. Combining the two adds a passage to the overall story and a new link to that passage with the use of the macro.

Note: This does not work with the Sugarcane StoryFormat. It also bypasses the History object, so rewinding and restarting may not work as expected.


:: Start
<<addLink "A new link" "All new content. Pretty cool, right?" >>

:: script [script]
Tale.prototype.addPassage = function(title,tags,content) {
	var newPassage = document.createElement("div"); = title;
	newPassage.innerHTML = content;

	this.passages[title] = new Passage(title,$(title));


macros['addLink'] = {
	handler: function(place, object, parameters)	{
   		new Wikifier(place, "[["+parameters[0]+"]]");