Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Issues with ROT13

Hello! :D

I'm using twine 1.4.2 with Sugarcane and have been trying to use ROT13 to... well, obfuscate spoilers in the HTML source code. After clicking StorySettings -> checkbox with ROT13, test plays from then on refuse to run and instead give the following error message:

Traceback (most recent call last):
File "storyframe.pyo", line 907, in rebuild
File "tiddlywiki.pyo", line 188 in toHtml
File "tiddlywiki.pyo", line 507 intoHtml
File "tiddlywiki.pyo", line 495, in applyRot13
File "encodings/rot_13.pyo", line 20, in decode
UnicodeEncodeError: 'ascii'codec can't encode character u'\u2019' in position 409: ordinal not in range (128)


Any ideas on how to work around it? Thanks! :D


  • ROT13 only works on non-unicode (ASCII) characters, and somewhere in your text you have at least one fancy right single quote.

    There is no real benefit obfuscating your story because it is a trivial process for the Reader to undo but if you really want to do it then you will need to replace all unicode characters with their ASCII equivalents.
  • Oh okay, thanks!

    I was trying to make a lock requiring a password, but I realized that the answer could be found in the source code.. :/ is there any other function I could use instead of ROT13?
  • You could use a hash function to encrypt both the master password and the password the Reader inputs, and then compare the hashes.

    1. Place the following in the passage you use to story your Javascript, if you don't have one yet then right click on the Passage Map and select the New Script Here option.
    You can give the new passage whatever title you want, I name mine Scripts.
    note: There are bound to be better hash functions, but for this purpose this one will do.
    // source
    // source
    String.prototype.hashCode = function() {
    	var hash = 0, i, chr, len;
    	if (this.length == 0)
    		return hash;
    	for (i = 0, len = this.length; i < len; i++) {
    		chr   = this.charCodeAt(i);
    		hash  = ((hash << 5) - hash) + chr;
    		hash |= 0; // Convert to 32bit integer.
    	return hash;

    2. You need to determine what the hash is for your master password because you will need to hard-code that into your story. Use the following to generate a hash your master password, the master password of this example will be banana.
    note: Once you have done this you can (and should) remove the code in point 2 from the story.
    <<set $hash to "banana".hashCode()>>
    hash: <<print $hash>>

    3. You need to store the hash from point 2 into a variable in your StoryInit passage, you will use this variable later to compare the Reader's password.
    note: the hash of my master password was -1396355227, yours will be a different value.
    <<set $masterPassword to -1396355227>>

    4. Ask the Reader what they think the password is in one of your passages:
    note: In this example you will need to enter banana to be correct.
    Enter Password <<textinput $password "[[Check Password]]">>

    5. Check the Reader's $password against the $masterPassword in the Check Password passage, you can change the passage title but remember to also change it in the code in point 4. Also remember that the Reader may not of entered a value before clicking on the button in point 4.
    <<if $password eq "">>
    	<<print "Tell the Reader they need to enter a password">>
    	<<if $password.hashCode() is $masterPassword>>
    		<<print "Tell the Reader they got it correct">>
    		<<print "Tell the Reader they got it wrong">>
  • Awesome! Thanks for the help! :)
Sign In or Register to comment.