Procedural Generation: Passage Manipulation
There are many different ways to approach procedural generation of content in Twine. This example covers adding and changing passages as a method to generate content.
<blockquote>
This example uses the SugarCube 2.21.0 story format.
</blockquote>
<<silently>>
<<set $numberOfLoops to random(3,6)>>
<<set $vowels to ['A', 'E', 'I', 'O', 'U', 'Y']>>
<<set $consonants to ['B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z']>>
<<set $locations to []>>
<!-- Generate Locations -->
<<for _i to 0; _i < $numberOfLoops; _i++>>
<<set _vowel to $vowels.random()>>
<<set _consonant to $consonants.random()>>
<<run $locations.pushUnique(_vowel + _consonant)>>
<</for>>
<!-- Create a 'Map' passage -->
<<addpassage "Map" "">>
<<set $links to "Locations:<br>">>
<!-- Build all the locations -->
<<for _i to 0; _i < $locations.length; _i++>>
<<set $links to $links + "[[" + $locations[_i] + "]]<br>">>
<</for>>
<!-- Update Map with locations -->
<<changepassage "Map" $links>>
<!-- Create new content and passages, linking back to map -->
<<for _i to 0; _i < $locations.length; _i++>>
<<set _content to "Now in: " + $locations[_i] + "<br>[[Back to Map->Map]]">>
<<addpassage $locations[_i] _content>>
<</for>>
<</silently>>
[[Map]]<<widget "changepassage">>
<!-- Find the passage in storage and change it -->
<<run jQuery('[name="' + $args[0] + '"]').text($args[1])>>
<</widget>><<widget "addpassage">>
<<script>>
// Get a reference to the storage area
var storyStorage = jQuery("tw-storydata");
// Get the number of passages
var numberOfPassages = storyStorage.children("tw-passagedata").length + 1;
// Create new 'tw-passagedata' with PID and NAME
// (We can set position and size to default values)
var newPassage = jQuery('<tw-passagedata pid="' + numberOfPassages + '" name="' + State.variables.args[0] + '" tags="" position="100,100" size="100,100"></tw-passagedata>' );
// Add new content to the new passage
newPassage.text(State.variables.args[1]);
// Add the new 'tw-passagedata' to the storage area
storyStorage.append(newPassage);
// Find the passage we just added in storage by name
var passageElement = document.getElementsByName(State.variables.args[0])[0];
// Create a new object
var newPassage = {};
newPassage._excerpt = null;
newPassage.classes = [];
newPassage.element = passageElement;
// Generate a lowercase name
// starting with "passage-" and
// replacing spaces with hyphens
var id = "passage-" + State.variables.args[0].replace(/\s/g, "-").toLowerCase();
newPassage.domId = id;
newPassage.title = State.variables.args[0];
newPassage.tags = [];
// Tell the new object to pretend it to a Passage object
Object.setPrototypeOf(newPassage, Passage.prototype);
// Add it to the Story object
Story.passages[State.variables.args[0]] = newPassage;
<</script>>
<</widget>>