Simple Variable Types in Ren’Py

Simple Variable Types in Ren’Py

Now that you’ve learned about booleans and the basics of variables in Ren’Py as well as some basic conditional statements, you’re ready to learn about more variable types.

Difficulty Level: Beginner

As with before, I recommend you have a passing familiarity with choice menus before going through this guide, and that you go through the previous two tutorials as well (A Quick Primer on Variables in Ren’Py and Conditional Statements in Ren’Py).

Simple Variable Types

  • Booleans – A boolean (often called a bool for short) is one of either True or False. A Quick Primer on Variables in Ren’Py covers booleans as well.
  • Integers – Numbers without decimal places like 1-720, and 51687. May be called int for short.
  • Floats – Numbers with decimal places, like 0.03.14159-500043.2 and 0.00004Float is short for Floating Point Number, named for the fact that the decimal point can “float” anywhere in the number, since there isn’t a fixed number of digits before or after the decimal point e.g. 100.05 has the decimal point after the third number but 4.9543 has it after the first number, even though both have 5 digits.
  • Strings – Words you put inside quotation marks. Python and Ren’Py allow you to declare strings with either apostrophes ('like this') or with quotations ("like this"). Anything inside quotes is a string. So "1" is a string, not an integer, because it’s in quotes. Other example strings are "This is a string"'Pi is approximately equal to 3.14159', and "!!!!".
  • None – This is actually a very special kind of value, the None value. If you’re familiar with other programming languages, None is approximately equivalent to NULL. For the most part, you can think of None as a bit like a special False value.

Matching variables to use cases

Now we’ll go over what situations you might want to use each variable type for. There will also be a quiz testing what you’ve learned.

Booleans

Booleans are usually the first variable type most people find out about, and are probably the most common across Ren’Py games. As mentioned, they are one of two values: True or False.

In a default Ren’Py game, you’ll see booleans already in use in several places. For example, in screens.rpy there is a screen called screen navigation, and a line inside there that says if main_menu:main_menu is a boolean variable that Ren’Py sets to be True if the player is on the main menu and False if they’re in-game. In this case, if the player is on the main menu, they should be shown a Start button to start the game. If they’re already in-game though, there’s no need to show them a start button.

Places where you SHOULD use Booleans:

  • Tracking player actions e.g. did they give Ashwin a gift? True/False
    • gave_ashwin_gift = True
  • Keeping track of binary choices e.g. did the player lie about knowing who Xia is?
    • lied_about_xia = False
  • Toggling preferences e.g. do they have animations toggled on or off?
    • persistent.animations_on = True

Places where you should NOT use Booleans:

  • When you have 2+ values that are

Example boolean use:

default player_ate_apple = False
label start():
    "One day, Snow White was visited by a strange old lady selling apples."
    menu:
        "Eat the apple":
            $ player_ate_apple = True
            "She ate the apple. It was lovely and red and juicy."
        "Don't eat the apple.":
            $ player_ate_apple = False
            "She shook her head at the old woman and decided not to take the apple."
    "After the woman left, Snow White returned to her cleaning."
    if player_ate_apple:
        "She began to feel quite unwell and fainted in the kitchen."
        jump ate_apple
    else:
        jump end_day_1

This is a good use for boolean values as there are only two possibilities – either the player ate the apple (True) or they didn’t (False). This doesn’t conflict with anything else they could have done. You may also note that the $ player_ate_apple = False line under the "Don't eat the apple." choice is technically optional because player_ate_apple begins with a value of False. So, unless you change it earlier in the code, it will still be False whenever you go to check it. However, it’s good to add it for clarity and to prevent accidental errors in case player_ate_apple was somehow set to True before reaching this choice menu.

You may also notice that there is a conditional statement there – the thing that says if player_ate_apple. This is a useful feature of booleans is that you can just check if boolean_variable to see if boolean_variable is True. You can see more examples of conditional statements with booleans in Conditional Statements in Ren’Py.

The else statement basically says “if the condition(s) before this statement were NOT true, then do this”. So in the case of

if player_ate_apple:
    jump ate_apple
else:
    jump end_day_1

when player_ate_apple is False, the line if player_ate_apple isn’t True (the player didn’t eat the apple). So the program moves on to the next condition, which is the else line and jumps to the end_day_1 label instead.

Integers

Integers are excellent for tracking any sort of numerical values in your game, such as love point totals for characters or the number of times the player has gone to the park. Remember that an integer is any non-decimal number e.g. -5, 20, 0, or 124083

In a default Ren’Py game, integers are used for some preferences, such as the number of characters displayed per-second for dialogue (also known as CPS characters per second), and for lots of defined GUI values like the text size of in-game dialogue or the width (in pixels) of the dialogue box.

Places where you SHOULD use Integers:

  • When keeping track of collected points e.g. how many affection points do they have with Xia?
    • xia_love_points = 0 and xia_love_points += 1
  • When counting how many times a certain action has been done e.g. how many times has the player visited the park?
    • player_park_visits = 1
  • Tracking the number of actions the player has left before time runs out e.g. there’s only enough time to dance with two people at the ball. Once you’ve danced with two people, the ball is over.
    • num_dance_partners = 2
  • Tracking how many items a player is holding or has acquired e.g. How many life jackets did the player manage to get?
    • num_life_jackets = 3

Places where you should NOT use Integers:

  • Variables where there are only two outcomes e.g. either they have enough life jackets or they don’t, and there’s no way to acquire/lose just one or two (instead of all the life jackets)
    • In this case, a boolean would be more appropriate (see the definition of mutual exclusivity)
  • Keeping track of multiple distinct but diverse options e.g. the player can be either tall or short. You use a variable like player_height = 0 for short and 1 for tall
    • This is more subjective; it’s not a bad choice per se, but in the case of player heights, it can make your code harder to read by using numbers for non-numerical concepts. Additionally, what would happen if you wanted to allow players to be “average” height? Do you use 0.52? In this case, a better choice would be to use strings like player_height = "short"player_height = "average" etc
    • However, if you wanted to represent height as actual numerical values like 150cm, then an integer would be a good choice, especially if you’re doing comparisons like if player_height < 150 -> "You couldn't reach the top shelf."

Example integer use:

default zoran_love_points = 0
label start():
    "Zoran shuffles awkwardly, looking down at his feet."
    menu:
        "Make a joke.":
            $ zoran_love_points += 1
            "He smiles when you finish telling the joke."
        "Tell him to get over himself.":
            $ zoran_love_points -= 1
            "He looks almost angry at you."
            "Then he gets up and leaves."

Note that $ zoran_love_points += 1 will set the value of zoran_love_points equal to 1 + whatever the previous value of zoran_love_points was. So, if zoran_love_points was 5, after the line $ zoran_love_points += 1 it will be equal to 6. A later tutorial will cover this and other numerical operators.

Floats

Floats are very similar to integers, but refer to numbers with decimal places like 3.1415, -19.0, and 0.2

In a default Ren’Py game, floats are mostly used for alignment properties of GUI elements like the choice buttons. The alignment property, align for short, can position things like buttons on the screen. It uses floats to represent a percentage of the screen rather than a set number of pixels. So, a value like 0.5 indicates the alignment should be 50% of the way down/across the screen (aka centered).

Places where you SHOULD use Floats:

  • Tracking numbers which have decimal places, such as how much money the player has (including cents).
    • money = 100.00
  • Using decimal places as percentages
    • grade = 30.0/40.0 or grade = 0.9

Places where you should NOT use Floats:

  • Anywhere that you need distinct values or need to compare exact numbers.
    • Floats can’t be exact due to the infinite nature of decimal points. When it comes to numbers with a lot of decimal places like pi, the computer has to limit how many digits it will use so it can do calculations, which means that there will be some rounding errors.
    • So if you find yourself comparing two floats like if grade == 0.9, you may want to rethink if you should use integers OR check for a range instead e.g. if grade >= 0.85 and grade <= 0.95. We will cover these types of comparisons in Numerical Comparisons and Combinations in Ren’Py later on.
  • Same rules where integers would be bad also generally apply to floats

Example float use:

default cash = 10.00
label start():
    "You went to the market to make some purchases."
    menu:
        "What will you buy?"
        "A Flower ($4.99)":
            $ cash -= 4.99
            "You purchased a flower."
        "Don't purchase anything":
            "You didn't end up buying anything."

Strings

Strings are one of the most flexible variable types. They’ll contain just about anything so long as you put it in quotation marks. As a result, they’re useful for holding a variety of information.

In a default Ren’Py game, strings are used for things like defining colour codes to use for text (e.g. "#FF0000", the hex colour code for red) and for the name of your game and what the current version is. They’re also used to specify file paths for things like images, sound effects, and font files.

Places where you SHOULD use Strings:

  • When you have a lot of possible values for a variable that correspond to words e.g. keeping track of what colour hair the player has
    • hair_color = "black"
  • When you want to use a variable in dialogue during the script e.g. player_height = "short" and then p "Yeah, I'm pretty [player_height].". This would display to the player like "Yeah, I'm pretty short."
  • When a variable corresponds to an image or filename you want to use e.g. xia_hair = "long" and then image xia happy = "Characters/xia/[xia_hair].png". Like variable substitution in dialogue, this will search for an image at images/Characters/xia/long.png. If you later change Xia’s hair to be short ($ xia_hair = "short"), then the game would instead look for the file images/Characters/xia/short.png. (This will be covered in a later tutorial)
  • If you want to have branching storylines reconvene at some common event, then branch off again depending on past choices.
    • For example, the player can be on Xia, Zoran, or Ashwin’s romance routes. There is a common event to all three routes where the player spends the day at work. After they finish their job, the next scene depends on who they are romancing. Before you jump to the common event label, you can set up a variable like $ next_scene = "zoran_scene_4" at the end of each specific route, and then at the end of the common event you can write jump expression next_scene to jump to the label saved in the next_scene variable (so for Zoran it would jump to a label named zoran_scene_4)
      • jump expression is a special variation of the jump statement that lets you use a string to get the label name to jump to.
    • This and other more complex use of strings will be covered in a later tutorial.

Places where you should NOT use Strings:

  • When you’re keeping track of counters (numbers that increase/decrease during the game, like affection points or counting how many times the player has said a swear word) or other numerical values
    • Usually integers are better for this. Sometimes floats are also helpful.
  • If the variable only has two possible values in a yes/no-style pattern
    • An exception to this is if you use the variable to determine which image to use for a character e.g. the character has two different outfits, their work outfit and their normal outfit. You have a variable ashwin_outfit = "work" or ashwin_outfit = "normal". Even though Ashwin is either wearing/not wearing their work uniform, you might use this variable inside an image definition like image ash = "Characters/Ashwin/[ashwin_outfit].png" so it makes sense to keep it as a string so you can take advantage of Ren’Py’s variable substitution. With the above format, Ren’Py will either look for the image images/Characters/Ashwin/work.png or images/Characters/Ashwin/normal.png depending on the value of ashwin_outfit. (Keep an eye out for a later tutorial on this topic)

Example string use:

default gift = ""
label start():
    "At the mall, you decided you wanted to buy Ashwin something."
    menu:
        "Buy them a bath bomb.":
            $ gift = "bath bomb"
        "Buy them a self-help book.":
            $ gift = "self-help book"
        "Buy them a digital camera.":
            $ gift = "digital camera"
    "Later that day, you were able to give them the [gift] you bought earlier."
    "They liked it a lot."

The player can only get one gift for Ashwin, so it makes sense to store this variable as a string. Even more useful is that we can have Ren’Py substitute it in the sentence after the menu so that if the player bought Ashwin a bath bomb the line reads “Later that day, you were able to give them the bath bomb you bought earlier.” This saves us having to write out three separate sentences for each gift with only the name of the gift changed, but you can also customize later text by checking for conditions like if gift == "bath bomb" (these sorts of comparisons are covered in more detail in the next tutorial, Equality Comparisons in Ren’Py).

Flow Chart

For a visual example of when it is best to use each variable type, you can use the following flowchart:

A flowchart to help choose the best variable type to use for various situations.

Next Steps

Now that you know about the four basic variable types in Ren’Py, it’s time to see what you’ve learned with a quiz. Try the Simple Variables Quiz before moving onto the next tutorial, Equality Comparisons in Ren’Py.

Leave a Reply