Can't get Renpy menu to work?

I’m presently stuck in a loop where I simply cannot get a sequence of menu choices to work. I’ve tried following tutorials down to the letter and then editing the sequence in every minute way I can think of, but it either won’t load or it returns me to start screen when a question is picked, which is not what I want to happen.

The “return” command is what’s stumping me, I think.

Without giving away any details, here’s what I’m trying to do:

There’s a series of questions the player can ask of an NPC based on what species the NPC is (which is chosen earlier in the game). So the sequence starts with an “if” statement regarding the race, then continues to the question menu. And it’s supposed to loop so that the player can ask each question of the NPC, with a few questions leading to additional looped question lines as well as a few non-looping ones, all of it coming back to the main set.

But I cannot, for the life of me, get it to loop right. Every time I try to check and test it, I either get an error “expected menu item” regardless of whether or not I’m trying to use a name for the menu, it gives me a crash screen when it encounters the return command, or it returns to the start screen.

I suspect my problem is some combination of names and indentations, but I can’t puzzle out what is wrong with it.

Hard to say without seeing the code, but reading over your goal, I suspect you’ve got the wrong keyword.

  • return means exit the function and provide a response (if any) to whatever called it
  • continue means skip the rest of this iteration of the loop, and continue on with the next iteration
  • break means exit the loop that you called this in and continue with any code after the loop

Inside your loops, assuming you want to continue on to the next question, you probably either want to use continue or break, depending on how you’ve got it set up.


Here is a simple menu in a loop. The pages that follow also cover conditional menu items and menu sets.

Indentation to mark the beginning and ends of blocks of statements is critical in Ren’Py and Python. It literally counts spaces, so you can’t be out by even one. This is where a dedicated code editor helps. Ever line that ends with a : starts a block and needs the next line(s) to be indented.

If you return from somewhere and you haven’t reached there with a call (ie. the call stack is empty) that return will take you back to the start menu.


Find an editor that auto indents correctly to address what dingotush above states. That is the most common mistake for languages that rely on indentation.

If you’ve only programmed a little before this, it might be worth doing a simple python project (something like guess-the-number) to get solid on the basics of variables, conditionals, loops, and functions.

Otherwise, this sounds more ren’py specific, and I got nuthin’, sorry.

This was super helpful, thank you so much! I actually got the menu to work. Turns out that yeah, using “return” was a mistake (a tutorial I read suggested that “return” can bring you back to a former label, but evidently I still don’t understand it lol), and my other problem was that I was using the command “jump menu [example]” so it was looking for another menu…

I just needed to take that out, lol.

1 Like

Renpy does have a checker for that, and it lets me know when the indents are wrong… but it doesn’t help so much when I’m using the wrong commands, y’know? XD

Funny enough this is my first project and I simplified the plot and requirements and such as much as I could so I could learn it. On the bright side, it’s working. I’m very much the “learn by seeing the example” kind of person, so seeing functional coding helps me to understand it.

I’m making great strides!

It will go back to a previous call, not a previous label. I’d personally recommend getting used to the structured call & return pairs over using jump everywhere. Using jump alone makes it too easy to write unfathomable (even to you) spaghetti code, which can lead to errors that are hard to find. This is why some tutorials such as the excellent Lezalith’s Programming Cave deal almost exclusively with call/return.
I’d also recommend keeping your code out of script.rpy. See:


Thanks for the link. Yeah the tutorial I found said that call/return was a better system, but reading the explanation didn’t help my comprehension at all. I need to see the code written out to get it, y’see. It sounds like “call” kind of exclusively seeks out other files to draw on. I’ll fiddle around with it more and see what I can learn from that tutorial.

1 Like

When using labels call will work just like jump, except that it keeps track of where it last was allowing for return to return (rather than closing the game.)

call can do other things too but I don’t want to overcomplicate this post.

Labels just mark places in your script(s). To a first approximation what file a label is in is irrelevant for either call or jump. Ren’Py reads all the files into memory during initialisation, and makes a list of all the labels it finds and where they are. The upshot is you can have as many script files as you wish, whatever works to help you quickly organise and find things.

The important thing is that encountering a new label doesn’t stop the script continuing. It will just keep going. Many new coders don’t grasp this immediately and it leads to “fall-through” accidents. You’ll see it all the time in bug reports for Ren’Py games here: “I selected abc, but after that played out it did xyz too.” This happens most often when using jump, as it means they’ve left out the jump at the end of that scene.

If you work with call and return, then return marks the end of a chunk of code. It helps to get into the habit of starting with a blank subroutine like this:

label hotdogScene:
    # TODO: Eat hotdogs

This will “work” if you call it (eg. call hotdogScene), even though it does nothing. The TODO comment is something your code editor will likely spot, and keep a list of so you know what you’ve still to do. You can’t do this with jump as it must have a valid label to jump to (and you might not know what that is yet - so you leave it out, and forget to fix it later).


What’s the best VScode extension/plugin for managing TODOs?

I only just this moment learned that the string TODO had any special meaning, despite having like 50 lines of comments about things on a list of things I’d like to get to in the future, I wasn’t actually using any particularly keyword for this comments… I now realize I should’ve been!

1 Like

I haven’t actually looked into this. I know Atom and VSC will highlight “TODO” and “FIXME” in comments by default like most code editors do. I tend to just use global search to find them when I need to.