Track: Making Games · Lesson 8 of 10 · Ages: 8+ · Time: 45 minutes
Have you ever played a level that felt perfect? The first part is easy, then it gets trickier, and when you finally win it feels amazing. Other levels are the opposite: too hard, confusing or boring. The people who plan levels are called level designers, and they start with pencil and squared paper. Today you will become one.
Beep says I love levels with lots of batteries and not too many puddles. I do not like puddles. They make my wheels squeaky. Beep boop!
What you need
- Squared paper and a pencil
- Coloured pencils (optional)
- A friend or family member to try your levels
- A computer with Python 3 for the optional coding part
- About 45 minutes
Grown-ups Level design needs no screen. Squared paper is the perfect tool, and the testing is simply a person tracing a path with a pencil. Let your child run the “playtest” by watching you try their level without giving any hints. The coding section is optional and shows how a level drawn on paper can be stored as text.
Draw a level
Draw a grid of squares on your paper, for example 8 squares across and 5 squares down. Each square is a bit of ground. Now use symbols to fill it in:
| Symbol | What it means |
|---|---|
S | Start: where the player begins |
F | Finish: the goal |
* | A star to collect |
# | A puddle to avoid |
. | Plain ground |
The player moves one square at a time, up, down, left or right. They cannot step on a puddle. Here is a level drawn in colours: green for the start, yellow for stars, blue for puddles, grey for ground and orange for the finish. A little further down you will see the very same level written with the symbols.

Store a level in Python
A level on paper is a grid of symbols. In Python we can store the same thing as a list of text rows. Each row is one line of the grid. This program prints the level and counts the stars and puddles, using row.count("*"), which tells us how many times a symbol appears in one row.
level = [
"S..*....",
".#...#*.",
"..*.#...",
".#...*#.",
"...*...F",
]
stars = 0
puddles = 0
for row in level:
print(row)
stars = stars + row.count("*")
puddles = puddles + row.count("#")
print("Stars:", stars)
print("Puddles:", puddles)
S..*.... .#...#*. ..*.#... .#...*#. ...*...F Stars: 5 Puddles: 5
Pixel says Look at the numbers. Five stars and five puddles. Counting things is a quick way to check if a level feels balanced. Too many puddles and it will feel cruel. Meow!
Make it fair
A fair level is hard but never cheating. Every good designer follows rules like these:
- There is always a way through. Before anyone plays, trace a route from start to finish yourself.
- The player can see danger coming. A puddle should never be hidden. The player should lose because of a choice, not because of a surprise.
- Learn first, then test. Show a new idea in a safe place before you make it difficult.
- Risk deserves a reward. If a star sits next to a puddle, the player has to decide if it is worth it.
Here is a route through our level, drawn with Beep. It goes along the top and then down the right-hand side. It is a safe route, so the level passes rule 1. The dark brick squares in the picture stand for the puddles.

The difficulty curve
When you have several levels, think about how hard each one is. Draw a line on paper that goes up as the levels go on. That picture is called a difficulty curve.
A very good pattern is to take four steps for each new idea:
| Step | What happens |
|---|---|
| Teach | The idea appears in a safe place, so the player can try it |
| Practise | The player uses the idea a few times |
| Twist | The idea is used in a surprising way |
| Test | A harder challenge that needs everything the player has learned |
Say your new idea is puddles. In level 1 you could place a single puddle in the open, where the player can easily see it and walk around it. In level 2 there are several puddles and the player has to plan a route. In level 3 the puddles block the straight route, so the player has to take a long way round.
Here is that plan as three tiny levels, with a program that counts the puddles in each. The number should go up level by level.
levels = [
["S..*..F", ".......", "..#...."],
["S.#*..F", ".....#.", "..#.#.."],
["S#.*#.F", ".#...#.", "...#..."],
]
for number in range(len(levels)):
puddles = 0
for row in levels[number]:
puddles = puddles + row.count("#")
print("Level", number + 1, "puddles:", puddles)
Level 1 puddles: 1 Level 2 puddles: 4 Level 3 puddles: 5
The loop inside a loop is called a nested loop. The outer loop visits each level and the inner loop visits each row in that level. Each of the three levels can be walked from S to F, so all three are fair.
Did you know? Many games hide their tutorial inside level 1. The player never reads a long list of instructions. They just play a gentle first level that teaches by doing. That is the “teach” step in action.
Challenges
Try it Design three levels of your own on squared paper using the symbols above. Level 1 should teach, level 2 should practise and level 3 should have a twist. Count the puddles in each. Then trace a safe route through every level.
Try it Give your level to a friend and ask them to trace a route with a pencil while saying what they are thinking out loud. Do not help! Where did they get stuck? Was it your design or their plan?
Try it One of these two levels is unfair. Trace a route from S to F with your pencil. Which level cannot be finished?
Level A Level B S.#.. S.#.. ...#. ..#.. ....F ..#.F
Show the answer
Level B is the unfair one. Its three puddles make a wall down the whole third column, so there is no way across to F. Level A is fair. Go down 1 square, right 2 squares, down 1 square, then right 2 squares, and you reach F without touching a puddle.
What you learned
- A level designer plans levels on squared paper before building them.
- A level can be stored in Python as a list of text rows, and
row.count(...)counts symbols. - A fair level always has a way through, shows its dangers and teaches before it tests.
- A difficulty curve is how the challenge rises from level to level.
