The Beast in the Castle Code Review

#Balancing Stats With Fairmath

###The Problem
Of course we know that numeric values have their uses, and one of those is tracking various sliding scale stats of the PC. Let’s take an example from from The Beast in the Castle again. If we look there’s a few stats we could use, so let’s start with a pretty obvious one: angry. Of course the first thing is the stat is *created, in this case the line is *create angry 0. Now let’s see it in use. (Note that I’ve reformatted and reduced these for the sake of the example.)

[details=First *choice]```
Your stomach growls. It’s times like this that you remember how different your life used to be.
Once upon a time, you didn’t know what it was like to be hungry.
You’d have taken a carriage through the rain.
Your house had twenty rooms, and all of them were clean. Dinner would have been ready.
There would have been hot coals waiting in your bed to warm your feet.

And now you have this.
*choice
#You miss that life.
*choice
#You try to make the best of things anyways.
#You’ll get that life back, no matter what stands in your way.
#Sometimes you think of ending it all.
#You don’t miss it.
*choice
#Hard as it is, you prefer your new life.
#There’s no sense in wanting what you can’t have.
#You think this is what you deserve.
#You try not to think about it.
*choice
#It makes you cry.
#It makes you angry.
*set angry +1
If life had continued as it had, for just a little longer, maybe you could have
escaped this hell. But no, no.
#There just isn’t a point.


[details=Second *choice]```
"She's here now. Poor girl, you're soaked through. Here, let me--" Father tries to sit up.
Half way through, he stops, a pained look on his face. His back is hurting again.
*choice
	#Help him.
	#Watch.
	#"Sit [i]down[/i]."
		*set angry +1
		Your father was once a swaggering sailor. But these past two years have aged him.
		Not enough good food, and too much strain on a body that has long since forgotten the sensation.
```[/details]

[details=Third *choice]```

You wonder what will happen when father comes back. [i]If[/i] he comes back.
All of this seems very suspicous, and your father's luck is poor.
He's made you so many promises in the past few years, each one broken after the next.
Do you resent him for what he's done to you?
*choice
	#Yes. You can't help it.
	#Yes. This is all on him.
		*set angry +1
		Father was too reckless.
		He put so much of his money into one single venture-- a trip to the Smoking Isles.
		If things had turned out, you would have been the richest family in the city.
		If. [i]Don't worry about it, these things always turn out right.[/i]
		Your father had enjoyed a lucky youth.
		How arrogant of him to think it would always be so.
	#No. He does his best.
	#No. You don't care enough. 
	#No. You love him too much.
```[/details]

Now, for the sake of completeness, lets talk a moment about balancing stats. The name of the idea speaks for itself, but essentially, you're going to want to come back at some point and check to how many players are hitting various stats, and balance them accordingly.

This means we're going to want to know on average, how many players see any given choice if they were to play randomly. For this, we're going to use [randomtest](https://www.choiceofgames.com/make-your-own-games/testing-choicescript-games-automatically/) (Make sure to turn on 'Show line coverage statistics').


----------
###Why It's a Problem
Now let's say we want to show a line to players that have a lot of anger (maybe a warning to calm down). We want the number of players that see it to be low enough that it's not too common (otherwise it loses meaning), but high enough that players actually get it. Let's put that at around 20% of players (remember, randomtest gives you estimates based on people playing randomly). Much lower and it's too common. Much higher and it's too rare to see.

So with that in mind, let's look at how many players get 0, 1, 2 and 3 anger points (out of a thousand iterations).

[details=This is the example code I used.]```
*temp angry 0

Your stomach growls. It's times like this that you remember how different your life used to be.
Once upon a time, you didn't know what it was like to be hungry.
You'd have taken a carriage through the rain.
Your house had twenty rooms, and all of them were clean. Dinner would have been ready.
There would have been hot coals waiting in your bed to warm your feet.

And now you have this. 
*choice
	#You miss that life.
		*choice
			#You try to make the best of things anyways.
				*goto choice2
			#You'll get that life back, no matter what stands in your way.
				*goto choice2
			#Sometimes you think of ending it all.
				*goto choice2
	#You don't miss it.
		*choice
			#Hard as it is, you prefer your new life.
				*goto choice2
			#There's no sense in wanting what you can't have.
				*goto choice2
			#You think this is what you deserve.
				*goto choice2
	#You try not to think about it.
		*choice
			#It makes you cry.
				*goto choice2
			#It makes you [i]angry[/i].
				*set angry +1
				If life had continued as it had, for just a little longer, maybe you could have
				escaped this hell. But no, [i]no[/i].
				*goto choice2
			#There just isn't a point.
				*goto choice2
*label choice2
"She's here now. Poor girl, you're soaked through. Here, let me--" Father tries to sit up.
Half way through, he stops, a pained look on his face. His back is hurting again.
*fake_choice
	#Help him.
	#Watch.
	#"Sit [i]down[/i]."
		*set angry +1
		Your father was once a swaggering sailor. But these past two years have aged him.
		Not enough good food, and too much strain on a body that has long since forgotten the sensation.

You wonder what will happen when father comes back. [i]If[/i] he comes back.
All of this seems very suspicous, and your father's luck is poor.
He's made you so many promises in the past few years, each one broken after the next.
Do you resent him for what he's done to you?
*fake_choice
	#Yes. You can't help it.
	#Yes. This is all on him.
		*set angry +1
		Father was too reckless.
		He put so much of his money into one single venture-- a trip to the Smoking Isles.
		If things had turned out, you would have been the richest family in the city.
		If. [i]Don't worry about it, these things always turn out right.[/i]
		Your father had enjoyed a lucky youth.
		How arrogant of him to think it would always be so.
	#No. He does his best.
	#No. You don't care enough. 
	#No. You love him too much.

*if angry = 0
	*comment Angry 0
*if angry = 1
	*comment Angry 1
*if angry = 2
	*comment Angry 2
*if angry = 3
	*comment Angry 3
*if (angry < 0) or (angry > 3)
	*bug
*ending
```[/details]

Running this, we get 46.7% getting 0 anger, 42.6% getting 1 anger, 10.2% getting 2 anger, and 0.5% getting 3 anger. Hm, there's no number in the line of what we want. This is where balancing comes in. The problem though, is with our stats using fixed increments, there's not a lot of balancing we can do. So how do we fix this?

----------
###The Solution

Well, with a few quick changes, we can switch to [fairmath](https://www.choiceofgames.com/make-your-own-games/important-choicescript-commands-and-techniques/). Let's make our starting value `50`, and all our increments `%+25` to start with. Then we start playing with numbers.

[details=What that looks like.]```
*temp angry 50

Your stomach growls. It's times like this that you remember how different your life used to be.
Once upon a time, you didn't know what it was like to be hungry.
You'd have taken a carriage through the rain.
Your house had twenty rooms, and all of them were clean. Dinner would have been ready.
There would have been hot coals waiting in your bed to warm your feet.

And now you have this. 
*choice
	#You miss that life.
		*choice
			#You try to make the best of things anyways.
				*goto choice2
			#You'll get that life back, no matter what stands in your way.
				*goto choice2
			#Sometimes you think of ending it all.
				*goto choice2
	#You don't miss it.
		*choice
			#Hard as it is, you prefer your new life.
				*goto choice2
			#There's no sense in wanting what you can't have.
				*goto choice2
			#You think this is what you deserve.
				*goto choice2
	#You try not to think about it.
		*choice
			#It makes you cry.
				*goto choice2
			#It makes you [i]angry[/i].
				*set angry %+25
				If life had continued as it had, for just a little longer, maybe you could have
				escaped this hell. But no, [i]no[/i].
				*goto choice2
			#There just isn't a point.
				*goto choice2
*label choice2
"She's here now. Poor girl, you're soaked through. Here, let me--" Father tries to sit up.
Half way through, he stops, a pained look on his face. His back is hurting again.
*fake_choice
	#Help him.
	#Watch.
	#"Sit [i]down[/i]."
		*set angry %+25
		Your father was once a swaggering sailor. But these past two years have aged him.
		Not enough good food, and too much strain on a body that has long since forgotten the sensation.

You wonder what will happen when father comes back. [i]If[/i] he comes back.
All of this seems very suspicous, and your father's luck is poor.
He's made you so many promises in the past few years, each one broken after the next.
Do you resent him for what he's done to you?
*fake_choice
	#Yes. You can't help it.
	#Yes. This is all on him.
		*set angry %+25
		Father was too reckless.
		He put so much of his money into one single venture-- a trip to the Smoking Isles.
		If things had turned out, you would have been the richest family in the city.
		If. [i]Don't worry about it, these things always turn out right.[/i]
		Your father had enjoyed a lucky youth.
		How arrogant of him to think it would always be so.
	#No. He does his best.
	#No. You don't care enough. 
	#No. You love him too much.

*comment These lines you'd have to play with to find what you're looking for.
*if angry >= 63
	*comment Angry 63
*if angry >= 62
	*comment Angry 62
*ending
```[/details]

To save time, I'll point out that we end up with much the same problem. Only 10% of players get a 63 or above (they select two angry options), while more than 50% of players get a `62` or above. So we stat by tweaking our numbers so there's a little difference between them.

Let's pick one of the numbers to raise the value of. If we look at that first one, there's only about a 1/9 chance a player will pick it, so it's pretty rare (and won't change the numbers much). Likewise, that second one is 1/3, which is pretty common, so it might change the numbers _too_ much. That leaves us with the third choice. If we think about it, we know that anyone that picks two angry `#options` right now will go over a `62`. If we raise the last one though (say to `%+30`), it alone will also trigger our extra line.

Let's test those numbers. If we run it now, 23.2% will get at least a `63`. That's still a bit high for what we want though, so let's give players a chance to bring their anger down a little. Let's look at that third `#option` on the third `*choice`. (`#No. He does his best.`). That looks like it's the opposite of angry. Let's give players a `%-25` for that (just for the sake of the example).

That will drop it down to 22.5% of players getting the extra line. Still a bit off, but we can already see how fairmath gives us more to play with in terms of balancing our stats. Of course there's other considerations (maybe `angry` should start at `10` and we should balance from there and we want smaller growth), but the premise stays the same.

[[Return to the first post]](https://forum.choiceofgames.com/t/the-beast-in-the-castle-code-review/22238)
2 Likes