For Twinery.org 2.0 Harlowe. Reference guide
This part of the guide is more for advanced use and more advanced routines from the reference guide. Because of this, I’ll be describing the use of what’s going on instead of a step by step guide of a “Let’s Code”.
For understand the basics of Twinery, check out the first post here: Part 1: Basics
::Your Pocket
(print: “**Pocket**”)
(if: $pocket) [
(if: $pocket’s sword > 0)[Swords: (print:$pocket’s sword)]
(if: $pocket’s flint > 0)[Flint: (print:$pocket’s flint)]
]
(else:) [
(set: $pocket to (datamap: “sword”, 0, “flint”, 1))
]
So, “Your Pocket” has a few things going on with it. It’s meant to do two things, initialize $pocket if you don’t have one and print your inventory when you do have a $pocket.
(if: $pocket) […]
(else:)[ (set: $pocket to …)]
if the pocket exists do something
(if: $pocket) […]
otherwise, create a pocket with some value
(else:) [(set: $pocket to …)]
In this case, we’re setting $pocket to:
(set: $pocket to (datamap: “sword”, 0, “flint”, 1))
which has attributes of “sword” and “flint” with a count to your inventory 0 and 1, respectively’
So next time “Your Pocket” gets displayed:
(if: $pocket) [
(if: $pocket’s sword > 0)[Swords: (print:$pocket’s sword)]
(if: $pocket’s flint > 0)[Flint: (print:$pocket’s flint)]
]
Your $pocket should exist and if you have any stock of your inventory (e.g. flint):
(if: $pocket’s flint > 0)[Flint: (print:$pocket’s flint)]
It’ll be printed that you have something.
:: Something about Swiglers Family
(display: “Your Pocket”)
{
(if: $pocket’s sword <= 0) [
Swiglers family was a bit dim, as their batteries didn’t power their ideas. [[Sniglers Life]]
]
(else: $pocket’s sword > 0) [
[[Oh, you can now venture forward. You have stuff|Start Adventure]]
]
}
(display: “Your Pocket”)
Display the contents of “Your Pocket”, which the first time it’s called will initialize $pocket with flint.
(if: $pocket’s sword <= 0) [Swiglers family was a bit dim, as their batteries didn’t power their ideas. [[Sniglers Life]]
]
When we don’t have a sword, we get a certain block of text linking to passage “Sniglers Life”
(else:) [
[[Oh, you can now venture forward. You have stuff|Start Adventure]]
]
If we have a sword, then we get a different text block linking leading us to “Start Adventure”
::Sniglers Life
Life Was Bland
A large rock was outside you’re house.
{
[You go and look under the rock]<looking|
(mouseover: ?looking)[
(replace: ?looking)[
But you found a sword
(set: $pocket’s sword to 1)
(display:”Your Pocket”)
[[Go back a few steps|Something about Swiglers Family]]
]
]
}
[You go and look under the rock]<looking|
The text “You go look under the rock” is displayed to the screen, but it has what’s called a hook, which we labeled as “looking”.
[You go and look under the rock]<looking|
(mouseover: ?looking)[
(replace: ?looking)[
“Something here”…
]
]
We hooked “looking” with an action “mouseover”. When we run our mouse over this text, it “replaces” the text blob that was hooked with whatever is within the “Something here”
[You go and look under the rock]<looking|
(mouseover: ?looking)[
(replace: ?looking)[
But you found a sword
(set: $pocket’s sword to 1)
(display:”Your Pocket”)
[[Go back a few steps|Something about Swiglers Family]]
]
]
In this case, you print some stuff, add a sword to you inventory, show your inventory, and display a link back to “Something about Swiglers Family”
So when you take the link back to “Something about Swiglers Family”, you now have a sword in your inventory, so it should look a bit different now.
The Hinterlands
:: Start Adventure
(display: “Hinterland Enemies”)
You’ve encountered something already?! you idiot…
(set: $next_loc to “Hinterland’s End”)
(display: “Combat Start”)
This block should be a bit straight forward.Show the “Hinterland Enemies” passage, set the variable $next_loc to “Hinterland’s End”, show the “Combat Start” passage. $next_loc is meant to be the passage that you’ll be heading to after combat Is finished. You’ll see it in action in a bit.
::Hinterland Enemies
{
(print: “New Enemy has joined”)
(set: $hinterlandsGoose to (datamap: “name”, “goose”, “hp”, 5, “atk”, 1))
(set: $hinterlandsPoop to (datamap: “name”, “poop”, “hp”, 3, “atk”, 2))
(set: $enemy to (either: $hinterlandsGoose, $hinterlandsPoop))
}
This block is generally standard for the most part. Set up different enemies for the area giving them properties like a name, health points and attack damage. The interesting line of code is this:
(set: $enemy to (either: $hinterlandsGoose, $hinterlandsPoop))
Because what it does is it randomizes what your encounter is. $enemy gets set to either goose or poop. At least you don’t need to write your own randomizer for this, however if you want a weighted randomizer then you’ll need a bit more intricate code (later on)
::Enemy Info
Enemy: (print: $enemy’s name)
Hp: (print: $enemy’s hp)
Not much going on here. This is the part of code to show the enemies name and hp
:: Combat Start
(display: “Enemy Info”)
[[Attack|Attack Loop]]
[[Run Away|Flee]]
Again, not much interesting going on here. The enemy has appeared and we can see what it is. What do we do, attack or run? If we attack, then we move to the more interesting “Attack Loop”
::Attack Loop
(set: $enemy’s hp to $enemy’s hp – 1)
(if: $enemy’s hp <=0) [
(print: $enemy’s name) has been killed!
[You Murderer!]<shout|
(click: ?shout)[
(replace: ?shout)[
[[Flee the crime scene|Flee]]
]
]
]
(else:)[
(display: “Enemy Info”)
[[Attack|Attack Loop]]
[[Run Away|Flee]]
]
Assuming you start the attack loop, say the enemy attacks at the beginning of every turn and so do you. For simplicity, you don’t take damage, but you do take a swing at the enemy, so you take away from its health
(set: $enemy’s hp to $enemy’s hp – 1)
And you ask again, what do you want to do? Attack or Run?
(display: “Enemy Info”)
[[Attack|Attack Loop]]
[[Run Away|Flee]]
But the enemy isn’t invulnerable, so you need to check when the bloody thing is dead
(if: $enemy’s hp <=0) […
]
(else:)[…
]
So, what do you do when it is dead?
(print: $enemy’s name) has been killed!
[You Murderer!]<shout|
(click: ?shout)[
(replace: ?shout)[
[[Flee the crime scene|Flee]]
]
]
You’re stuck looking at its dead body until you get the wherewithal to flee the scene (after clicking on the “You Murderer!” link created, of course)
:: Flee
Why did you run?
We were only getting to the fun part!
(link-goto: “Moving on”, $next_loc)
Again, nothing really interesting except for this part:
(link-goto: “Moving on”, $next_loc)
Where when we set $next_loc from way back in “Start Adventure” passage dictating to us that we can go to “Hinterland’s End” Passage next.
I did this because we are able to separate out the attack loop section from the rest of the “story” so they don’t become tightly dependent on each other.
The only dependencies are $enemy and $next_loc, and if they are set, then we can use the “Combat Start” loop at any point in the story and we can return to where we need to go.
We can even make combat encounters randomized by an if check like this:
(set: $combatRand to (random: 1, 10))
(if: $combatRand > 8) [(display: “Combat Start”)]
(else:)[
Something’s supposed to happen here.
]
A similar sort of randomizer can be used to weight when enemy you want to encounter.
(set: $combatRand to (random: 1, 10))
(if: $combatRand > 8) [(set:$enemy to $hinterlandsGoose)]
(else:)[(set:$enemy to $hinterlandsPoop)]
:: Hinterland’s End
Something looks funny about this place
Nothing interesting to say here, just a placeholder for more stuff to happen in the story.
Putting it all together looks something like this:
Here’s the project for this so you can load it up and not type the same thing over again. Download for you Lazy Butts.
There was a reason why I put the time in to writing up a tutorial for Twinery, but I’ll get to that in another post.
Twitter: @GIntrospection
1 Pingback