Skip to main content

Harlowe's Input Problem: A Text Input Tutorial

Harlowe has a problem...


For a writing format within Twine 2 that boasts its simplicity, and user friendliness it lacks in one key area: HTML accessibility. For a writer to present an input option for a player they are often bogged down with the limited, and clunky (prompt:) macro.

When an author wants to gather information from a player more often than not they have to execute the (prompt:) macro, and in doing so the player is presented with something like this:

a white box that has the title "First Name:" and an input line

While it has the desired effect for some people, it's not very integrative to the page itself. It's a separate pop up that might just be a turn off for the reader.

So after countless hours of digging, and researching, and collaborating I've come up with a fairly simple solution.

First I created a new Twine file, now if you need help with this this article really isn't a good place for you to start so I'm going to send you over to the Twine Website, and the Harlowe Documentation to brush up a little first.

I named this new story "Bandits and Snakes", and I wanted my user to have the ability to name their bandit and snake sidekick.

Editing your story's JavaScript is key to this whole ordeal so what you need to do is copy/paste/(edit if you dare) this line of code into your "Edit Story JavaScript" option:

window.Harlowe = { 'State' : State };
window.processInputElements = function () {
    $('input[data-varname]').on('change', function () {
        var varName = $(this).attr('data-varname');
        Harlowe.State.variables[varName] = this.value;
    });
};
[Massive thanks to TheMadExile for writing this up for me]

Within this we've established that now whenever the user inputs any text into the variable varName it'll convert the text so that the Twine engine can read it, and utilize it properly within the Harlowe format.

Your next order of business should be setting up your passage.

In your passage you need to establish what input type you want presented, and what you want the variable name for that input type to be. For this example we are using a text input type, and that text is going to be accessed by the banditName, and snakeName variables. This is what I wrote in my passage titled "name":

Howdy there, traveler! Would ya kindly tell me your name and 
the name of that little critter there?
Bandit's Name:
<input type="text" data-varname="banditName">\
<script>processInputElements();</script>
Snake's Name:
<input type="text" data-varname="snakeName">\
<script>processInputElements();</script>
(link-goto: "Done", "aBandit")

Remember that (prompt:) macro pop-up I showed you earlier? Well, this is how seamless the input type form looks now:


And believe it or not, it works exactly the same as the (prompt:) macro does in terms of functionality. On the next passage I wrote: 

You mean to tell me that you are *the* $banditName?! 
And that this is your trusty sidekick, $snakeName?! 
Well, I'll be a son of a gun!

I went ahead and named my bandit Billy Bob, and his pet Rattler. So when the names are typed in it displays just like this:


Now I never trust players to follow directions so I tend to have a default name tucked away. To set this up is a piece of cake. At the end of your (link-goto:) macro just add this little tid bit:

(link-goto: "Done", "aBandit")[(if: $banditName is 0)
[(set: $banditName to "Rick")](if: $snakeName is 0)
[(set: $snakeName to "Stripes")]]

So that if the player decides not to select a name they won't be faced with that awkward "0" in place of their character's name but rather "Rick", and "Stripes".


There ya have it, folks! Keep an eye out for my Radio Button Input tutorial next!

Comments