0 votes
by (160 points)
edited by

My Harlowe 2 game has a frame that always displays all your current stats in little text-based bar graphs like this:
Stress:
| _ _ _ _ _ _ _ _ _ 9 |
Health:
| _ _ _ _ _ 5 _ _ _ _ |

Additionally, the numbers are colored green when good and red when bad, AND the previous level your stat was at is displayed small and grey.

I draw them with for loops, but it is currently very slow to load each new page. There are 5 stats all being rendered this way.

I'd like help optimizing this code if possible:
 

Stress:
{
|(for: each _i, 0,1,2,3,4,5,6,7,8,9)[
 (if: $Stress is _i and $Stress < 4)
     [(color:green)[(print:$Stress)]]
 (else-if: $Stress is _i and $Stress > 6)
     [(color:red)[(print:$Stress)]]
 (else-if: $Stress is _i)
     [(print:$Stress)]
 (else-if: _i is $Stress - $StressC)
     [(color:grey)+(textstyle:"subscript")(print:$Stress-$StressC)]]
 (else:)[_]] |
}

($Stress is the current value of that stat, and $StressC is its previous delta)

1 Answer

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

This is such a simple implementation, I don't think you need anything other than a handful of (set:) macros, really:

Stress: {
(set: $meter to '_________')
(unless: $stress < 1 or $stress > 9)[
    (set: $meter's ($stress) to (text: $stress))
]
(if: $stress < 5)[
    (set: $stressColor to (colour: 'red'))
]
(else:)[
    (set: $stressColor to (colour: 'green'))
]
$stressColor[|$meter|]}

If you only want to change the color of the number and not the whole bar, you can do that, too.  It's a bit more annoying, and a bit hack-y, but it's probably how I'd do it:

Stress: {(set: $stress to 4)
(set: $meter to (a: '_', '_', '_', '_', '_', '_', '_', '_', '_'))
(if: $stress < 5)[
    (set: $stressColor to (colour: 'red'))
]
(else:)[
    (set: $stressColor to (colour: 'green'))
]
(unless: $stress < 1 or $stress > 9)[
    (set: $meter's ($stress) to '$stressColor[' + (text: $stress) + ']')
]
|(print: $meter.join(''))|}

You can add your delta code the same way, with (set: $meter's ($Stress - $StressC) ...).  I forgot about it and didn't test it out, though.

by (160 points)

That was perfect. I was able to get it working and it is definitely faster. Thanks!

This is what it ended up as (I added +1s to the meter sets to get 0 position in the meter):

Stress:
{(set: $meter to (a: '_', '_', '_', '_', '_', '_', '_', '_', '_', '_'))
(if: $Stress > 6)[(set: $Color to (colour: red))]
(else-if: $Stress < 4)[(set: $Color to (colour: green))]
(else:)[(set: $Color to (colour: white))]
(set: $meter's ($Stress + 1) to '$Color[' + (text: $Stress) + ']')
(unless: $StressC is 0)[
(set: $meter's (1 + $Stress-$StressC) to '(color: grey)+(textstyle:"subscript")[' + (text: $Stress-$StressC) + ']')]
| (print: $meter.join(' ')) |}

 

...