The Beast in the Castle Code Review


#1

So you may remember a while back I asked for games to use as examples to help develop some of our author’s code. Well @iris has graciously allowed me to use her work in progress The Beast in the Castle as an example game. Below are a series of quick jumps to various spots in this dissection, or if you want to read my notes in full, you can just scroll down.


#2

The Usefulness of Comments

Now, when writing your game, on of the easiest commands to overlook in terms of usefulness is *comment. At first glance, it doesn’t do anything other than hide a line, but when used well, it can make things a lot easier on you.

Let me be clear here, at some point, you’re going to want someone to read your code. Preferably, you’re going to want a few people to read your code. There are a lot of little errors which can creep in no matter how good you are that no amount of automated testing, nor regular beta testing will find.

So, for example, @iris did one thing I always love, which is to break down her *create commands into categories and label them. This one in particular jumped out at me:

*comment BEAST STUFF
*create withbeast false
*create beast 0
*create freaction 0
*create freactionshow 0

Why did this jump out? Well it jumped out because I saw one variable that I didn’t understand: freaction. My first though was free action? However, I wasn’t sure. That prompted me to do a quick search for it through the rest of her game, so that I could know what the variable was for, and I found seven instances of it being used, twice in *ifs, and five times in the same *choice. The choice was the obvious place to look:

[details=Code has been shortened to just the parts that matter.]```
[The PC first sees the Beast, then a few NPCs react, then this *choice shows up.]

You are…
*choice
#Terrified.
*set freaction +1
#Confused.
*set freaction +2
#Frozen.
*set freaction +3
#Angry.
*set freaction +4
#Fascinated.
*set freaction +5


Well, considering this is the only `*choice` where the stats change, and that the stat numbers are sequential, it's apparent that the specific numbers don't matter, but the choices do. Looking for context clues around the `*choice` I found it was the first time that the PC was reacting to the beast, which clued me in on what the variable was, that is the PC's `f`_irst_`reaction` to the Beast.

Now, obviously, this is a minor instance, but it's a good indicator of how even a few `*comment`s can really help someone read your code. Likewise anyone that's come back to a project after a few months can tell you that this can help _you_ read your own code too. However, that `*choice` brings up the first critique I have...

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

#3

Types of Variables and Why They Matter


###The Problem
If you’re already experienced with coding in ChoiceScript, your probably know there are three distinct types of things you can *create a variable as or *set it to:

  • String *create name "Jessie"
  • Numeric *create intelligence 50
  • Boolean *create has_tools true

Additionally you probably know that each has it’s own uses, for example:

  • You can display a ${name} with strings.
  • You can add to a number: *set intelligence + 50
  • You can check a boolean just by: *if has_tools

What you might not be aware of is why it’s important to pick the right tool for the job though. Let’s take our above example:

*choice
	#Terrified.
		*set freaction +1
	#Confused.
		*set freaction +2
	#Frozen.
		*set freaction +3
	#Angry.
		*set freaction +4
	#Fascinated.
		*set freaction +5

###Why It’s a Problem
Let’s say we continue coding and find that a lot of beta testers want another #option included, say, they want the PC’s first reaction to also be #Happy. However, when we look at that list, it doesn’t seem to work well with #Happy at the end, so lets add it in the above #Angry.

*choice
	#Terrified.
		*set freaction +1
	#Confused.
		*set freaction +2
	#Frozen.
		*set freaction +3
	#Happy.
		*set freaction +4
	#Angry.
		*set freaction +5
	#Fascinated.
		*set freaction +6

That looks right, right? Well it does until we test our game and find out that all our happy reactions act as though they’re angry now, and our angry PC is actually fascinated. Obviously this is an easy fix, but tracking down errors is time consuming and once we start adding all the other variables and stat checks, it can get much more difficult.


Okay, so that’s one reason, but let’s say we’re careful and make sure to always keep our variables correctly valued. Well, we still have another reason to make sure to use the correct type of variable. One thing that’s you’re going to do is pare down choices that don’t do anything.

One of the best ways to get your game to do well is replayability. (If you play it once or twice, you’re not likely to rate it in the stores or mention it to people, but if you play it twenty times, you’re much more likely to engage in the community, right?) Well to do that, you’re going to sometimes want to remove or condense choices that are essentially the same. Let’s say we test our game a bit and find that #Frozen and #Confused aren’t really that different in playthroughs and we decide to combine them. Our code would look something like this:

*choice
	#Terrified.
		*set freaction +1
	#Frozen.
		*set freaction +3
	#Angry.
		*set freaction +4
	#Fascinated.
		*set freaction +5

(Note that we avoid the previous mistake of changing the values of our variables.)

Well, in this case the mistake is less obvious at first glance. Let’s say we continue coding for a few months, and down the line we want to add a scene where the Beast comments on how our first reaction was that the PC was angry. Well, we know our three options are now Terrified, Frozen, Angry, or Fascinated, and Angry is the third one, so we write:

*if freaction = 3
	*goto foo

Again, we see a problem. We’re off by one. If the PC is Frozen, they act as though they were Angry. Of course we can mitigate this by having a list of every *choice and #option in our game, but that’s hardly a good answer. Games can have hundreds of *choices (and even if we just use systems like this sparingly, that can still be dozens for a long game).


###The Solution
Well, we’ve seen why you don’t want to a numeric variables to track a series like this, and we can obviously see why a boolean won’t work, so that leaves us using strings. Just to be sure though, let’s double check how both of those above scenario works with strings. First, let’s update our original code:

[details=Updated Code]```
*choice
#Terrified.
*set freaction “terrified”
#Confused.
*set freaction “confused”
#Frozen.
*set freaction “frozen”
#Angry.
*set freaction “angry”
#Fascinated.
*set freaction “fascinated”


Then we can add our new option:

[details=#Happy Added]```
*choice
	#Terrified.
		*set freaction "terrified"
	#Confused.
		*set freaction "confused"
	#Frozen.
		*set freaction "frozen"
	#Happy.
		*set freaction "angry"
	#Angry.
		*set freaction "fascinated"
	#Fascinated.
		*set freaction "..."
```[/details]

Even _if_ we make the same mistake, by the time it comes to enter in our final `*set` we can see it. Additionally, we're more likely to catch the mistake as it happens. So, what about our other error? Well, let's remove the Happy `#option` and take out the Confused one along with it.

[details=No more #Confused]```
*choice
	#Terrified.
		*set freaction "terrified"
	#Frozen.
		*set freaction "frozen"
	#Angry.
		*set freaction "angry"
	#Fascinated.
		*set freaction "fascinated"
```[/details]

Then, months down the line, we add an `*if` that looks something like this: `*if freaction = "..."` and we realize that we either remember the values, or we have to check them. No small errors floating around, as we make sure everything is correct.

----------
###Advanced Coders
Now, advanced users may sometimes do the above, tracking which in a list of options a player has picked with a single digit. This has the same dangers as above (making mistakes which are difficult to hunt down), but can occasionally be used to condense your code (just a little bit).

Lets say in our previous example, we wanted all three of our first options to collectively be some kind of 'afraid', but considered each of them unique enough to still merit their own `#options`. Well, with the first set of code all we need to do is check: `*if fraction <= 3`.

Of course, you need to be careful, because if you _do_ make a mistake, you might end up saving yourself minutes now, only to cost yourself hours or even _days_ later.

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

#4

#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)

#5

#The Case Against Linebreaks

###The Problem
Now, as you write your game, you’ll probably notice that ChoiceScript uses a space between paragraphs rather than a first line indent (and if you’ve played ChoiceScript games on mobile devices you probably already know why that is). Additionally you might be able to understand why single line breaks in code don’t cause paragraph breaks (as a hint, try writing a paragraph where the second half is determined by a previous choice, without copying the first part). Finally we can use *line_break to cause a new line with no space, so that it doesn’t look like a new paragraph (the same as <br> in html).

Putting all together these are our options:

If we just move down one line in code we get a space, but no paragraph break. So this code:

red
rum

prints this:

  1. If we want a new paragraph, we move down two lines while coding. So this code:
red

rum

prints this:

  1. If we want a new line, but no paragraph break, we use *line_break. So this code:
red
*line_break
rum

prints this:

However, there’s something I see done very commonly which is a mistake, which is spacing your paragraphs with double *line_break, so that your code looks something like this:

red
*line_break
*line_break
rum

which looks something like this:

Now, The Best in the Castle doesn’t do this directly. What I do see is a lot more of this (again, I’ve cropped the code to better highlight what I’m talking about):

"You won't have to come back here, if'n you don't want to."
He says with knowing eyes.
*choice
	#That sounds nice. 
		[...]Or you could finally get away...
		*goto dadhome
	#But you can't.
		[...T]here's your family to think about...
		*goto dadhome
*label dadhome
*line_break
*line_break
But now is not the time to make decisions for the future.
You're still waiting on your father's promise.
*page_break

###Why It’s a Problem
There’s two reasons to avoid this. The first is very obvious, which is to see what happens when you make a mistake counting *line_breaks:

"You won't have to come back here, if'n you don't want to."
He says with knowing eyes.
*choice
	#That sounds nice. 
		[...]Or you could finally get away...
		*line_break
		*line_break
		*goto dadhome
	#But you can't.
		[...T]here's your family to think about...
		*line_break
		*line_break
		*goto dadhome
*label dadhome
*line_break
*line_break
But now is not the time to make decisions for the future.
You're still waiting on your father's promise.
*page_break

[details=(It looks something like this:)][quote]The mountains are cold and craggy and dangerous. But it might be worth it, if the pay is good. And you are becoming quite proficient at hunting.

	You could probably send the money back home. Or you could finally get away...<br><br><br><br>But now is not the time to make decisions for the future. You're still waiting on your father's promise.[/quote](And if you don't think that looks bad, try viewing it on a phone.)[/details]

The second reason not to is a bit more insidious, and harder to see, but gets to the heart of one of the things we mean when we talk about ‘code efficiency’. Code takes time to write. Every line is at least a few seconds. Likewise code takes time to read, again, only a second to skim those lines.

However, inefficient code takes more time. It’s longer to write (think of how many times you have different labels leading to new paragraphs. If your game is complex or long enough, you might be writing thousands of extra words. Then, once you’re reading it back, you’re going to have even more to go through. In the same vein, you might consider why we use paragraph breaks in the first place when writing. (You’ve probably seen a few people write a long post without them.) Simply put, you’re both going to spend less time coding and editing.


###The Solution

So, the solution is actually pretty simple. When you want to use a paragraph break, just use a paragraph break.
"You won't have to come back here, if'n you don't want to."
He says with knowing eyes.
*choice
	#That sounds nice. 
		[...]Or you could finally get away...
		*goto dadhome
	#But you can't.
		[...T]here's your family to think about...
		*goto dadhome
*label dadhome

But now is not the time to make decisions for the future.
You're still waiting on your father's promise.
*page_break
If you add a few extras, it doesn't matter.
"You won't have to come back here, if'n you don't want to."
He says with knowing eyes.
*choice
	#That sounds nice. 
		[...]Or you could finally get away...

		*goto dadhome
	#But you can't.
		[...T]here's your family to think about...

		*goto dadhome
*label dadhome

But now is not the time to make decisions for the future.
You're still waiting on your father's promise.
*page_break

Both cases will look the same in an actual game. ChoiceScript reduces all paragraph breaks down to one, the same way as it reduces trailing spaces down to one.

[Return to the first post]


#11

If you’re interested in getting personalized help with your own game code, shoot me a PM, or send me an email (Rachel at choiceofgames dot com).

If you have questions or comments, please leave them below.


#13

This was fantastically helpful! Thank you, @RETowers, and thank you also @iris for allowing your work to be analysed and shared with us.

I didn’t know all blank lines were reduced to one (I knew it about spaces, but somehow not lines). That’s very reassuring; I’ve wasted loads of time trying to make sure I’m not accidentally adding spare blank lines when I had complex coding blocks.

I also really appreciated the fairmath demonstration, and your observations on how to get fairmath to balance well in terms of overall game mechanics. I hadn’t thought of looking at how likely a specific option was and tweaking the fairmath additions accordingly.

Thanks so much for taking the time to do this!


#14

It’s noteworthy that balancing is something you’re likely to do later on (rather than with three choices) and will probably involve a little more pushing around numbers by smaller amounts, but I think getting the premise in a smaller form like this is a good place to start to at least see the why and how of it.


#15

#Question and Answer

So one last section, a Q&A. I asked @iris for some questions that can hopefully shed some light on things anyone might be confused about.


The short to both answers is ‘No’.

That said, there’s two things to address here, the first being what “needs” to go in the stats screen. To understand that, it’s probably best to start with knowing that the stats screen works like just any other code in the game. You can make it to display whatever you want, and do whatever you want the same as anywhere else. Additionally, things that normally go in the stats screen, such as *stat_chart, can be put elsewhere in your game without a problem.

You can in fact even *set variables in the stats screen! (Although that’s going to require some more advanced work.)

Now, as for fairmath specifically, all fairmath does is add a certain amount to a variable. The max it can raise the stat by is the entered number, and the average it will raise it by is half that (e.g. *set angry %+ 20 adds between 20 and 0 to angry, with an average of 10). Fairmath variables will remain between 0 and 100.

These are the actual equations used:

Fair Addition: *set x %+ y = (x + (100-x)*(y/100))

  • Large scores are hard to increase: (90 %+ 20) = (90 + 2) = 92
  • Small scores are easy to increase: (10 %+ 20) = (10 + 18) = 28

Fair Subtraction: *set x %- y = (x - x*(y/100))

  • Large scores are easy to decrease: (90 %- 20) = (90 - 18) = 72
  • Small scores are hard to decrease: (10 %- 20) = (10 - 2) = 8

50 is equally easy to increase or decrease.

  • (50 %+ 20) = (50 + 10) = 60
  • (50 %- 20) = (50 - 10) = 40

(More information can be found from here.)

You don’t need anything special anywhere to use fairmath, all you need to do is make sure to *create your variable between 0 and 100, and just use fairmath for it.


There’s some arguments for both sides. Obviously the first argument to making stats visible is the stats screen. You’ve got to populate it with something, and that should probably be your core stats. Second, it helps player engagement by letting players have a better clue as to why things are happening (and players hitting something and not knowing why is usually a very bad thing). And finally, it guides players into anticipating what they should be doing and how they should be approaching problems. The only real downside to including it is possibly taking away some of that ‘magic’ for a few readers (and I’d argue that’s not actually that strong an effect).

Now, as for solutions (Roughly in order of complexity):

  1. As you mentioned, you can toggle it with an option at the beginning. This is a very basic option, but gives players the most choice in how to interact with the game. (Advanced users might even let you toggle it in the stats screen). The downside is it’s a little harder to control how the player perceives the game if you do this.

  2. You can decide not to display the stats, but then reveal them at the end. This can keep the veil up while actually writing, but encourage some replay value at the end. This, however, can also be frustrating, in that the player won’t know what exactly they should be doing when replaying the game.

  3. You can show imprecise stats. E.g. Say you have health that ranges from 0 to 100. If it’s less than 20, instead of showing the exact number, you can display ‘dying’ while if it’s more than 80, it say’s something like ‘perfect health’. For an example in practice, check out “Revolutionary Reputation” and “Shepherd and Wolf Reputation” in the Choice of the Vampire stats screen.

  4. You can actually split the difference. With achievements you can track things between playthroughs! (Although it’s noteworthy that this is only one way, and will always produce an achievement.) So, write both stats screens (make sure both look good, and to that I’d recommend you use option 3. for the one you’re planning on displaying through the first playthrough). Then, at the end of startup (after you’ve run all your *create and *achievement commands, add *check_achievements. Then, for every achievement you have, you’ll have a variable that’s set to either true or false (whether you have the achievement or not). (This is something I’d have to go deeper on at a different time.)


[quote=“iris”]And now onto trans related questions! First, background-- The world building in the game is sort of light handed at the moment, but the gist of gender in the Beast world is that people who are trans, nonbinary, etc are classified in a sort of third gender subspace that includes maleness, femaleness, and everything in between. I’m not sure if this is all that relevant (lol) but I’m Hawaiian and back in the day we used to have something like that going on which is where I got the idea. Basically the MC is a girl in societies eyes, but still set in a category apart.

So I have ideas on how to introduce the characters gender identity if they have dysphoria-- once they realize the beast was once a person, they can empathize for instance. If the beast is also classified in this third gender (nonbinary option) it’s made even more relevant.

But I’m sort of wondering how I’ll be able to give subtle options if the MC does not have dysphoria, or is ok with her classification? I’m sort of at a loss. The spirit Laliya is ‘female’ presenting, but spirits technically don’t have a gender so she specifically chose to be female. But I’m not sure if this is relevant because I’m not sure if transgender people choose to be transgender? I’ve never really understood gender, mine and especially not other’s :worried:[/quote]

(Note that I’m going at this from the angle of high inclusivity rather than having a dark world where trans people are treated badly as a note about the world not being all good since you mentioned “light handed world building”.)

So the inclusion of trans and nonbinary people is always great, but it’s also something you need to be careful about. As a note, I’m Navajo, I get the idea of two-spirit totally, but mashing every trans group together under it is 1) probably not going to be as coherent as it could be (different trans experiences can vary widely, especially between transgender and nonbinary people), 2) probably not going to represent anyone very well, let alone everyone, and 3) may alienate some of the people you’re trying to be inclusive of.

So first, trans as a third gender is a bad idea. My general recommendation for games with a gender option is, don’t make the option to be trans part of the gender choice. A trans woman is not ‘something other than a man or a woman’, they’re just a woman. That choice should be separated out from the choice of gender. The reason is, if it’s packed in with the gender choice, you end up othering trans people by making them pick between being a ‘real’ woman and a trans woman.

As for the discussion of dysphoria, I wouldn’t recommend separating the two (that is, those with and those without), or mentioning it. It’s not easy to categorize or represent across a large group, and to the extent you might do it well, most trans people don’t like being reminded of their dysphoria anyways.

Now as for the big one: trans people do not choose to be trans. In the same way no one chooses their skin color, their height, their orientation, their blood type, or anything else like that, these things are innate to people. (The term you originally used is an old term, transgender is preferred now that science has advanced on the issue.) To that extent, someone that doesn’t have a gender presenting as having one for some reason, would be an entirely different thing.


I hope all that helps. If there’s more specific question or some lingering confusion I’m happy to address it.