Engines

2D Fighter Maker 2002

Game Maker

Fury²

RPG Maker 2000

RPG Maker 2003

RPG Maker VX

RPG Maker XP

RPG Toolkit

Verge

Forums

Games

News

Resources

Scripts

Tutorials

Utilities

Sponsors

Affiliates

Home > Articles > Tutorials > Ruby Game Scripting System (RGSS) > RGSS For Dummies Tutorial 3: Control Flow

RGSS For Dummies Tutorial 3: Control Flow

Author: RPG
Updated: September 04, 2007

Introduction

Our little variable and print programs were executed line by line; they weren't interactive and just displayed some text on the screen. Real programs aren't like that, they interact with users and other things to produce the desired output. Ruby (and all high level languages) introduces some statements (commands) that we can use to add interactivity to our scripts, mainly it introduces conditional statements and loops. A conditional statement (or expression) basically checks if a condition is met. If it is met, then some commands will be executed, otherwise some other commands might be executed,. As for loops, they allow you to execute a block of code over and over until a condition is met. Loops and conditional statements are essential in programming, if you don't learn them then you'll probably stay a worthless noob till the end of time! ;)

Contents

1. Boolean Expressions
2. Important Note
3. Conditional Statements
      3.1. if
      3.2. unless
      3.3. Ternary operator
4. Loops
      4.1. while
      4.2. until
      4.3. Ranges
      4.4. for
      4.5. loop
      4.6. break, next, retry, redo
      4.7. Statement Modifiers
5. Conclusion
6. Summary

1. Boolean Expressions

A Boolean value is a value that can either be true or false. Think of a switch that can be either on or off, or a path that only goes left and right; there's no gray about Booleans, everything is black and white. You might be asked: "is u alex???", thre are two valid answers for that question, either "lol yes im alex!!!", or "no im not r u???". So if we had a Boolean variable called is_u_alex?, (variables can't have spaces, so we use underscores) the value of the variable could be true if you are Alex and false if you aren't. Makes no sense, I know. Let's try something more simple, the mathematical statement "1 is equal to 2" is false, while the statement "1 is equal to 1" is true. Here are some other statements that can be true or false:

"3 is bigger than 2"
"98 is equal to 89"
"0.01 is smaller than 0.1"
"3 is smaller or equal to 3"

I think you know which ones are true and which ones are false, if you don't then check this statement: "RGSS for Dummies isn't equal to RGSS for Idiots". Now, in programming we can compare two values to get a Boolean value that evaluates the comparison. We use "==" to indicate equality. Remember when I talked about variable assignment and I said that the = operator means assignment and not equality? "var = 5" means assign 5 to var, while "var == 5" means that var is equal to 5. Let's just try an example:

p 1 == 1

This will output 'true'. Basically we're asking RGSS to evaluate the statement "1 is equal to 1", just like we were evaluating statements earlier. Now, change both numbers and see the various results. "p 1 == 4" would output false, p "0.1 == 0.1" would output true, etc. You can even use strings like "cow" == "cow" or 1 == cow. It's really simple, the statement can be either true or false and RGSS evaluates it for us. Other than the equality operator "==", we can use ">" for bigger than, "<" for smaller than, ">=" for bigger or equal to, "<=" for smaller or equal to and "!=" for not equal to. These examples will help:

p 1 > 2  # false
p 5 == 5  # true
p 0 >= 0  # true
p 4 < 1  # false
p -19 <= 0   # true
p 1 == 8  # false
p 1 + 3 == 2 + 2   # true
p 4 != 7  # true

It's all simple logic, all of those are Boolean statements that can be true or false. Now, since they're Boolean statements, their evaluation values can be stored in Booleans, for example:

my_bool1 = 9 == 9
my_bool2 = 3 <= 1
my_bool3 = true
p my_bool1   # true
p my_bool2   # false
p my_bool3   # true

I just stored Boolean values in Boolean variables, this should help you understand the difference between "=" and "==", you use the former to store the values on the right of the "=" in the variable on the left of it, and you use "==" to compare two values for equality. Also, note that we can directly store true or false values in variables, just like I did with my_bool3.
Another thing you can do is to evaluate multiple statements at once. You can use "and", "or" and "not". You place an "and" between two statements and the new statement (statement1 and statement2) will evaluate to true if both statements are true, and to false if one or both of the statements are false. Examples:

p 1 == 1 and "hello" == "hello"   # true
p 1 > 5 and 5 >= 1     # false
p 9 < 3 and 6 == 3     # false

You place an "or" between two statements and the new statement (statement1 or statement2) will evaluate to true if at least one of the statements is true (one is true or both are true), and to false if both statements are false. Examples:

p 1 == 1 or "hello" == "hello"  # true
p 1 > 5 or 5 >= 1     # true
p 9 < 3 and 6 == 3     # false

Finally, place a "not" before a statement and the new statement (not statement1) will evaluate to true if the original statement (statement1) is false, and to false if the original statement is true. In other words, it returns the opposite of the original statement. "not 1 == 1" is the same as "1 != 1" or "1 is not equal to 1", which is false. Example:

p not 1 == 1   # false
p not 4 < 2   # true
p not (3 <= 8)   # false

In the last example, I used parenthesis around the statement, it's generally a good practice because it can make your code more readable, especially if you have many statements joined with and's or or's.
There's one more thing you need to know about "and", "or" and "not"; you can abrriviate them to &&, || and !. Actually, there's a difference in precedence between the word forms and the symbol forms, but it's not really that important (at the moment). Basically, using "&&" is the same as using "and", "||" is like "or" and "!" is like "not". Why do we use two &s and two |s instead of one? Well, both & and | have different meanings in ruby so remember not to confuse them with && and ||. I've rewritten some of the previous and-or-not example with the new symbols:

p 1 == 1 && "hello" == "hello"   # true
p 1 > 5 || 5 >= 1     # true
p !(4 < 2)    # true

The last example is interesting, "not 4 < 2" works, but "! 4 < 2" doesn't. ! has higher precedence than "<" and than "not". So RGSS reads "! 4 < 2" as "the opposite of true is less than 2", wait... the opposite of true? Well, you see... every value in RGSS is true expect for the values false and nil, so the value 4 on its own is true. You don't understand? Never mind then! Just forget all about this precedence thing for now, but remember to always (most of the time actually) use parenthesis around statements when using ! instead of not.

2. Important Note

= is NOT the same as ==, I know I mentioned that already but this is one common mistake in programming. Even professionals working for Microsoft might fell for it and use = instead of ==. Always remember that = is only used to assign values, and that == is used to test for equality of two values. I know you'll do this mistake sooner or later (I did, a lot!), but when something isn't working in your program, it's a good idea to check the comparisons to see if you used = instead of ==.

3. Conditional Statements

The hero of light was sent on a mission to retrieve defeat the evil dragon king, he does that and returns to the king. The king (of happyland) asks for proof and the hero presents the 'evil dragon king's magical nose™' which makes the king happy and everyone lives happily ever after. This could be the story of your upcoming groundbreaking RPG that you plan to send to Squaresoft, they will use it part of it (because it's too complicated to be fully used) as the story for the next Final Fantasy game and you'll be very rich and famous. There's one problem though... how would the king know that the hero has the 'evil dragon king's magical nose™'? Maybe we want the king to say "You did it! You have the nose so you must have defeated the dragon" if the player has the item and "Oh, you don't have the magical nose™! Go defeat the evil dragon king before it's too late!” In English we might say "If the hero has the item, the king will say the 'you did it!' thing. Otherwise the king will say the 'go defeat the dragon' thing".  Another example is saying "If I was Alex, I would be strong". Notice the pattern? If some condition is met, something will happen. Conditional statements are used to evaluate if something is true or false and do something if it's true.

3.1. if

if condition
    do something (true)
else
    do something (false)
end

The condition is simply a statement that can be true or false, a Boolean expression in other words, it could also be a simple Boolean variable. And the first 'do something' could be a block of code that would be executed if condition is true. The other do something (after else) is another block of code that'd be executed if the condition is false. So basically, the if statement allows you to have branches in your script, different thing would happen depending on different situations. If you used rm2k/3, you might remember the conditional branch command, which is simply a form of if statements. Here's an example demonstrating how to use if:

cow = true
if (cow == true)
    p 'cow is true!'
else
    p 'this will never be executed!'
end

cat = false
if (cat == true)
    p 'this will never be executed!'
else
    p 'cat is false'
end

Note that you can simply use if cow or if cat, there's no need for the parenthesis surrounding the condition; I just do it because I feel it'd be clearer that way. One thing you can add to the if statement is an elsif (stands for else if), elsif is followed by a condition and is executed if the preceding if condition isn't met. An example might make it clearer:

age = 15
if (age < 13)
    p 'child'
elsif (age < 18)
    p 'teenager'
elsif (age < 150)
    p 'adult'
else
    p 'Man, you're too old. You should be dead by now'
end

If you run that program you'd get 'teenager' as output. How does it work? First it checks if the age is less than 13, it's not so you'd expect it to go to the else statement. However, elsif is actually an else statement followed by an if, it checks for another condition if the one before it wasn't met. The elsif condition checks if age is less than 18, and prints a message (because the first if failed we know that the age will be >= 13). If you change the age value to 40 instead of 15 the first elsif will fail and the second elsif condition will be evaluated. If you change age to 200 for example then all the conditions will fail and the code after the last else will be executed.

The last thing you need to know about if is that you can nest ifs, like this:

if 1 == 1
    if 2 == 2
        p 'Hello world!'
    end
end

The inner if will be executed only if the outer one succeeds. It might look confusing if you next too ifs inside each other so don't overdo it if you don't need it. You can also nest loops the same way (as well as classes and methods, basically all blocks can be nested inside each other, I think...)

3.2. unless

unless (condition)
    do something (false)
else
    do something (true)
end

Unless is the opposite of if. It executes the first statement if the condition is false, and the second if it is true. It's like saying "if not(condition)".

boolean = false
unless boolean
    print 'hi'
end

As you can see, we didn't use else in this example, it's optional. You can also have if statements without else... actually, most of the time you wouldn't need an else case.

3.3. Ternary operator

var = condition ? value (true) : value (false)

There's a shortened form of the if statement, the ternary operator (the ?) checks if condition is true, if it is the first value (left of :) will be returned and stored in var, otherwise it'd store the second value (right of the ":") in var. In other words, the value of var will be value (true) if condition is true, and value (false) if it is false.

monkey = true
my_var = monkey ? 1 : 2
p my_var   # 1

case var_name
    when val1
        do something
    when val2
        do something
    when val3
        do something
    when val4
        do something
    else
        do something
end

The case statements compares the expression following it (var_name) with each expression after a when (val1, val2, val3, val4), it executes the code (do something) following the matched when and if no when is matched the code after else (which is optional) will be executed. You can have as many whens as you like and you can think of the case statement as a long list of if...elsif, but the only condition we check is equality between the expression after case and the other expressions after the whens. Here's an example:

number = 1
case number
    when 0
        p 'The number is zero.'
    when 1
        p 'The number is one.'
    when 2
        p 'the number is two.'
    Else
        p 'The number isn't zero, one or two.'
end

4. Loops

A conditional expression just checks if a condition is true (or false) and executes some code. A loop keeps executing some code until a condition is met. For example, in game programming you generally check for input, do some calculations and finally draw stuff. Here's what your game source code might look like:

check input
do calculations
draw stuff

There's one problem though, everything will be executed line by line, first it checks for input, does calculations such as changing hero's position depending on input and finally draw the map and sprites. The problem is, the program ends after the last line (draw stuff), there isn't anything else to do, it executed all the commands and drew one frame and that's it. You might think of asking the computer to do that again like this:

check input
do calculations
draw stuff
check input
do calculations
draw stuff
...

Even if you add thousands of line, the program execution will eventually end. What you need is a way to ask the program to do things again and again, until the player exits the game by pressing escape or something. Something like:

while (Esc isn't pressed)
    check input
    do calculations
    draw stuff
end

This is how loops work, the condition after while will be checked and as long as it's true the code will be executed again and again. The condition will be checked every loop (iteration) so your code will need to break out of the loop eventually. Loops allow you to create interactive programs that don't 'die', it's pretty similar to the way RPG Maker's parallel process and auto start events work, instead of ending somewhere you can do things all over again.

4.1. while
while (condition)
    do something
end

The code between condition and end (do something) will be executed as long as the condition evaluates to true. If it evaluates to false, the loop ends and the code after the loop will be executed. Like the if statement, you don't really need parenthesis around the condition.

4.2. until

until (condition)
    do something
end

Until executes the code between the condition and end (do stuff) until the condition is true, or in other words, while the condition is false. It's the opposite of while.

4.3. Ranges

A range is an ordered sequence of objects (numbers, strings, anything), they aren't loops or anything but they can help you understand the for loop. (which will be discussed next) Basically, a range written as (0..3) includes 4 numbers: 0, 1, 2 and 3. The range ('A'..'D') includes: A, B, C and D. So, a range is just a sequence that can be written as (start..end). You can also write it as (start...end) (3 dots in this version, 2 dots in the earlier examples), doing so will exclude 'end' from the set, for example, 0...3 includes 0, 1 and 2. You can store ranges in variables too.

4.4. for

for varname in range/array
    do something
end

Ruby's for loop is different than the ones you'd find in other programming languages. It simply iterates over a collection (Range/Array) and the variable after the for (varname) will hold the value of the current Range/Array element. For example:

for x in (0..10)
    print x
end

You'll get numbers from 0 to 10 as output for this example. How? For loops over the elements in the range (0..10) and each loop x will be assigned to one element (0, then 1, then 2, etc.), so we just print x's value. If you wanted to write a similar thing using while, you'd do something like:

x = 0
while (x < 11)
    print x
    x += 1
end

See? It takes more lines to do it that way. You might be wondering what x += 1 means, it's just another way of saying x = x + 1. You can also do x -= number, x *= number, x /= number, etc.

So, why do we use for anyways? Why'd we need to increase a number each loop? The main use of the for loop is to deal with arrays, which will be discussed in the next tutorial. An array is just one name that holds many values, and each value is addressed with a number called index. Sometimes you might want to change or view all the values in an array and you use the for loop (or an array method) to do that. More about it in the next tutorial.

4.5. loop

loop do
    do stuff
end

The simplest loop, it doesn't check for any conditions and just keeps looping for ever. Of course, looping forever isn't a good thing, eventually the user would want to exit your program/script/game. The only way to exit such a loop is to break out of it, which is discussed next.

4.6. break, next, retry, redo

Sometimes you might like to control your loops, and you use back, next, retry or/and redo to do that. Break ends the loop and execution continues at the statements after the loop block. (after end) Next skips everything following it and starts a new iteration. Retry starts the loop from the very beginning and redo repeats the current iteration from the start. These examples might help:

# The output of the following loop would be: 0 1 2 3 4 5
# Basically we check if x is equal to 6 and stop looping
for x in (0..10)
    if (x == 6)
        break
    end
    p x
end
# The output of the following loop would be: 0 1 2 3 4 6 7 8 9 10
# Notice how the 5 is missing from the output .When x is 5, next 
# will skip anything after the if (it'd skip p x) and start the next loop (6)
for x in (0..10)
    if (x == 5)
        next
    end
    p x
end

As for retry and redo, basically redo will go back to the beginning of the current loop, if you add a redo after the if in the previous example, the output would be 0 1 2 3 4 and then you'd get an infinite loop (because it'll never get to the print statement (p x) and would check if x == 5 again and again. Retry is similar to redo, but it goes back to the beginning of the entire loop instead from the beginning of the entire iteration, adding a retry after the if in the previous example would get you an infinite loop with output like 0 1 2 3 4 0 1 2 3 4 0 1 2 ....

4.7. Statement Modifiers

In the break and end examples, we had an if statement like:

if (x == 6)
    break
end

You might think it's a bit annoying to put everything on separate lines. In cases like this, you might like to put everything on one line this way:

break if (x == 6)

This if is called the if modifier, it works just like an if but operates on one line. Actually, it can also be attached to a block, but that's another story. You can also have an unless, while, until modifiers:

do something unless condition
do something while condition
do something until condition

5. Conclusion

I realize that this tutorial was boring, but understanding conditional statements and loops is essential to understand more advanced subjects. I think it shouldn't be hard to follow because it's just logic, if something then something, while something is true something will keep happening, for each element in a sequence do something, etc. The next tutorial will introduce you to arrays, hashes, methods and some other topics.

6. Summary

- A Boolean expression is an expression that evaluates to either true or false.
- Comparison operators such as (>, ==, <) are used to compare two values and produce a Boolean value.
- More complex Boolean expressions can be formed by combining two or more expressions with && (and) or ||. (or)
- Conditional statements check if a condition (Boolean expression) is true or false, then executes some code depending on the result.
- If and unless are conditional expressions, you can also add an else or an elsif (else if) to them
- The case statement compares one expression with many other expressions.
- Loops execute some code until some condition is met. (or while it's not met)
- While and until are loop statements.
- A range is a sequence of ordered objects.
- The for loop iterates over each element in an array or a range.
- 3 monkeys are not enough for one day.
- You can control loops with break, next, retry and redo.
- Statement modifiers allow you to write less code.
More in the 'RGSS For Dummies' series:
RGSS For Dummies Tutorial 1: The Basics
RGSS For Dummies Tutorial 2: Variables
RGSS For Dummies Tutorial 3: Control Flow
RGSS For Dummies Tutorial 4: Containers and Methods
RGSS For Dummies Tutorial 5: Object Oriented Programming and More!
RGSS For Dummies Tutorial 6: Game Programming 101
RGSS For Dummies Tutorial 7: Windows for Dummies

Copyright 2007 RPG RPG Revolution.

Contact Us