[This is the last scheduled Twine Tuesday post for awhile. I might come back to doing these later this year, but I don’t get the feeling that they are as helpful to others as they could be. It’s mostly just me posting my own code.]
For those following my weekly Twine projects, you may have noticed that I have become really interested in algorithmically generated stories lately. It’s taking some core text and having code, often randomly, make decisions about its placement, size, or even content. It’s also a trend I’m going to follow for a few more weeks too.
However, I thought I would point out something that has become key to these projects: passages can be storage. You don’t have to display passages written in Twine. They can, in fact, be used to hold content that will be reference via macros or with JavaScript.
For example, consider the following short passage:
:: HamletLines Well, God-a-mercy. Excellent well; you are a fishmonger.
They are lines 172 and 174 from Hamlet, Act 2, Scene 2. Normally, the paradigm is to create a link to that passage at some point. However, that doesn’t necessarily have to happen. Using that passage as storage, it could be referenced by a call to Tale.get() to retrieve its content and then used for another purpose.
var Hamlet = tale.get("HamletLines");
In fact, by placing special delimiters within the text of a passage, it can be parsed by calling String.split() to chop up a text and create an array of its lines. Everything that is in-between whatever that delimiter and the next instance of it is will become an index in an array. In turn, using a randomly chosen number or simply incremental counter, lines can be picked out and placed in another passage. (This technique has been around for a long time in various text parsers, but it didn’t occur to me to use it with Twine until a couple weeks ago.)
:: HamletLines Well, God-a-mercy. Excellent well; you are a fishmonger. Then I would you were so honest a man. Ay, sir; to be honest, as this world goes, is to be one man picked out of ten thousand. :: PoloniusLines Do you know me, my lord? Not I, my lord. Honest, my lord! That's very true, my lord. I have, my lord. ... macros['dialogue'] = { handler: function(place, object, parameters) { var Hamlet = tale.get("HamletLines"); var Polonius = tale.get("PoloniusLines"); H_wordList = Hamlet.text.split(" "); P_wordList = Polonius.text.split(" "); } }
Combining this with calling Tale.add(), as I have done in the full example, would allow for new passages to be added with the text from each of the characters. Using setInterval() then breaks up the dialogue over time.
Source:
:: Start <<dialogue>> :: script [script] (function() { var line = 0; var H_wordList = []; var P_wordList = []; var text = ""; Tale.prototype.add = function(title,tags,content) { var pTitle = unescape(encodeURIComponent(title)); var el = insertElement($("storeArea"),"div",pTitle,"",content); el.setAttribute("tiddler",pTitle); el.setAttribute("tags",tags); el.setAttribute("modifer","twee"); var newP = new Passage(pTitle,$(pTitle)); this.passages[title] = newP; if(tags === "stylesheet") { addStyle(newP.text); } else if(tags === "script") {try {eval(newP.text);} catch(e) {alert("There is a technical problem with this story (" + newP.title + ": " + e.message + "). You may be able to continue reading, but all parts of the story may not work properly.");} } }; var dialogue = function() { if(line < 11) { text = "''Hamlet:'' " + H_wordList[line]; tale.add("Hamlet"+line, "", text); state.display("Hamlet"+line, null); text = "''Polonius:'' " + P_wordList[line]; tale.add("Polonius"+line, "", text); state.display("Polonius"+line, null); line++; } }; macros['dialogue'] = { handler: function(place, object, parameters) { var Hamlet = tale.get("HamletLines"); var Polonius = tale.get("PoloniusLines"); H_wordList = Hamlet.text.split(" "); P_wordList = Polonius.text.split(" "); timer = setInterval(dialogue, 7800); } } }()); :: HamletLines Well, God-a-mercy. Excellent well; you are a fishmonger. Then I would you were so honest a man. Ay, sir; to be honest, as this world goes, is to be one man picked out of ten thousand. For if the sun breed maggots in a dead dog, being a god kissing carrion,--Have you a daughter? Let her not walk i' the sun: conception is a blessing: but not as your daughter may conceive. Friend, look to 't. Words, words, words. Between who? Slanders, sir: for the satirical rogue says here that old men have grey beards, that their faces are wrinkled, their eyes purging thick amber and plum-tree gum and that they have a plentiful lack of wit, together with most weak hams: all which, sir, though I most powerfully and potently believe, yet I hold it not honesty to have it thus set down, for yourself, sir, should be old as I am, if like a crab you could go backward. Into my grave. You cannot, sir, take from me any thing that I will more willingly part withal: except my life, except my life, except my life. :: PoloniusLines Do you know me, my lord? Not I, my lord. Honest, my lord! That's very true, my lord. I have, my lord. How say you by that? Still harping on my daughter: yet he knew me not at first; he said I was a fishmonger: he is far gone, far gone: and truly in my youth I suffered much extremity for love; very near this. I'll speak to him again. What do you read, my lord? What is the matter, my lord? I mean, the matter that you read, my lord. Though this be madness, yet there is method in 't. Will you walk out of the air, my lord? Indeed, that is out o' the air. How pregnant sometimes his replies are! a happiness that often madness hits on, which reason and sanity could not so prosperously be delivered of. I will leave him, and suddenly contrive the means of meeting between him and my daughter.--My honourable lord, I will most humbly take my leave of you. Fare you well, my lord. :: style [stylesheet] body { background: #333333; } .passage { font-size: 3.1em; background: transparent; color: white; width: inherit; } .passage .title { display: none } h1 { color: white; font-size: 3.3em; } #sidebar { display: none;} #footer {display: none;} #floater { display: none; } :: StoryTitle Hamlet: Act 2, Scene 2, Lines 172-218