Back to Minecraft Lessons
Lesson 3 · Self-Paced

The Builder & Relative Coordinates

Meet a faster block-placer, learn the tilde, and combine everything from Lessons 1 and 2.

ESSENTIAL QUESTION

How can choosing a smarter tool let your code do the same job in far fewer lines?

By the end of this lesson, I will...

  • Explain how the Builder is different from the Agent.
  • Read and write relative coordinates using the ~ (tilde) operator.
  • Use builder.move, builder.turn, and builder.trace_path to draw a shape.
  • Make the same program more efficient by moving trace_path outside the inner loop.
  • Use builder.mark() and builder.line() to draw long lines in one step.
  • Combine loops (Lesson 2) with the Builder to build a wall or repeating structure.
Every Lesson

Start Here First — Every Single Time

Every Minecraft lesson begins with a brand-new world. Do not skip this. Open Lesson 0, follow the setup steps, then come back here and continue with Step 1.

Open Lesson 0 — World Setup

What you already know

Today's lesson builds on everything from Lessons 1 and 2. Here's the toolkit you bring in:

From Lesson 1Sequences run in order. Events (player.on_chat) start your code.
From Lesson 2For loops repeat instructions. Nested loops make 2D patterns.
New todayThe Builder (invisible, fast) and relative coordinates with ~.

STEP 1 Warm-up: Meet the Builder

You've spent two lessons with the Agent — a visible character you can watch walk around the world. The Agent is great for learning because you can see what your code did.

Today you'll meet the Builder. The Builder does similar work but with three big differences:

AgentBuilder
Visible?Yes — you can see it.No — it's invisible while working.
SpeedSlow — walks one block at a time.Fast — can teleport and stamp lines.
InventoryNeeds set_item first.No inventory needed — just say which block.
Best forLearning, debugging, watching what code does.Big builds, walls, lines, structures.
You'll still use both. The Agent is easier to debug because you can watch it. The Builder is faster once you know what you want. Real programs often use whichever fits the job.

Today's Vocabulary

BuilderAn invisible, faster block-placing tool with its own commands.
Relative coordinateA position written with ~ meaning "offset from here."
trace_pathStamps a block trail along the Builder's recent route.
markSaves the Builder's current position.
lineDraws a straight line of blocks from mark to where the Builder is now.

STEP 2 Open MakeCode (Python Only)

You should already be in your fresh flat world from Lesson 0. If not, go back and complete Lesson 0 first.

  1. In Minecraft, press C to open Code Builder.
  2. Choose MakeCode.
  3. Click New Project and name it Lesson 3 - Builder.
  4. Click Code options, then select Python Only, then click Create.

STEP 3 Relative Coordinates with ~

Minecraft has two ways to describe a position. Absolute coordinates use exact world numbers (like X = 200, Y = 64, Z = -57). Relative coordinates use the tilde character ~ and mean "offset from where the player is standing."

PositionWhat it means
pos(~0, ~0, ~0)Exactly where the player is standing right now.
pos(~5, ~0, ~0)5 blocks east of the player (X axis).
pos(~0, ~3, ~0)3 blocks up from the player (Y axis).
pos(~0, ~0, ~5)5 blocks south of the player (Z axis).
pos(~-2, ~0, ~0)2 blocks west of the player (negative direction).
Why this matters: If you write absolute coordinates (no ~), your program only works at one specific spot in the world. With ~, the same program works wherever the player is standing. Relative coordinates make your code portable.

You'll see pos(~0, ~0, ~0) a lot in this lesson. It just means "start here."

RECAP First, the Agent Way (from Lesson 2)

You already know how to make a 5×5 square outline with the Agent. Here it is one more time so we have something to compare with:

def on_chat():
    agent.set_item(STONE, 64, 1)
    for side in range(4):
        for step in range(5):
            agent.move(FORWARD, 1)
            agent.destroy(DOWN)
            agent.place(DOWN)
        agent.turn(LEFT_TURN)
player.on_chat("agent_square", on_chat)

If you want to feel the difference, paste this in and run it with the chat command agent_square. You'll watch the Agent walk every block, one at a time. It works — but you'll see why the Builder is appealing.

STEP 5 Builder Version 1: Just Like the Agent

Here is the same 5×5 square — but written with the Builder. Look carefully at the differences.

def on_chat():
    # Start fresh: warp the Builder to the player. This resets where the
    # Builder is so the program produces the same result no matter what ran before.
    builder.teleport_to(pos(~0, ~0, ~0))
    for side in range(4):
        for step in range(5):
            builder.move(FORWARD, 1)
            builder.trace_path(STONE)
        builder.turn(TurnDirection.LEFT)
player.on_chat("build1", on_chat)

What changed

  • builder.teleport_to(pos(~0, ~0, ~0)) — warp the Builder to where the player is standing. This is a one-line replacement for "summon and position the Agent."
  • builder.move(FORWARD, 1) — same idea as agent.move, but for the Builder.
  • builder.trace_path(STONE)stamps a stone block on the Builder's path. No set_item, no destroy, no inventory worries.
  • builder.turn(TurnDirection.LEFT) — same idea as agent.turn(LEFT_TURN), but the constant name is different. (Don't ask me why — it just is.)
Predict: how is the result different from the Agent version? How does the experience of running it differ?

The result is the same: a 5×5 stone outline. The experience is very different — you won't see anything walking around the world. The square just appears. The Builder is invisible.

Step back first. The Builder teleports to your spot, so anything it builds will end up around your feet. Before running the chat command, press T to open chat, type /tp ~ ~ ~10, and press Enter to jump 10 blocks south. Now there's open ground in front of the Builder and you'll have a clear view of what it does.

Run it with the chat command build1 and watch the square pop into existence.

STEP 6 Builder Version 2: One Trace at the End

The Builder has a trick the Agent doesn't have. You can walk the whole path first, then call trace_path once at the very end. The Builder remembers every step it took and stamps the blocks along the whole route.

def on_chat():
    # Start fresh: warp to the player so this function stands alone.
    builder.teleport_to(pos(~0, ~0, ~0))
    for side in range(4):
        for step in range(5):
            builder.move(FORWARD, 1)
        builder.turn(TurnDirection.LEFT)
    builder.trace_path(STONE)
player.on_chat("build2", on_chat)

What changed (and why it's better)

  • trace_path(STONE) moved outside the inner loop — it's the last line of the function.
  • The Builder walks the entire square path first, then trace_path stamps all the stone in one operation.
  • Result is identical to Version 1, but the program does its work in one big stamp instead of 20 small ones.
The pattern: The hot, slow part of the loop is now outside it. Whenever you can do an expensive operation once instead of many times, your code becomes more efficient. This is the same idea as Lesson 2's loop — replacing repetition with one well-placed statement.
Step back first. Before running this one, open chat (T), type /tp ~ ~ ~10, and press Enter. Standing 10 blocks back lets you see the entire square at once. Then run the chat command build2.

STEP 7 Builder Version 3: mark() and line()

For straight lines the Builder has a faster trick still: mark a spot, teleport somewhere else, and draw a line between them.

def on_chat():
    # Start fresh: warp to the player so this function stands alone.
    builder.teleport_to(pos(~0, ~0, ~0))
    builder.mark()
    builder.teleport_to(pos(~100, ~0, ~0))
    builder.line(STONE)
player.on_chat("long_line", on_chat)

How this works

  1. teleport_to(pos(~0, ~0, ~0)) — place the Builder at the player's spot.
  2. mark() — remember this position.
  3. teleport_to(pos(~100, ~0, ~0)) — warp 100 blocks east.
  4. line(STONE) — fill every block between the mark and here with stone.
Predict: how many stone blocks will appear, and how long does the program take to run?

Roughly 100 stone blocks stretching east from where you stand — and the whole thing happens almost instantly. You did the work of a 100-iteration loop in 4 lines of code.

When to use which:
  • trace_path — you walked a curvy path and want to stamp blocks along the route.
  • mark() + line() — you want a straight line between two points. Way faster than walking.
  • agent.move + place — you want to see the work happen for debugging or for fun.
Step back first. The line shoots out 100 blocks east of you, so the start of the line will be right under your feet. Before running, open chat (T), type /tp ~ ~ ~10, and press Enter. The line will run alongside you instead of into you. Then run long_line.

STEP 8 Combining Loops with mark() and line()

Now bring the two pieces together. We use a loop (from Lesson 2) to repeat a mark/line pair. Each iteration draws one row, and after drawing we step the Builder up by 1. Result: a wall.

def on_chat():
    # Start fresh: warp to the player so this function stands alone.
    builder.teleport_to(pos(~0, ~0, ~0))
    for layer in range(5):
        builder.mark()
        builder.move(FORWARD, 10)
        builder.line(STONE)
        builder.move(BACK, 10)
        builder.move(UP, 1)
player.on_chat("wall", on_chat)

Reading this nested idea

  • The loop runs 5 times — one per layer of the wall.
  • Each iteration: mark the spot, walk forward 10, draw a stone line back to the mark.
  • Then walk back to the start of this row (so the next mark begins lined up).
  • Move up 1 block to start the next layer.
  • Total: a wall 10 blocks long, 5 blocks tall.
Predict: if you change range(5) to range(15), what changes? What if you change FORWARD, 10 to FORWARD, 30?

range(15) → the wall becomes 15 blocks tall instead of 5. Same length, more height.

FORWARD, 30 (and BACK, 30) → the wall becomes 30 blocks long. Same height, much longer.

Step back first. Before running this one, open chat (T), type /tp ~ ~ ~10, and press Enter. You'll be 10 blocks south of where the wall builds, with a clean view of the whole thing.

Run it as wall and look at what just appeared. Try the changes from the prediction prompt and watch the wall scale up.

CHALLENGE Build Something Big

Create an original Builder program that uses at least one loop and either mark()+line() or trace_path(). Pick a challenge below — or invent your own.

Option A — The Big Floor

Use a loop and mark()/line() to draw 20 parallel stone lines side-by-side. You should end up with a flat 20×20 floor.

Option B — The Tall Tower

Use a nested loop to build a rectangular tower: 4 walls, each at least 8 blocks tall. Use a different block material (glass, oak planks, brick) for variety.

Option C — Custom Skyscraper

Combine everything: nested loops, mark/line, multiple block types. Build a recognizable structure with at least two rooms or two visible patterns.

Minimum requirements

  • Your program starts with a chat command.
  • Your program uses at least one for loop.
  • Your program uses the Builder — not the Agent.
  • Your program uses at least one of: trace_path, mark()+line().
  • Your program uses relative coordinates (~) at least once.
  • Your build covers a footprint of at least 10×10 blocks, or stands at least 8 blocks tall.

Stretch goals

  • Build a filled rectangle floor (not just an outline) using nested loops and mark()+line().
  • Use multiple block types — alternate stone and glass to make a checker or stripe pattern.
  • Add an opening (door or window) by skipping certain iterations with an if statement.
  • Add # comments above each section to explain what it does.

SUBMIT Turn In Your Work

Submit three items to the Schoology assignment:

  1. Screenshot of your code in the MakeCode editor. Your loop and your Builder commands must be visible.
  2. Screenshot of the result in Minecraft — the structure or pattern your Builder created.
  3. Short written reflection. Answer all four in 1–2 sentences each:
    • What did your program build, and which Builder commands did you use?
    • Where in your code did you use ~ (relative coordinates)? Why is that useful?
    • Compare: how would this same build look if you wrote it with the Agent? Faster or slower? Why?
    • Describe one bug or surprise you ran into and what fixed it.
Important: The reflection counts for half the grade. Show that you understand why the Builder was the right tool for this job — not just that it worked.

When You're Done

  • Trade computers and run a classmate's program.
  • Look up builder.fill in the MakeCode docs — it fills a solid box between two marked corners in one call.
  • Try building a hollow cube using mark() + line() for each edge.
  • Re-write your Lesson 2 challenge using the Builder. How much shorter does the code get?
Back to Minecraft Lessons