Implementing an RPG Class System in Harlowe

+1 vote
asked Jul 13 by Lucario (220 points)
I'm trying to set up what would amount to an old school rpg. I want to have a class system where the player can select their class at the start, and whatever class they chose will determine what piece of text shows up in any particular passage. I'm assuming this could be achieved by using an if/else statement, but I'm having trouble getting it to work. I will admit that I am inexperienced with Harlowe. I'm only allowing for three classes at the moment, (mage, knight, rogue) and I feel like it would be simpler to be able to use a single passage, but account for the class variable, instead of having to have completely different passages for each individual class. Any help would be much appreciated.

 

~Lucario

2 Answers

+1 vote
answered Jul 14 by Hexalby (940 points)
selected Jul 14 by Lucario
 
Best answer
The best way I think is to use datamaps. Datamaps are similar to arrays but allow you to give a name to each array cell.

In other words you can have: (set: $mageClassBaseStats to (datamap: "HP", 20, "Mana", 50, "Strenght", 1, "Intelligence", 3))

Then you can assign this values to the player's datamap:

(if: $chosenClass is "mage")[ (set: $player to $mageClassBaseStats)]

and check the values during combat or dialogue checks:

(if $player's intelligence > 3)[(you manage to solve the riddle)]

 

You can easily manage your enemies this way as well, even outright recycling the datamaps and just changing the names. Then since you can have arrays (or datamaps) of datamaps you can keep all of them in a single easily accessible entity.

If you want you can spawn an enemy from said array:

(set: $activeEnemy to (either: ...$enemyList))

(Either: chooses one of the elements of the list you provide after, while "..." writes down all values of $enemyList so that you don't have to write (either: $enemyList[0],  $enemyList[1], etc...)\)
commented Jul 14 by Lucario (220 points)
You are officially my new best friend. I was considering using datamaps for this very thing, but this is the most clear and concise explanation I have seen about them thus far. I have looked up a few tutorials, and everyone made it sound way too complicated. It'll take some time to get them all set up, but it sounds like it'll make my life so much simpler in the long run. Praise be to Hexalby!
0 votes
answered Jul 13 by geekdragon (1,150 points)

I expect some more experienced coders may have a more elegant solution, but I can certainly imagine coding it in the way you suggest:

(if: $class is "mage")[
    Mage things happen!
](elseif: $class is "knight")[
    Knight things happen!
](elseif: $class is "rogue")[
    Rogue things happen!
]

You can use this structure to replace a single word, display unique options, replace paragraphs, or segregate entire passages, depending on your plans and needs. It really depends on how much you need to customize each class experience, and how much code will be common between classes.

commented Jul 13 by Lucario (220 points)
See, that was what I was thinking, and it was what I tried to implement first. For instance, say the player selects the mage class. It takes them to another passage that has this:

(set: $class to mage)
(if: $class = mage (set: $hp to 10))
(if: $class = mage (set: $gold to 50))

and when run I get an error stating that "mage" is undefined, and two secondary errors stating the the "mageMacro" is unrecognized.

Then when I have all three passages link back into another passage I have this code set-up:

 

(if: $class = mage) [You sit in your favorite chair, pondering the implications of your latest magical studies. You consider that it might be important for you to apply what you've learned in the field.]

[Your health is currently at $hp and you have $gold gold.]

(elseif: $class = knight)[You sit in the barracks at the Castle of Twin Moons, praying for the blessing of Lunara, the Goddess of the moon before your patrol. Violent attacks have been on the rise, and the Knights of the Order have been hard pressed to keep everything under control.]

[Your health is at $hp and you have $gold gold.]

(elseif: $class = rogue) [You sit at a desk in your personal office, counting the gold that you made off the recent sale of some stolen gemstones. You prefer the term "liberated", but you know that semantics don't change the reality of what you're doing. You hear a distant bell ring, and realize you are going to be late for a meeting with an important client.]

[Your health is at $hp and you have $gold gold.]
 

And it shows all the specific comments, but before each is an error that reads "(elseif)'s 1st value is a to or into and should be boolean."

I'm convinced that it has to be something stupidly simple that I'm overlooking, but I obviously can't spot it on my own. *shrugs*

 

~Lucario
commented Jul 14 by Hexalby (940 points)
You're missing the quotes around "mage" and "rogue". TwineScript ses mage and thinks it's a macro because it's neither a string nor a number, so it gives you back the error "no macro of that name found"
commented Jul 14 by Lucario (220 points)

Awesome, that fixes my first issue, and I was able to solve the second one on my own. Like I said above, it was something stupidly simple that I had overlooked. Thank you so much for your help guys! laugh

commented Jul 14 by Chapel (30,160 points)
edited Jul 14 by Chapel

FYI. There's a number of issues with your syntax in addition to missing quotes. You're using = when you should be using 'is', and you should be using hooks with your ifs and sets, not nesting them. 


(if: $class is 'mage')[(set: $hp to 10)]

= is the JavaScript operator that Harlowes 'to' operator is based on, which is why you're getting error messages about using to/into in your if macros. 

Also, there really shouldn't be white space between your hooks (if:) style macros and their associated hooks []. 

commented Jul 14 by Lucario (220 points)
Thanks for the heads up Chapel. I had already realized what I had done as far as the "=" instead of "is". It was like 4am when I had originally set that part up, and I was tired out of my mind.

However when it comes to nesting vs. hooking, I wasn't aware that there was a huge difference as far as Harlowe was concerned. I had looked up examples of what others had done, and everything I saw was nested, so I just figured that was standard for Harlowe.

In all honesty I haven't really done any coding at all since 2012, and I find that it's sort of like speaking a foreign language, if you don't practice using it regularly you forget a lot.
Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...