P1.5 — Making Decisions¶
What you'll learn
- How
ifruns a block of code only when a condition istrue. - How
elseandelifadd alternative paths. - How indentation decides which lines belong inside a branch.
- That a decision with no catch-all simply does nothing for cases you did not handle.
How it applies
- Decisions are how a program reacts. "If health is zero, end the game"; "if the score beats the
record, save it." Without
if, a program runs the same straight line every time, unable to respond to what is actually happening. - An unhandled case silently does nothing. If your branches cover the situations you thought of and there is no catch-all, an unexpected value falls through and the program just... continues, doing nothing — a quiet bug with no error. Deciding what "everything else" should do is part of the job.
- Indentation is not decoration. The indented lines under an
ifare the ones that run when the condition is true; a line you forgot to indent runs always. Wrong indentation changes which code is conditional — a real and common mistake. =in a condition is a trap. A condition asks a question, so it uses==; writing=there is an assignment, which is either an error or silently changes a variable while pretending to test it (P1.4).
Concepts¶
if: run code only when a condition is true¶
An if statement runs a block of code only if a condition (an expression that is true or
false, P1.4) is true:
Read it as: "if health <= 0 is true, run the indented line(s); otherwise skip them." The condition
goes after if, followed by a colon :. The lines that run when it is true are indented beneath
it. If the condition is false, the indented block is skipped entirely and the program continues below.
else: the other path¶
An else attaches a block that runs when the if condition is false:
Exactly one of the two blocks runs every time: the if block when the condition is true, the else
block when it is false. else has no condition of its own — it is simply "in every other case."
elif: more than two paths¶
For several mutually exclusive cases, elif ("else if") adds extra conditions, each tested in
order until one is true:
if health <= 0:
print("You died.")
elif health < 20:
print("Warning: low health!")
else:
print("Healthy.")
The computer checks top to bottom and runs the first block whose condition is true, then skips the
rest. So with health of 15: health <= 0 is false (skip), health < 20 is true → print the
warning, and the else is skipped. Order matters — the first match wins.
Indentation defines the block¶
The indentation is how GDScript knows which lines are inside a branch:
if score > best:
best = score # inside the if — runs only when score > best
print("New record!") # also inside — same indentation
print("Done.") # NOT indented — runs always, after the if
Both indented lines belong to the if. The un-indented print("Done.") is outside it and runs every
time, no matter the condition. Move that last line one tab to the right and it would suddenly only run
on a new record — a different program. Indentation is part of the meaning, not formatting.
Example
A decision reacting to a value, traced:
var temperature := 15
if temperature > 30:
print("Hot.")
elif temperature > 10:
print("Mild.")
else:
print("Cold.")
With temperature of 15: temperature > 30 is false (skip "Hot."); temperature > 10 is true →
print Mild. and skip the rest. Change temperature to 5 and trace it again: both conditions are
false, so the else runs and prints Cold.. The else is what guarantees something sensible
happens for values none of the named conditions caught — without it, a temperature of 5 would
print nothing at all.
Walkthrough¶
Use your P1.1 script setup.
- Set
var health := 100. Write anif health <= 0:that prints"You died."Run — nothing prints (the condition is false). Changehealthto0, run, and the message appears. - Add an
else:that prints"Still standing."Run at a fewhealthvalues and confirm exactly one message prints each time. - Expand to three cases with
elif health < 20:printing a warning. Test withhealthof100,15, and0, and confirm the right branch fires each time. - Indentation test: after the whole
if/elif/else, addprint("Turn over.")with no indentation. Confirm it prints every time. Then indent it under theelseand watch it only print in theelsecase — proof that indentation decides membership.
Optional sanity check
Remove the else entirely and set health to a value none of your conditions catch (e.g. a middle
value if your conditions only cover extremes). Run: nothing prints for that case — the program
silently did nothing. Put the else back. That silence is exactly the "unhandled case" bug, felt
directly.
Self-check quiz¶
Q1 — In an if / elif / else, how many blocks run, and which?
A. All blocks whose conditions are true.
B. Exactly one: the first block (top to bottom) whose condition is true, or the else if none match.
C. Always the else.
D. None, unless every condition is true.
Reveal answer
B. The computer checks conditions top to bottom and runs the first one that is true, then
skips the rest; if none are true, the else runs (if present). A is wrong — later true
conditions are skipped once one matches. C and D misdescribe the flow.
Q2 — An if/elif has no else, and the current value matches none of the conditions. What happens?
A. The program crashes.
B. Nothing — all blocks are skipped and the program continues, doing nothing for that case.
C. The first block runs anyway.
D. The last elif runs by default.
Reveal answer
B. With no matching condition and no else, every block is skipped and execution simply
continues past the if — a silent no-op, which is why an unhandled case is a quiet bug. A is
wrong (no crash). C and D invent a default that does not exist without an explicit else.
Q3 — Why must a condition use == and not =?
A. They are interchangeable in conditions.
B. A condition asks a question, which is == (compare); = is assignment and would change a variable instead of testing it.
C. = is faster.
D. if only accepts numbers.
Reveal answer
B. A condition must evaluate to true/false, which is what == does; = assigns a value
(changing data), so it is wrong inside a condition — the P1.4 trap, here where it bites most. A
is false. C is irrelevant. D invents a restriction (conditions test bools, text, etc., not just
numbers).
Integration question¶
Q4 — open
A game should print "Level up!" when xp reaches 100 or more, "Keep going." when xp is
between 1 and 99, and "No XP yet." when xp is 0. A teammate writes three separate if
statements (not elif), and also indents the final "No XP yet." print so it sits inside the
second if. Explain the two problems this causes, and rewrite it correctly using if/elif/else,
referencing how branch selection and indentation work.
Reveal expected answer
Problem 1 — separate ifs instead of elif/else. Three independent ifs each test on
their own, so for some values more than one could fire (or the logic is harder to keep mutually
exclusive), and there is no single guaranteed catch-all; the cases are meant to be one decision
with exactly one outcome, which is what if/elif/else expresses — the first true branch wins
and the rest are skipped. Problem 2 — wrong indentation. Indenting "No XP yet." inside the
second if makes it run only when that if's condition is true, not when xp is 0; indentation
decides membership, so the misplaced line belongs to the wrong branch. Correct version:
Checked top to bottom, exactly one branch runs: xp of 150 hits the first; 50 falls to the
elif; 0 falls to the else. Ordering the conditions from highest threshold down, and letting
the else catch 0, makes every value land in exactly one correct branch — and each print is
indented under its own branch, so it runs in that case and no other.