P2.5 — Thinking Like a Programmer (Capstone)¶
What you'll learn
- To break a vague, big task into small, named steps — decomposition, the core habit.
- To plan in plain language (pseudocode) before writing code.
- To build in small steps and run often, so bugs are caught while they are still small.
- That you cannot memorize everything — looking it up is a real skill — and that you are now ready for Foundations.
How it applies
- Big tasks are not solved in one leap. "Make an inventory screen" is too big to write directly. Breaking it into named pieces — each a function (P2.1) doing one thing — is how every real program gets built, and how you avoid staring at a blank screen.
- A plan in plain words prevents wrong code. Sketching the steps in pseudocode first catches mistakes in thinking before they become mistakes in code, which are cheaper to fix.
- Small steps keep bugs small. Writing a little and running it often means a new bug is almost always in the few lines you just added — easy to find. Writing a hundred lines then running gives a hundred suspects.
- Nobody memorizes it all. Professionals look things up constantly. Knowing how to find the answer — and that needing to is normal, not a gap — is what makes you self-sufficient. The next book teaches you to read the Godot documentation specifically.
Concepts¶
Decomposition: break the big into the small¶
The defining habit of a programmer is decomposition: taking a task too big to write at once and breaking it into small pieces, each of which is small enough. Each piece usually becomes a function (P2.1) that does one clear thing. "Announce the tournament results" is vague; decomposed, it is:
- find the highest score,
- print each player and their score,
- print the winner's name.
Each of those is a step you can write — a loop here, a comparison there, a function around each. The skill is not knowing a clever trick; it is reducing the scary whole into ordinary parts you already know how to do with the toolbox from P1–P2.
Pseudocode: plan in plain words first¶
Before writing GDScript, sketch the steps in plain language — pseudocode. It has no rules; it is thinking made visible:
set winner_score to 0 and winner_name to ""
for each player in the list:
print the player's name and score
if their score is higher than winner_score:
remember their score and name as the winner
print the winner's name
Now translating to code is mechanical: "for each player" is a for loop (P1.6, P2.2), "if their score
is higher" is an if with a comparison (P1.4–P1.5), "remember their score" is assignment (P1.2). The
hard part — deciding what the steps are — was done in plain words, where mistakes are obvious and
cheap. Planning first is not slower; it is what makes the coding fast.
Build small, run often¶
Do not write the whole thing and then run it. Write one piece, run it, confirm it works, then add the next. When a bug appears — and one will (P2.4) — it is almost certainly in the small piece you just added, so it is easy to find. This is the same discipline as changing one thing at a time while debugging, applied to writing: small increments keep cause and effect close together.
Look it up¶
You have learned values, variables, types, operators, decisions, loops, functions, collections, objects, and debugging. That is the universal toolbox — but you will constantly need a specific detail: the exact name of a function, what arguments it takes, what it returns. No one memorizes all of that. Looking it up is not a failure; it is the normal, daily activity of programming. The skill is knowing that the answer exists, where to look, and how to read what you find. Foundations teaches you to read the Godot documentation — for now, internalize that "I don't remember the exact name" is answered by looking, not by feeling stuck.
Example
Decomposition turning a vague task into known pieces:
Task: "Total the prices in a cart, and if the total is over 100, apply a 10% discount."
Pseudocode:
set total to 0
for each price in the cart:
add the price to total
if total is over 100:
reduce total by 10%
print total
Every line maps to something you own: a variable (P1.2), a for over a list (P1.6, P2.2),
accumulation with assignment, an if with a comparison (P1.4–P1.5), arithmetic. You could even
wrap it in a function func cart_total(cart): ... (P2.1) that returns the total, so the rest of the
program just calls it. Nothing here is new — the only work was breaking the sentence into steps.
That is the whole job, and you can now do it.
Walkthrough¶
A capstone exercise that uses the whole toolbox. Build it in small steps, running after each.
- Make a list of scores, e.g.
var scores := [40, 90, 75, 100]. Run a loop that prints each score. Run it; confirm. - Add a running total: a
totalvariable, add each score inside the loop, printtotalafter. Run; confirm the sum. - Add a decision: track the highest score seen with a variable and an
ifinside the loop (if this score is greater than the best so far, update the best). Print the best after the loop. Run; confirm. - Wrap the "find the best" logic in a function
func highest(list): ...that returns the largest value, and call it. Run; confirm it matches. You have just decomposed, used a loop, a decision, a collection, and a function — and tested at every step.
Optional sanity check
Before writing step 3's code, write its pseudocode in a comment first (# for each score: if it's
bigger than best, best = score). Then translate it line by line. Notice how the code almost writes
itself once the plain-words plan exists — and how a flaw in the plan (forgetting to initialize
best) is easier to spot in the comment than in the code.
Self-check quiz¶
Q1 — What is decomposition, and why is it the core programming habit?
A. Deleting code you don't need. B. Breaking a task too big to write at once into small pieces (often functions), each small enough to write with the basics you know. C. Memorizing every function name. D. Running the program many times.
Reveal answer
B. Decomposition reduces an overwhelming whole into ordinary parts you can each handle — the habit behind building anything non-trivial. A is unrelated (that's cleanup). C is the opposite of the "look it up" lesson. D is good practice but is not decomposition.
Q2 — Why write pseudocode (a plain-words plan) before the real code?
A. It is required by GDScript. B. It works out what the steps are in a place where mistakes are cheap and obvious, making the translation to code mechanical. C. It makes the program run faster. D. It replaces the need to test.
Reveal answer
B. Pseudocode separates the hard part (deciding the steps) from the mechanical part (writing syntax), catching thinking-errors early and cheaply. A is false (it is a habit, not a requirement). C confuses planning with runtime speed. D is wrong — you still test.
Q3 — You don't remember the exact name of a function you need. The right move?
A. Give up; you weren't meant to do this. B. Look it up — needing to is normal; knowing where to find the answer is the actual skill. C. Guess names at random until one works. D. Memorize the entire language first.
Reveal answer
B. Looking things up is the daily reality of programming, not a personal failing; the skill is knowing the answer exists and how to find it (Foundations teaches the Godot docs). A defeats you over something routine. C is flailing. D is impossible and unnecessary.
Integration question¶
Q4 — open
Capstone synthesis. You are asked: "Given a list of enemies (each an object with a health
property), print a report of how many are alive (health above 0), how many are defeated, and the
total health remaining." Without writing full code, lay out how you would think through this —
the decomposition into steps/pseudocode, and which primitive from P1–P2 each step uses — and then
state honestly what this book has and has not prepared you for as you move to Foundations.
Reveal expected answer
Decomposition / pseudocode:
set alive to 0, defeated to 0, total_health to 0
for each enemy in the list:
add enemy.health to total_health
if enemy.health > 0:
add 1 to alive
else:
add 1 to defeated
print alive, defeated, total_health
Primitive per step: three counters are variables (P1.2) initialized to 0; "for each
enemy in the list" is a for loop over a collection (P1.6, P2.2); enemy.health reads a
property of an object (P2.3); "add to total" is assignment/arithmetic (P1.2, P1.4);
"if health > 0 … else" is a decision with a comparison (P1.4–P1.5); and the whole thing
could be wrapped in a function that returns the three numbers (P2.1). If a count came out
wrong, I would debug by printing the counters inside the loop to see where they diverge
(P2.4). Every step is something this book taught.
Honest readiness: this book has given you the concepts — you can now read and reason about variables, types, decisions, loops, functions, collections, and objects, and you have a debugging mindset and the decomposition habit to attack a new problem. What it has not given you is the GDScript and Godot specifics: how the type system enforces types, the value-versus-reference rules, how objects become nodes in a scene, how signals and the engine loop work. That is exactly what Foundations teaches next — and because you now own the concepts, Foundations can move fast, teaching the delta rather than the basics. You are no longer "someone who has never coded"; you are a programmer ready to learn Godot.