Development Diaries

Twine: escape line breaks with backslashes

Update: The Javascript on this page is now built into Twine 1.4! It is no longer necessary to install it.

As you know, one of the most prominent difficulties with mixing code and prose in Twine games is the handling of line breaks. If you have a bunch of macros interspersed in your prose, especially <<if>> macros, then the temptation is to leave them on separate lines from the text, for readability. However, the line breaks adjacent to these macros end up appearing in the rendered passage.

The <<silently>> macro is the 'official' solution...

<<silently>>
<<set $hp -= 1>>
<<set $dead = true>>
<<endsilently>>
Wrap up all of the macros in it and the line breaks will be suppressed. But, it seems to me to be a half-effective solution, requiring two large macro tags enclosing each block, and disallowing <<print>> macros within it.

I've previously advocated a different solution, involving the TiddlyWiki comment syntax:

/%
%/<<set $hp -= 1>>/%
%/<<set $dead = true>>/%
%/
This has the advantage of allowing the use of <<print>> macros. But it, too, is authorially and visually unwieldy, requiring both the end and beginning of lines to be tagged with one of two similar-looking tags.

However, I believe it's on the right track. Right now, my proposal is to directly borrow the syntax of the C language's preprocessor - a single backslash at the end of a line suppresses the line break:

<<set $hp -= 1>>\
<<set $dead = true>>\
You are \
<<if $hp gt 1>>
hale
<<else>>
almost dead
<<endif>>.
In my opinion, this has much more convenience compared to the other two.
Here is the script code to enable this in your stories:

Obsolete script removed: use Twine 1.4

To recap, when you install this script:

  1. A line that reads:
    You have \
    twenty dollars.
    ...will be rendered as "You have twenty dollars."
  2. A line that reads:
    You have \
    <<set $cash = "twenty">>\
    <<print $cash>>\
    dollars.
    ...will be rendered as "You have twenty dollars."

Feel free to report any bugs to @webbedspace.

Healy's picture

Good Comics Journalism and Robin will Never Die: Comics Alliance is being shut down

Dunno how many of you keep up with the funnybooks, but word spread out on Monday that AOL is shutting down Comics Alliance. I don't really count myself as part of the comics "scene" anymore, but the news was still just an absolute shock for me. I mean, earlier this year 1Up was shut down and my reaction was pretty meh, but they close Comics Alliance and I'm all HOLY MOTHER OF GOD SHIT SHIT NO

That must say something about me, I think.

Anyway, because I am mad autistic and don't want to see the whole site just up and disappear one day, I'm making a personal archive of the site, mostly my favorite articles and junk. Attached is part one of the Remedial Batmanology series, covering the Burton films; they're are some of my favorite comics writing (even though it's mostly just two nerds gettin' mad about Batman, go figure). This is pretty grey market, so I'd suggest you read the articles on Comics Alliance's website while it's still up.

vampirkat's picture

Birthday Trainwreck

I was making a game for GT's bday and had two weeks to get on it... but real life got in the way (yay freelancing life)... gonna submit it soon... at least my main screen looks tight :D i'll upload my game soon

The Minimalist Game

I don't have time to make anything substantial for Ludum Dare this weekend, so I decided to port NOM3RCY's classic text adventure, THE MINIMALIST GAME, to Twine.

I added a few bells and whistles. First, the scoring works unlike in the original game, and second, the order of the possible responses are randomised each time you play! REPLAY VALUE.

I couldn't submit it to the actual site because it's a port of someone else's game. :(

ENJOY.

Twine: example uses for <<revision>>

The <<revision>> macros provide a good deal of expressive power, though some potential uses may not be immediately obvious. Here are a few examples which may provide some inspiration.

An extended form of <<cyclinglink>>

This combination of <<cycle>> and <<set>> changes a variable every time you cycle the passage using the link.

<<cycle attire>>
<<set $shirt="red">>[<img[redshirt.png]] You eagerly slip on a red shirt.
<<becomes>>
<<set $shirt="blue">>[<img[blueshirt.png]] No! Clearly, a blue shirt is required.
<<becomes>>
<<set $shirt="vermillion">>[<img[yellowshirt.png]] Nope, it ''has'' to be vermillion! Or so you think...
<<endcycle>>
<<revise attire "Reconsider shirt">>

A music picker

This uses my HTML5 sound macros to create a link that changes the currently playing music when you click it. (If the music isn't meant to loop, of course substitute <<loopsound>> with <<playsound>>)

<<cycle music>>
<<stopallsound>><<loopsound "piano.ogg">>Piano music
<<becomes>>
<<stopallsound>><<loopsound "chiptune.ogg">>Chiptune music
<<becomes>>
<<stopallsound>><<loopsound "acapella.ogg">>A capella music
<<endcycle>>
<<revise music "Change current music">>

More info / Less info

This functions similar to <<replace>> but also provides a link to hide the inserted text after it's been shown.

<<revision info>>You see here a spotted stripe frog.<<revise info "(More info)">><<gains>>
Poisonous in 3 countries and illegal contraband in 7, this fearsomely shaded amphibian is an aesthetic and biological terror.
<<revert info "(Less info)">>
<<endrevision>>

More examples to come...

Twine: loading jQuery without editing the HTML

Update: Twine 1.4 now lets you load jQuery via a StorySettings option, so this page is no longer necessary.

You can load jQuery into your Twine game via Google Hosted Libraries using this simple script code:

Obsolete script removed: use Twine 1.4

Change whatever you want the function passed to ready() to do.
Notes:
* Since Twine's engine uses '$' for something, jQuery must sadly relinquish that convenient abbreviation.
* Due to a minor bug, Twine's runtime currently doesn't work at all in IE 8 or below, so there's not much reason to use jQuery 1.9 over 2.0
* Using Google Hosted Libraries of course means that people can't play your game without a live internet connection - which, in the extremely rare chance you intend your Twine game to be available offline, should be borne in mind. Nevertheless, it can be more convenient for you, the author, due to not having to provide the jQuery file yourself.
Feel free to report any bugs to @webbedspace.

Twine bugfix: "and" and "or" in strings in <<set>>, <<print>> and <<if>>

Update: this has been fixed in Twine 1.4, so this is no longer necessary.

As you know from reading my macro reference, code parameters passed to <<if>>, <<set>>, <<print>> and <<remember>> have their operators ("and", "or", "$", "not", etc.) converted to Javascript equivalents ("&&", "||", etc.) when they're executed.

But, due to a bug, this conversion is also applied to "operators" that are inside strings passed to these macros. So, <<print "Vast and large">> will print "Vast && large", and <<print "You find $10">> will print "You find state.history[0].variables.10".

Now, I've sent out a pullreq to the Twine GitHub repo that fixes this, but in the meantime, if you're stymied by this bug, you can fix it with this script:

Obsolete script removed: use Twine 1.4

Again, note that in some versions this will be loaded after the Start passage has rendered.

Version history:
* 2/7/13 - Bugfix for "She's cute" string.
* 5/5/13 - Bugfix.
* 25/4/13 - Initial.
Feel free to report any bugs to @webbedspace.

Twine macro: <<hoverrevise>>, a mouseover extension to <<revise>>

The <<hoverrevise>> macro is an extension of the <<revision>> / <<revise>> macros. It lets you make a span of passage text briefly appear or disappear whenever you mouseover another span of text in the same passage.

Code

Just install the latest version of <<revision>> (1.1.0 or later). It's included already.

CSS

You may want a "dissolve" type of transition to be applied to the text that appears or disappears. For that, give the <<insertion>> or <<removal>> macro a name that, say, contains "hover", and then use this CSS to exclusively target it:

.revision-span-in[class*=hover] {
	opacity: 0;
}
.revision-span[class*=hover] {
	transition: 1s;
	-webkit-transition: 1s;
}
.revision-span-out[class*=hover] {
	position:absolute;
	opacity: 0;
}

If you aren't using any normal <<revise>> macros, you could omit "[class*=hover]" to make every <<revision>> span have this transition.

Usage examples

Use this in conjunction with <<revision>>, <<insertion>> or <<removal>> spans, as you would with <<revise>>. The <<hoverrevise>> macro covers a full span of text, ending with <<endhoverrevise>>

To make the text "Aah! A ghost!" appear when you mouseover a span:

<<insertion hoverghost>>Aah! A ghost!<<endinsertion>>
<<hoverrevise hoverghost>>You'd better [[go to the chapel|chapel]]<<endhoverrevise>>

To make the text "Don't leave me" disappear when you mouseover a span:

<<removal words>>"Don't leave me"<<endremoval>>
<<hoverrevise words>>[[Go to the beach|beach]]<<endhoverrevise>>

To make the text "Cold" change to "Warm" when you mouseover a span:
<<revision hovermetal>>Cold<<becomes>>Warm<<endrevision>>
<<hoverrevise hovermetal>>[img[gold.png]]<<endhoverrevise>>

These are just a few of the possibilities allowed by this macro.

Notes:
This wraps the contained text in a <span> with the class "hoverrevise" as well as "hoverrevise_" suffixed with the identifier you use (for instance, "hoverrevise_boo" for <<hoverrevise boo>>").
Feel free to report any bugs to @webbedspace.

vampirkat's picture

Nearly there

I'm still mucking around with AGK. I got some of the files I need to test it on after a bit of digging, and having to update other files. I'm running out of room again on my computer, but a few deletes and some backups will free space.

About to go home, eat dinner, then code and see if my games compile for Android, and then I'm in business.

Twine macro: <<revision>> and <<revise>>

The <<revision>> macro is a more powerful variation of the <<replace>> macro. It lets you alter a span of passage text by clicking a link from anywhere in the passage.

Install my <<Replace>> Macro Set to use these macros.

Basic usage
First, use the <<revision>> macro to define two different versions of some text:

You see here <<revision tome>>a closed book.<<becomes>>an open book.<<endrevision>> Each section of text separated by <<becomes>> is a different "version" of the text. The name "tome" in the macro is an identifier. You can use any single word you want as an identifier.

Then, you can create a link using the <<revise>> like so:
<<revise tome "Open the book.">>
This creates a link reading "Open the book" that changes any "tome" revision in the passage into the next version - in this case, changing "a closed book" into "an open book".

(Notice that the word "revise" is the verb form of "revision", reflecting the fact that the hyperlink serves as a verb for the player to perform.)

Running code in revisions
Just like with <<replace>>, any macros inside a revision are run as soon as they are made to appear:

<<revision button>>You see a button.<<becomes>>The button is pushed.<<set $button=true>><<endrevision>>
<<revise button "Push it.">>

The above code will set $button to true when you click the "Push it." link.

Multiple versions
You can have many versions of a span of text:

You see here <<revision books>>a closed book.<<becomes>>a chewed book.<<becomes>>paper scraps.<<endrevision>>
<<revise books "Chew book">>

In this case, the link "Chew book" will change "a closed book" into "a chewed book", then "paper scraps". When it reaches the end, the link vanishes.

Back and forth
The <<revert>> macro functions to reverse the effects of the <<revise>> macro.

<<revision box>>Here is a closed box.<<becomes>>Here is an open box.<<endrevision>>
<<revise box "Open the box.">>
<<revert box "Close the box.">>

The <<revert>> macro's link won't be displayed if it's at the first revision, just as the <<revise>> macro won't be visible if it's at the last revision.

Cycling link text options (New)
The <<revise>> and <<revert>> macros have a number of additional options similar to the <<cyclinglink>> macro. You can supply additional link text strings after the first, and it will change to the next string after you click it.
<<revise wall "Smash wall" "Smash it again" "Keep smashing">>

If the second parameter begins with the "$" sigil, then it will interpret it as a variable to be altered by clicking the link. When the player clicks the link, the variable will be changed to match the text of the link.
<<revise heat $warmth "Set it to warm" "Set it to hot" "Set it to boiling">>

If the last parameter is the word "end", then it will disable the link at the parameter before last, leaving just the text. If the last parameter is the word "out", then it will vanish altogether once it's reached the final string.
<<revise roast "Devour roast" "Munch some more" "You're too full now" end>>
<<revise amphora "Drink wine" out>>

<<hoverrevise>>
Click here to read about <<hoverrevise>>.

<<becomes>> vs. <<gains>>
Just as the <<replace>> macro has a variation, <<insert>>, so too does <<becomes>>.

The vase contains:<<revision vase>>Two roses<<gains>>, an orchid<<gains>>, a pencil<<gains>>, a straw<<endrevision>>.
<<revise vase "Put something in the vase">>.

When you click "Put something in the vase", the text changes from "Two roses" to "Two roses, an orchid", then to "Two roses, an orchid, a pencil" and so forth.

You can mix and match <<gains>> and <<becomes>> at will:

<<revision count>>One<<becomes>>Two<<gains>>and a half<<becomes>>Three!<<endrevision>>

This changes from "One" to "Two", "Two and a half", and finally "Three!".

<<cycle>>
Normally, when a <<revision>> macro reaches the end of its revisions, its links disappear. If you change "revision" to "cycle", then you can keep clicking the link to return to the first revision.

You see here <<cycle pet>>a dog<<becomes>>a cat<<endcycle>>.
<<revise pet "Change pet">>

This will change "a dog" to "a cat" and vice-versa, with the link never expiring.

<<insertion>> and <<removal>>
Two other variations exist, which are roughly analogous to <<timedinsert>> and <<timedremove>>.
You look at the plate. <<insertion grain>>1 grain.<<becomes>>2 grains.<<becomes>>3 grains.<<endinsertion>>
For <<insertion>>, the first version "1 grain" is initially invisible. Clicking a <<revise>> link will make it visible. Then, it functions as normal.
You look at the plate. <<removal seed>>3 seeds.<<becomes>>2 seeds.<<becomes>>1 seed.<<endremoval>>
For <<removal>>, the <<revise>> link will remain when you get to "1 seed". Clicking it a final time will remove the text altogether.

Example program
http://www.glorioustrainwrecks.com/files/TwineMacro-RevisionTest.html

Technical details

  1. Each version inside a <<revision>> macro is a <span> classed with "revision-span" as well as the kind of version they are ("becomes", "gains"). When they appear, they are given the class "revision-span-in" and their display is set to "inline". When they disappear, they gain the class "revision-span-out" and, after 1 second, their display is set to "none". All of these are inside a container <span> classed with the name of the macro ("insertion", "removal", "cycle", "revision") and the name of the identifier ("book" or whatever the author set it to be).

Version history:

  1. 27-9-2013: Fixed several bugs, including:
    <<revision>> macros were being called twice on passage load.
    <<revision>> macros were still taking effect while they were animated being removed by other macros.
    Multiple <<revision>> macros with the same ID weren't all being revised at the same time.
  2. 16-6-2013: Updated regarding Combined Replace Macro Set.
  3. 26-4-2013: Added extra options to <<revise>>.
  4. 20-4-2013: Added <<hoverrevise>> and support for <<randomise>>.
  5. 18-4-2013: Initial

Feel free to report any bugs to @webbedspace.

Syndicate content