0 votes
by (8.8k points)

I'm experimenting with an aggression meter.  This tracks how violently the PC or an NPC can act – if $pc.aggression lt 10 he might have the option to shove someone or shout a violent insult; if $pc.aggression gt 90 he might unlock the option to drive his thumbs into a foe's eyes.

So far, so good!  Now, I'd like to introduce some game-wide modifiers.  For example, if $pcTraits.contains("berserker"), I'd like all increases to $pc.aggression to be doubled.

Now I could do this with a lot of <<if>> statements, but I'm coming to appreciate the limitations of such a brute-force approach – it would require lots of duplication of code.  Is there a smarter way to tell the game to double any increases to $pc.aggression if $pcTraits.contains("berserker")?

1 Answer

+1 vote
by (62.7k points)
selected by
 
Best answer

I recommend using widgets to cut down on repeated code. That's 90% of the answer you're probably looking for. All following examples will do so, and the widgets are used like so: 

<<addAggression (number)>>

E.g. 
<<addAgression 4>>
/% adds 4 to aggression. if berserker trait is chosen, adds 8 %/

There's a few approaches you could try. Here's some of them. You could: 

  • Use a modifier. 
/% in StoryInit, set $aggressionMod to 1; when the perk is selected increase the mod to 2 %/

<<widget "addAggression">>\
    <<silently>>
        <<set _increase to $args[0] * $aggressionMod>>
        <<set $pc.aggression += _increase>>
    <</silently>>\
<</widget>>
  • Use the ternary operator (?). Works like an if/else. 
<<widget "addAggression">>\
    <<silently>>
        <<set _increase to ($pcTraits.includes("berserker")) ? ($args[0] * 2) : $args[0]>>
        <<set $pc.aggression += _increase>>
    <</silently>>\
<</widget>>

Note the use of "includes" instead of "contains". Contains is deprecated. 

  • Use <<if>> macros as you have been, but use widgets as shown above. 
<<widget "addAggression">>\
    <<silently>>
        <<set _increase to $args[0]>>
        <<if $pcTraits.includes("berserker")>>
            <<set _increase *= 2>>
        <</if>>
        <<set $pc.aggression += _increase>>
    <</silently>>\
<</widget>>

They all work fine, which one you use will likely depend on preference. 

by (8.8k points)

Thanks, Chapel.  Your idea of creating an <<addAggression>> widget is exactly the conceptual breakthrough I was lacking.

by (8.8k points)

Chapel, in your third widget example, what does this line do?

  <<set _increase to $args[0]>>
by (62.7k points)
Pretty much nothing. I tend to like to "unpack" the $args array into temp variables so they can have more appropriate names, that's all. I also like to do it first, so I know $args[0], i.e. the first argument, is the amount of the increase. Makes it easier for very complicated widgets with potentially a lot of arguments, but is totally unnecessary in all the examples above. More a habit for me, so my apologies if it's confusing.
by (8.8k points)
Thanks, Chapel.  :-)
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.
...