Now that you know how to write conditional statements using
if/elif/else (Conditional Statements in Ren’Py), how to check if strings or integers are the same (Equality Comparisons in Ren’Py), and the concept of truthy/falsey for non-boolean values (Truthy vs Falsey), you’re ready to learn about numerical comparisons and how to check more than one expression at once.
As with the last tutorial, it’s recommended that you first look over Simple Variable Types in Ren’Py. This guide also assumes you have a basic idea of how to write choice menus. If you need a quick refresher, you can check out the section on Menus, Labels, and Jumps in the Ren’Py quickstart.
There is also another quiz to test your knowledge of comparisons, with additional questions combining the information in this tutorial and the earlier parts on conditionals to check your understanding of these concepts.
If you’re dealing with numbers like integers or floats, sometimes you might want to check whether a number is in a particular range, or if it’s over or under a threshold. From the example list in Equality Comparisons in Ren’Py, this includes things like:
- If the player has at least 8 affection points with Xia, she’ll ask them on a date
- If the player has 10 or more bad end points, they get the bad end. If they have less than 10 bad end points but more than 0, they get the normal end. Otherwise, they get the good end.
- If the player has enough money, they can buy a flower.
You may already be familiar with symbols like <, >, ≤, ≥. They’re used in math like
y > 5 (y is greater than 5) or
x ≤ 2 (x is less than or equal to 2), or even
130 ≤ height ≤ 170 (height is between 130 and 170, inclusive of the end points).
< for “less than” and
> for “greater than”, as you’d expect from above. However, in coding,
<= (less than or equal to) and
>= (greater than or equal to). Note that the position of the
= is important;
=> are incorrect and will cause an error. You can think of the order as following how you’d say it – “greater than” (
<) “or equal to” (
<=. There’s no need for double
== here, since it’s accompanied by a
< symbol. You might also remember the “not equal” comparison
!= did something similar – all three additional symbols (
>) come before the
With this knowledge, you can compare numbers:
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 sighs deeply." if zoran_love_points >= 1: "Zoran" "Yeah, maybe I needed that. Thanks."
For this statement, the game checks if the player has 1 or more love points with Zoran through their past choices (
if zoran_love_points >= 1). If they do, then Zoran trusts their opinion enough to not get upset even if the player told him to get over himself.
It’s also fine to use these comparisons for floats, because they’re not checking for exact values but ranges e.g.
# This is 3.0 (float) instead of just 3 (an integer) # so we can get a float result when we do # correct_answers/total_answers. # Ren'Py 8.0+ will do this automatically, but # Ren'Py 7.x will round the answer down otherwise define total_answers = 3.0 default correct_answers = 0 default grade = 0.0 label start: menu: "What year was Ren'Py first released?" "2022": # Wrong! Ren'Py was first released in 2004 pass "2004": $ correct_answers += 1 menu: "Why is it bad to use == to compare floats?" "Decimals can have rounding errors.": $ correct_answers += 1 "You shouldn't compare any numbers with ==": # Wrong! It's fine to compare integers with == # but don't use it for floats! pass menu: "Can you put an else clause before an elif?" "Yes": # Wrong! The `if` is required, the `elif` clauses are # optional, and the `else` clause, if included, must go at # the end as a "catch-all" for the remaining possibilities. pass "No": $ correct_answers += 1 # Divide the # of correct answers by the # of total # answers to get a number like 0.6666667 for 2/3 $ grade = correct_answers / total_answers if grade >= 0.7: "Amazing!" elif grade > 0.5: "Not bad!" elif grade > 0.3: "Hmm, maybe try again." else: "Study up some more next time!"
Here you can see that we have comparisons like
if grade >= 0.7 (if
grade is greater than or equal to 0.7) and
elif grade > 0.3 (if
grade is strictly greater than 0.3).
Note that this illustrates a very useful feature of
if/elif/else-style conditional statements, which is that only one expression in an
if/elif/else can be True, and the rest will be skipped. You’ve seen this before in some previous examples, but let’s really take a look at this and see how it works now that we’re dealing with number ranges.
More specifically, what this means is that the above conditional statement is the same as:
if grade >= 0.7: "Amazing!" elif 0.7 >= grade > 0.5: "Not bad!" elif 0.5 > grade > 0.3: "Hmm, maybe try again." else: "Study up some more next time!"
Let’s look at it more closely.
So, first, we check
if grade >= 0.7. If
grade is equal to something like
0.9 >= 0.7 is True so the player will see the line “Amazing!” and the game will continue with whatever content is after the conditional statement.
grade is equal to
0.6 >= 0.7 is False, because
0.6 is not greater than or equal to
0.7. In this case, we’ll skip the block underneath
if grade >= 0.7 and move on to
elif grade > 0.5.
Now we look at this line and compare it – is
0.6 > 0.5? Yes! 0.6 is greater than 0.5. So this statement is True and the player sees the line “Not bad!”.
This is the same as
elif 0.7 >= grade > 0.5 seen above, because we already know that if we’re checking
elif grade > 0.5 then the first
grade >= 0.7, wasn’t True. If it had been True, then the player would have seen “Amazing!” and the game wouldn’t have bothered to check
elif grade > 0.5. So, since it wasn’t, then the number must be less than
You can also use this to do something like calculate which ending the player should get based on their accumulated good and bad end points:
if bad_end_points > 10: # The player made more than 10 bad choices jump super_bad_end elif good_end_points > 10: # The player made more than 10 good choices jump excellent_end elif bad_end_points > 5: # The player made 6-10 bad choices jump bad_end elif good_end_points > 5: # The player made 6-10 good choices jump good_end else: # The player didn't get more than 5 good or bad points jump normal_end
elif bad_end_points > 5 comes after the line
if bad_end_points > 10, so we know that if the game got to the clause
elif bad_end_points > 5, then
bad_end_points is at most 10, because if it was more, then the first expression would have been True and the game wouldn’t be checking this next one. Since
elif bad_end_points > 5 is looking for strictly greater than 5, and we know that it can’t be more than 10, then this statement will only be True if
bad_end_points is between 6 and 10, inclusive.
Similarly, the only way the game will get to the
else clause is if the player had 5 or fewer good or bad end points (so, 0-5), since if they had more than 10 one of the first two expressions would have been True, and if they had more than 5 the third or fourth expressions would have been True. Since we got to the
else clause, that means that none of the previous expressions were True, so the player has between 0-5 good end points and 0-5 bad end points.
Note on Strings
Besides just numbers, you can actually use
> etc with strings! In the case of strings, it compares them alphabetically, with a few notable caveats. This is, however, used very infrequently. You can read more on this in String Comparisons in Ren’Py.
This kind of comparison is very uncommon for most games, and it won’t be included in the quiz on numerical comparisons after this tutorial.
Combining more than one comparison
Now that you can directly compare values with
!=, and compare numbers with
>=, let’s look at combining comparisons. Remember earlier we had some statements like:
- If the player is carrying a life jacket or they made it to the top of the ship in time to get in a life boat, they survive.
- If the player gave Zoran the book Pride & Prejudice and has at least 5 trust points with Zoran, Zoran will share a story from his childhood.
Note the language used to describe these comparisons – “or” and “and” are actually Python concepts you can use directly! We’ll start with using them for booleans (True/False), since that’s the simplest to understand, and in the next part you’ll see how to combine them with all the previous things you’ve learned to create complex conditional statements.
Consider the following statement:
If the player went to the park and they own a dog, then we know that they took their dog to the park. The dialogue should reflect this.
So, say you have two booleans,
went_to_park = True and
owns_dog = True.
If you want to check that both of them are True, you can do:
if went_to_park and owns_dog: "Your dog was sleeping in the corner of the room, tired after your walk in the park earlier that day."
If either or both of
owns_dog is False, then this statement won’t play. Let’s construct a more elaborate example, with some
else clauses to see what happens:
if went_to_park and owns_dog: "Your dog was sleeping in the corner of the room, tired after your walk in the park earlier that day." elif went_to_park: "You sat down on the couch, tired after your walk in the park earlier that day." elif owns_dog: "Your dog seemed restless after being inside all day while you went to the movies." else: "You sat down on the couch, still thinking about the movie you'd seen earlier."
So, let’s break it down.
- Case 1 – the player has gone to the park and owns a dog
owns_dogare True, so the condition
if went_to_park and owns_dogis also True.
- This means that the player sees the line “Your dog was sleeping in the corner of the room, tired after your walk in the park earlier that day.”
- Case 2 – the player has gone to the park, but doesn’t own a dog
went_to_parkis True, but
owns_dogis False. This means that
if went_to_park and owns_dogis
False, because the player doesn’t own a dog.
- The next expression,
elif went_to_park, is True, because the player did go to the park. So they see the line “You sat down on the couch, tired after your walk in the park earlier that day.”
- Case 3 – the player owns a dog, but didn’t go to the park
owns_dogis True, but
went_to_parkis False, so
if went_to_park and owns_dogis False because the player didn’t go to the park
elif went_to_parkis False, because the player didn’t go to the park.
elif owns_dogis True – the player does own a dog. So they see the line “Your dog seemed restless after being inside all day while you went to the movies.”
- Case 4 – the player didn’t go to the park, and they don’t own a dog
went_to_parkis False and
owns_dogis False, so
if went_to_park and owns_dogis False, because the player neither went to the park nor owns a dog
elif went_to_parkis False, because the player didn’t go to the park
elif owns_dogis False, because the player doesn’t own a dog
elsethen must execute, since everything before it was False. So the player sees the line “You sat down on the couch, still thinking about the movie you’d seen earlier.”
and, both operands on either side of the
and operator  need to be True in order for the whole statement to be True. It’s not enough for the player to have just gone to the park, or just to own a dog – they must both own a dog and have gone to the park for the first
if went_to_park and owns_dog expression to evaluate to True.
operator – special symbols or words that indicate some kind of computation should take place. You’ve seen operators in math before; they include things like
/. Those math operators exist in programming languages, as well as a few other ones such as
and, as you’ve seen here, and
or, as you’ll see in the next section. Equality comparisons like
!= that you saw in Equality Comparisons in Ren’Py are also called operators.
operand – what we call the values the operator acts on. For example, in the expression
2 + 4,
4 are the operands, which are acted on by the operator
+. The operator, in this case, adds the two operands together and the result is the number
2 + 4 = 6).
or is similar to
and, but less strict – only one of the operands on either side of the
or operator has to be True (or both). Consider the following:
If the player helped Ashwin with their groceries or mowed their lawn, then they’ll mention how the player helped them out and agree to return the favour.
if helped_ash_groceries or mowed_ash_lawn: "Ash" "I guess you did help me out earlier today..." "Ash" "So I can spare some time to help you, too." jump moving_day_ash else: "Ash" "No, sorry, I'm just too busy." "Ash" "Maybe you can ask Xia or Zoran." jump no_help
Let’s look at what happens for the different combinations of
- Case 1 – the player both mowed Ashwin’s lawn and also helped them with groceries
mowed_ash_lawnis True and
helped_ash_groceriesis True. We only needed one or the other to be True, but it’s fine that they’re both True – Ashwin will agree to help and the player will jump to
- Case 2 – the player mowed Ashwin’s lawn but didn’t help them with groceries
mowed_ash_lawnis True, but
helped_ash_groceriesis False. However, we only need one of the two to be True, since we’re using
or. So, Ashwin will agree to help the player and they’ll jump to the
- Case 3 – the player didn’t mow Ashwin’s lawn, but they did help them with groceries
mowed_ash_lawnis False, but
helped_ash_groceriesis True. Again, we just need one of the two to be True, so Ashwin will agree to help and the player will jump to
- Case 4 – the player did not mow Ashwin’s lawn and didn’t help them with their groceries
mowed_ash_lawnis False and
helped_ash_groceriesis False. Neither of the two operands is True, so the whole thing is False. Ashwin says they are too busy and the player goes to the
or in Practice
Note that you can use as many
or operators in a conditional statement as you like to connect many operands. The outcome of evaluating such an expression will depend on which of
or you’re using, as well as the value (True/False) of each operand.
if True and True: # True if True and False: # False if False and True: # False if False and False: # False if True and True and True and True: # True only if *all* operands are True if True and False and False and False: # False; all operands must be True
if True or True: # True if True or False: # True if False or True: # True if False or False: # False if True or True or True or True: # True if True or False or False or False: # True; at least one True makes the whole condition True
In this tutorial, you learned about the operators
>= for numerical comparison, and about the operators
or for combining multiple expressions into a single conditional statement.
and requires that all its operands evaluate to
or only needs one of its operands to be
True in order for the whole expression to evaluate to
As per usual, there is a quiz on numerical comparisons and combinations that you can use to test your knowledge: Numerical Comparisons and Combinations Quiz. If you’d like some extra information on using operators like
< for strings, check out String Comparisons in Ren’Py, which comes with a very short quiz on the topic. When you’re ready to move on, check out Combining Comparisons in Ren’Py.