This journey is meant to be followed in order, from start to finish. Each step unlocks a new power and ends with a small « your turn » challenge. You need to know nothing to begin. By the end, you will have programmed a real little game, a brick-breaker, by putting together everything you learned along the way.

Copy each program into the editor (EDIT), validate with Ctrl+S (on a Mac : +S), then run the command from the ? prompt. Change the numbers, watch what happens : tinkering is how you understand.

The steps : 1. The first line · 2. Smart laziness · 3. Inventing your own words · 4. Building with bricks · 5. Your first error · 6. Deciding · 7. Remembering · 8. The wow effect · 9. Making it move · 10. Draw your own shapes · 11. The bouncing ball · 12. Your game

Step 1. The first line

When GoLogo starts, type ST (SHOWTURTLE) to bring up the graphics area. The turtle is there, in the centre, pointing up. Give it an order :

? FORWARD 100
? RT 90
? FORWARD 100

It moves, turns right, moves again. FORWARD (or FD) moves, RT turns right, LT turns left. With just these, you can already draw a square, side by side.

Your turn : finish the square by hand (four FD and four RT 90).

Step 2. Smart laziness

Doing the same thing four times is tedious to type. A good programmer is lazy : they make the machine repeat. That is what REPEAT is for :

? REPEAT 4 [ FD 100 RT 90 ]

The square in one line. Change the 4 and the angle for other polygons : the angle is always 360 divided by the number of sides.

? REPEAT 3 [ FD 120 RT 120 ]   ; triangle
? REPEAT 6 [ FD 80 RT 60 ]    ; hexagon

Your turn : make a circle. Hint : lots of small steps and tiny turns, for instance REPEAT 360 [ FD 5 RT 1 ].

Step 3. Inventing your own words

You will want to reuse your square without retyping it. So teach the turtle this new word, with TOEND :

TO SQUARE
  REPEAT 4 [ FD 100 RT 90 ]
END

GoLogo replies SQUARE DEFINED. From now on SQUARE is a command like any other. And to choose the size, add a parameter :

TO SQUARE :SIDE
  REPEAT 4 [ FD :SIDE RT 90 ]
END
? SQUARE 50
? SQUARE 150

Your turn : write POLYGON :N :SIDE that draws a polygon with :N sides. (Reminder : the angle is 360 / :N.)

rosette of squares

Twelve calls to SQUARE, turning a little each time : a rosette.

Step 4. Building with bricks

A big program is just small programs placed end to end. Define a wall and a roof, then a house that uses them :

TO WALL
  REPEAT 4 [ FD 100 RT 90 ]
END

TO ROOF
  REPEAT 3 [ FD 100 RT 120 ]
END

TO HOUSE
  CS WALL FD 100 RT 30 ROOF
END

This is the single most important idea in programming : break a big problem into small pieces you know how to solve.

Your turn : add a DOOR to the house. Remember to lift the pen (PU) to move the turtle without drawing, and to lower it (PD) before drawing.

house

HOUSE : a square wall topped by a triangular roof.

Step 5. Your first error

Here you learn something the coloured blocks will never teach you : to read an error and fix it. Type something silly on purpose :

? FORWARD HELLO

GoLogo objects : FORWARD DOESN'T LIKE HELLO. It does not just say « no » : it explains. FORWARD expects a number, not a word. Another classic :

? SQUAR 50
I DON'T KNOW HOW TO SQUAR

A typo : GoLogo does not know SQUAR. You fix it, you try again. That is what programming for real is : you make mistakes, you read the message, you fix them. This reflex will serve you in every language, later on.

GoLogo's error messages are written to be understood. If one day you get stuck, read the message again : it almost always names the command at fault.

Step 6. Deciding

An interesting program does not always do the same thing : it decides. The IF command runs instructions only if a condition is true :

? IF 3 > 2 [ PRINT "BIGGER ]

A condition is a question you answer yes or no (in Logo : TRUE or FALSE). These questions always end with a ? : EQUAL? (equal ?), GREATER? (bigger ?), LESS? (smaller ?). You can also write comparisons with the signs =, >, <, like in maths. With a second list, IF does « otherwise » :

TO SIGN :N
  IF :N > 0 [ PRINT "POSITIVE ] [ PRINT "NEGATIVE_OR_ZERO ]
END

Your turn : write a procedure that says EVEN or ODD depending on the number. Hint : REMAINDER :N 2 is 0 when :N is even.

Step 7. Remembering

To count points or remember a position, the turtle needs memory. A variable is a name that holds a value. You create it with MAKE and read it back with a colon :

? MAKE "SCORE 0
? MAKE "SCORE :SCORE + 1
? PRINT :SCORE            ; prints 1

« Take the score, add 1, put it back in the score. » That is exactly how you keep a point counter in a game. Keep this word SCORE in mind : you will use it again at the end.

Step 8. The wow effect

Here is a surprising idea : a procedure is allowed to call itself. It is like a Russian doll that contains a smaller doll, which contains a smaller one still… We call this recursion, and it is perfect for drawings that repeat at smaller scales. A tree, for instance : a trunk, then two smaller branches, and each branch is itself a little tree! You just need a rule to stop, or it would go on forever : here, we stop when the branch becomes tiny.

TO TREE :T
  IF :T < 10 [ STOP ]      ; branch too small: we stop
  FD :T
  LT 30 TREE :T * 0.7
  RT 60 TREE :T * 0.7
  LT 30
  BK :T
END

TO DRAWTREE
  CS WINDOW SETH 0 BK 150 TREE 120
END

Run DRAWTREE. A few lines, and a whole tree appears. This is often the moment you catch the bug.

fractal tree

Each branch splits into two smaller branches.

Step 9. Making it move

So far the turtle was drawing. Now it will move over time. Two ingredients : WAIT makes a small pause (in sixtieths of a second), and a loop repeats the movement. Here is a sprite you steer with the arrow keys (JOYSTICK 0 is emulated by the arrows) :

TO DRIVE
  CS WINDOW
  SPRITE 2
  WHILE [ NOT BUTTON? 0 ] [
    MAKE "D JOYSTICK 0
    IF :D = 1 [ SETH 0 FD 10 ]     ; up
    IF :D = 5 [ SETH 180 FD 10 ]   ; down
    IF :D = 3 [ SETH 90 FD 10 ]    ; right
    IF :D = 7 [ SETH 270 FD 10 ]   ; left
    WAIT 2
  ]
END

Run DRIVE and steer the car with the arrows. Press the space bar (the fire button) to stop. WHILE repeats the block as long as its condition is true : here, as long as the button is not pressed.

The WINDOW field lets the turtle roam without hitting the edges. It is the mode we use for games.

Step 10. Draw your own shapes

So far the turtle had a ready-made shape. But you can draw it one yourself! The DEFSPRITE command lets you create a shape on a small grid of 16 by 16, a bit like pixel art. Each line is a string of characters : a dot . for an empty cell, a letter (for example X) for a filled cell. Let us draw a round ball and a brick :

DEFSPRITE 3 [
  ..XXXX..
  .XXXXXX.
  XXXXXXXX
  XXXXXXXX
  XXXXXXXX
  XXXXXXXX
  .XXXXXX.
  ..XXXX..
]

DEFSPRITE 4 [
  XXXXXXXXXXXXXX
  XXXXXXXXXXXXXX
  XXXXXXXXXXXXXX
  XXXXXXXXXXXXXX
]

Look closely at the first one : if you squint, the Xs draw a round shape. Shape number 3 is now your round ball, number 4 your brick. You pick them with SPRITE, like the ready-made shapes :

CS ST
SPRITE 3     ; the turtle becomes a round ball
SETPC 1     ; in red (the shape takes the pen colour)

Two things to remember : the numbers of your shapes start at 3 (0, 1 and 2 are the built-in shapes: triangle, turtle and car), and your shape takes the pen colour (SETPC) and turns with the turtle.

Your turn : draw your own shape, a spaceship, a heart, a little person. You will be able to use it in the game, at the end : a real round ball (SPRITE 3) and real bricks looks a lot nicer than triangles.

Step 11. The bouncing ball

Before making a game, one essential brick is missing : a ball that bounces off the edges. It looks complicated, but the idea is very simple.

Imagine the ball moving in small steps, frame after frame. At each step it shifts : a bit to the right, a bit up. We store these two shifts in two variables : :DX (how far right in x) and :DY (how far up in y). As long as we hit nothing, we repeat : move by :DX and :DY, over and over.

Now, the bounce. Think of a real ball you throw at the right-hand wall : it comes back to the left. Its vertical motion does not change, only its horizontal motion flips. In Logo, flipping a number is 0 - :DX (if :DX was 9, that gives −9 ; the ball will now go left). Same at the top and bottom, but there it is :DY that flips. Here goes :

TO INITBALL
  CS WINDOW
  DEFSPRITE 3 [
  ..XXXX..
  .XXXXXX.
  XXXXXXXX
  XXXXXXXX
  XXXXXXXX
  XXXXXXXX
  .XXXXXX.
  ..XXXX..
  ]
  SETTURTLE 0 SPRITE 3 SETPC 7 ST PU SETXY 0 0   ; reuse the round ball (shape 3) from step 10, in white
  MAKE "DX 9 MAKE "DY 6
END

TO BOUNCE
  IF XCOR + :DX > 780 [ MAKE "DX 0 - :DX ]
  IF XCOR + :DX < -780 [ MAKE "DX 0 - :DX ]
  IF YCOR + :DY > 480 [ MAKE "DY 0 - :DY ]
  IF YCOR + :DY < -480 [ MAKE "DY 0 - :DY ]
  SETXY XCOR + :DX YCOR + :DY
END

TO BOUNCEBALL
  INITBALL
  REPEAT 300 [ BOUNCE WAIT 1 ]
END

Run BOUNCEBALL : the ball shoots off diagonally and bounces in every corner. Let us break down BOUNCE, line by line :

We check the edge before moving, so the ball never overshoots. This is exactly the trick we reuse in the game.

Your turn : change :DX and :DY for a faster or slower ball. Put SETPENSIZE 6 first and lower the pen (PD) so it leaves a trail.

Step 12. Your game: the brick-breaker

You have everything you need. A brick-breaker is just an assembly of things you already know : squares (the bricks), a loop, some IFs, a score, and the bouncing ball.

What is new is that we will have several turtles on screen at the same time, one per game object. Each turtle has a number : turtle 0 will be the ball, turtle 1 the paddle, and turtles 2 to 15 the fourteen bricks. To give orders to one precise turtle, you type SETTURTLE followed by its number : after that, the commands (move, place, hide…) talk to that one.

Drawing the game shapes

We learned to draw our own sprites in step 10. Let us use that to give real shapes to our objects : a round ball (shape 3), a wide paddle (shape 4) and a brick (shape 5).

TO SHAPES
  DEFSPRITE 3 [
    ..XXXX..
    .XXXXXX.
    XXXXXXXX
    XXXXXXXX
    XXXXXXXX
    XXXXXXXX
    .XXXXXX.
    ..XXXX..
  ]
  DEFSPRITE 4 [
    XXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXX
  ]
  DEFSPRITE 5 [
    XXXXXXXXXXXXXX
    XXXXXXXXXXXXXX
    XXXXXXXXXXXXXX
    XXXXXXXXXXXXXX
  ]
END

We pick these shapes with SPRITE 3, SPRITE 4, SPRITE 5, and each one takes its turtle's pen colour (SETPC) : we will make the ball white, the paddle gray and the bricks red, right after.

Placing the bricks

SETTURTLE :B selects turtle number :B (and creates it if it does not exist yet). We want to arrange the 14 bricks in a grid : 7 columns, 2 rows. The loop FOR [ B 2 15 ] runs :B through every number from 2 to 15, one brick per turn :

TO SETBRICKS
  FOR [ B 2 15 ] [
    MAKE "I :B - 2
    MAKE "COL REMAINDER :I 7
    MAKE "ROW INTQUOTIENT :I 7
    MAKE "BX 100 * :COL - 300
    MAKE "BY 70 * :ROW + 250
    SETTURTLE :B SPRITE 5 SETPC 1 ST PU SETXY :BX :BY
  ]
END

Each brick takes shape 5 (SPRITE 5) in red (SETPC 1). The middle calculation may look mysterious, but it is just grid arithmetic. We first number the brick from 0 (:I is 0 for the first, 1 for the second…). Then :

Setting up the game

We draw the shapes (SHAPES), prepare the screen, then place the white ball at the centre-bottom and the gray paddle at the bottom :

TO SETUP
  SHAPES
  CS WINDOW HT
  MAKE "SCORE 0
  SETTURTLE 0 SPRITE 3 SETPC 7 ST PU SETXY 0 -100   ; the ball, white
  MAKE "DX 8 MAKE "DY 8
  SETTURTLE 1 SPRITE 4 SETPC 8 ST PU SETXY 0 -400   ; the paddle, gray
  SETBRICKS
END

Breaking the bricks

We go through the 14 bricks and, for each, we ask GoLogo : « does the ball touch it? » That is the job of COLLIDE? : COLLIDE? LIST 0 :B is TRUE if turtle 0 (the ball) and turtle :B (the brick) overlap on screen. (LIST 0 :B just builds the little list of the two numbers, for example [ 0 5 ].)

When it touches, we do three things :

TO HITBRICKS
  FOR [ B 2 15 ] [
    IF COLLIDE? LIST 0 :B [
      ASK :B [ HT ]
      MAKE "DY 0 - :DY
      MAKE "SCORE :SCORE + 1
    ]
  ]
END

One frame of the game

A « frame » is everything that happens in one instant of the game. This time we only bounce off three walls : left, right and top. The bottom is no longer a wall! We move the ball, then :

A game, deep down, is just that : one frame, repeated very fast, over and over.

TO FRAME
  SETTURTLE 0
  IF XCOR + :DX > 780 [ MAKE "DX 0 - :DX ]
  IF XCOR + :DX < -780 [ MAKE "DX 0 - :DX ]
  IF YCOR + :DY > 480 [ MAKE "DY 0 - :DY ]
  SETXY XCOR + :DX YCOR + :DY
  IF COLLIDE? LIST 0 1 [ MAKE "DY ABS :DY ]
  IF YCOR < -480 [ BALLLOST ]
  HITBRICKS
END

When the ball is lost

If the ball shoots to the bottom without the paddle catching it, it is lost. We play a small sound to signal it, then we relaunch it from its starting position, ready to go again :

TO BALLLOST
  PLAY "DO                    ; little « beep » of a lost ball
  SETTURTLE 0 SETXY 0 -100      ; put the ball back at the start
  MAKE "DX 8 MAKE "DY 8   ; and it heads up again
END

Watch it play itself

Even before adding the controls, run this : the ball bounces everywhere and breaks the bricks all by itself. If you see the bricks disappear one by one, your game engine works.

TO DEMO
  SETUP
  REPEAT 500 [ FRAME WAIT 1 ]
END

Your turn, for real

All that is left is to take the controls. Add the paddle steered by the arrows :

TO MOVEPADDLE
  SETTURTLE 1
  MAKE "D JOYSTICK 0
  IF :D = 7 [ IF XCOR > -700 [ SETXY XCOR - 20 YCOR ] ]
  IF :D = 3 [ IF XCOR < 700 [ SETXY XCOR + 20 YCOR ] ]
END

TO PLAYGAME
  SETUP
  WHILE [ :SCORE < 14 ] [
    MOVEPADDLE
    FRAME
    WAIT 1
  ]
  SETTURTLE 0 HT LABEL [ YOUWIN ]
END

We call the procedure PLAYGAME. So run PLAYGAME and move the paddle with the arrows. When the 14 bricks are broken, you win. Well done : you have just programmed a video game.

To go further, it is your turn to invent : You already know how to do everything. The rest is your imagination.

The complete program

Here is the whole game, in one piece. Copy all of it into the editor (EDIT), validate with Ctrl+S, then type PLAYGAME to play :

; --- Draw the shapes: ball (3), paddle (4), brick (5) ---
TO SHAPES
  DEFSPRITE 3 [
    ..XXXX..
    .XXXXXX.
    XXXXXXXX
    XXXXXXXX
    XXXXXXXX
    XXXXXXXX
    .XXXXXX.
    ..XXXX..
  ]
  DEFSPRITE 4 [
    XXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXX
  ]
  DEFSPRITE 5 [
    XXXXXXXXXXXXXX
    XXXXXXXXXXXXXX
    XXXXXXXXXXXXXX
    XXXXXXXXXXXXXX
  ]
END

; --- Place the 14 red bricks in a grid (turtles 2 to 15) ---
TO SETBRICKS
  FOR [ B 2 15 ] [
    MAKE "I :B - 2
    MAKE "COL REMAINDER :I 7
    MAKE "ROW INTQUOTIENT :I 7
    MAKE "BX 100 * :COL - 300
    MAKE "BY 70 * :ROW + 250
    SETTURTLE :B SPRITE 5 SETPC 1 ST PU SETXY :BX :BY
  ]
END

; --- Set up the game: white ball (0), gray paddle (1), bricks ---
TO SETUP
  SHAPES
  CS WINDOW HT
  MAKE "SCORE 0
  SETTURTLE 0 SPRITE 3 SETPC 7 ST PU SETXY 0 -100
  MAKE "DX 8 MAKE "DY 8
  SETTURTLE 1 SPRITE 4 SETPC 8 ST PU SETXY 0 -400
  SETBRICKS
END

; --- Move the paddle with the arrows ---
TO MOVEPADDLE
  SETTURTLE 1
  MAKE "D JOYSTICK 0
  IF :D = 7 [ IF XCOR > -700 [ SETXY XCOR - 20 YCOR ] ]
  IF :D = 3 [ IF XCOR < 700 [ SETXY XCOR + 20 YCOR ] ]
END

; --- Break the bricks the ball touches ---
TO HITBRICKS
  FOR [ B 2 15 ] [
    IF COLLIDE? LIST 0 :B [
      ASK :B [ HT ]
      MAKE "DY 0 - :DY
      MAKE "SCORE :SCORE + 1
    ]
  ]
END

; --- Lost ball (reached the bottom): sound + relaunch from the start ---
TO BALLLOST
  PLAY "DO
  SETTURTLE 0 SETXY 0 -100
  MAKE "DX 8 MAKE "DY 8
END

; --- One frame: move the ball, bounces, paddle, bricks ---
TO FRAME
  SETTURTLE 0
  IF XCOR + :DX > 780 [ MAKE "DX 0 - :DX ]
  IF XCOR + :DX < -780 [ MAKE "DX 0 - :DX ]
  IF YCOR + :DY > 480 [ MAKE "DY 0 - :DY ]
  SETXY XCOR + :DX YCOR + :DY
  IF COLLIDE? LIST 0 1 [ MAKE "DY ABS :DY ]
  IF YCOR < -480 [ BALLLOST ]
  HITBRICKS
END

; --- Start a game (type PLAYGAME) ---
TO PLAYGAME
  SETUP
  WHILE [ :SCORE < 14 ] [
    MOVEPADDLE
    FRAME
    WAIT 1
  ]
  SETTURTLE 0 HT LABEL [ YOUWIN ]
END

And now? Explore the example programs, browse the command reference, and keep tinkering. You are no longer learning to program : you are programming.