The Beast in the Castle Code Review

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)
2 Likes