Blocks and indents

While many programming languages use curly brackets (C, C++, Java) or keywords like begin and end (Pascal) to mark blocks of code, Ren'Py and Python use indentation. It follows that you have to be really careful about indentation as a mistake changes the meaning of your code.

Important: Set up whatever editor you are using to insert spaces when the tab key is pressed, and the width of a "tab" to something sensible like four spaces instead of the default eight. It really is best to use a dedicated code editor like Visual Studio Code rather than a plain text editor like Notepad as it will help you line up your indentation by providing vertical rules, keys to shift selected text left and right, and warnings when it can tell the indentation is wrong.

What is a block?

A block is a list of related statements that are either run one after another, or not at all. Blocks start with a line ending in a colon : all the statements in a block have to be indented, and the block ends when the indentation reverts back to the same level as the line that had the colon at the end.

Confused? Let's look at an example Ren'Py menu as this is likely where you will first encounter blocks:

label sandwich:
    menu:                              # This starts a new block for the menu options
        "What sandwich should I pick?" # Menu prompt doesn't start a block
        "Bacon, lettuce, and tomato":  # Menu option with a colon starts a block
            "You bite into your classic sandwich."
            npc "Is that good?"
            pc "Yes, it really is!"
        "Smelly cheese and onion":     # Another menu option with a colon starts another block
            "This sandwich is tasty, but the onions are particularly strong."
            npc "Ugh, your breath! Can you at least face the other way?"
    # This next line is indented the same as the menu so it ends the menu
    "Lunch finished you have to decide what to do next."

The line label sandwich: ends with a colon and marks the beginning of a block. The line menu: also ends with a colon, so it's expecting the things in the menu to be in a block, and they must be indented. There are three lines in the menu: the prompt that goes in the say box "What sandwich should I pick?", and two options for the player to pick from "Bacon, lettuce, and tomato" and "Smelly cheese and onion".

Both the sandwich options also end in a colon (which marks them as options, not the prompt), so they start their own blocks which are indented further. These blocks detail the interactions between the player character pc and a non-player character npc when the option is chosen.

Finally, the last line shares the same indentation as the menu: so it marks the end of the menu's block. That line gets executed whichever option the player chooses.

Note: because the pc and npc interactions are in a block you don't have to jump out of the menu to a label for each interaction. It makes the code a spaghetti mess:

# Don't be tempted to do this!
label sandwich:
    menu:
        "What sandwich should I pick?"
        "Bacon, lettuce, and tomato":
            jump blt
        "Smelly cheese and onion":
            jump cno
        
label blt:
    "You bite into your classic sandwich."
    npc "Is that good?"
    pc "Yes, it really is!"
    jump afterSandwich

label cno:
    "This sandwich is tasty, but the onions are particularly strong."
    npc "Ugh, your breath! Can you at least face the other way?"
    jump afterSandwich

label afterSandwich:
    "Lunch finished you have to decide what to do next."

And yes, I know there's an example  like this in the getting started guide. I just don't think you should follow it. It's specifically about using menus and jumps to illustrate both in a compact way.