Ren'Py Help with Menuset [SOLVED]

_13_

Active Member
Game Developer
Oct 8, 2020
802
2,714
Disclaimer: I only started learning any of this a couple of weeks ago and have never done any kind of programing prior to this.

I have many menus in my game and I'm fine making standard single choice menus and even having menu options dependent on previous decisions (flags). However, I wanted to make a menu where the player could choose multiple choices in the menu, so I found this type of code:
Code:
    default menuset = set()
    label morning_menu2:
        menu:
            set menuset
            "What should I do this morning?"

            "Go shower.":
                   "Text"
                   jump morning_menu2

            "Eat":

                   "Text"
                   jump morning_menu2
And that works. Great! However, now I want to do that but also give another multiple choice menu inside of that menu.

For example:
Code:
    default menuset = set()
    label morning_menu2:
        menu:
            set menuset
            "What should I do this morning?"

            "Go shower.":
                  "Text"
                  menu:
                    "How?"
                    "Soap":
                        "Text"
                    "Shampoo":
                        "Text"
                     
                   jump morning_menu2

            "Eat":

                   "Text"
                   jump morning_menu2
So that the player could choose which order to clean themselves, in this example. I've tried using "set menuset" again before the new menu, but that doesn't work. I tried numbering the menusets ("set menuset1" and "set menuset2"), including adding "default menuset1 = set()" and "default menuset2 = set()", but that didn't work. Is there a way to have a multi-choice menu within a multi-choice menu?

And to be honest, I've only tried using 1 multi-choice menu in the whole game. How will a second, non-related, menuset work? Do I do it the exact same way? Am I supposed to be naming each menuset differently?

Edit: I didn't copy and paste this from my code, please ignore the weird indents. My code usually looks much cleaner than that.
 
Last edited:

AnimeKing314

Giant Perv
Game Developer
Jun 28, 2018
395
605
Based on , it seems that each menuset should have it's own name or be cleaned up in between. I'm not quite sure what your error is or what you're trying to do though.

Edit:
Based on you're question (and using your example) I'm assuming you want when the player chooses shower for them to then choose if soap or shampoo happens first, then for them to select the other option afterwards and finally for it to jump back to the initial menu where they could then select to eat (or it just goes to the next scene if they chose to eat before going to the shower. In this case I would recommend having the menus separate instead of nested. So the final code would look something like this:
Python:
default menuset1 = []
default menuset2 = []

label first_menu:
    menu:
        set menuset1
        "What do you want to do?"
        "Shower":
            "Text"
            jump second_menu
        "Eat":
            "Text"
            jump first_menu
    jump next_scene

label second_menu:
    menu:
        set menuset2
        "What first?"
        "Shampoo":
            "Text"
            jump second_menu
        "Soap":
            "Text"
            jump second_menu
    jump first_menu
label next_scene:
 
Last edited:

_13_

Active Member
Game Developer
Oct 8, 2020
802
2,714
I keep trying to explain what I want, but every time it sounds like some kind of inception scenario.

I want a menu which asks the player to do 3 things (1, 2, 3). They choose the order. Choose 2, then return to the menu with choices 1 and 3, etc. However, option 3 also has a menu which asks the player to do 3 things (A, B, C). They choose the order. Choose B, then return to the menu with choices A and C, etc. Once A, B, and C are completed, they return to the first menu, if they haven't already selected both 1 and 2. After all choices have been selected, the game continues.

Does that make sense?
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,608
2,256
The problem I foresee is that you're jumping back to to the top level menu and set will store the choices as you make it.

Let's assume you have menuset1 and menuset2, as that seems to be where you are trying to get to.

So when you pick "Go shower." -> "Soap". "Go shower" is stored in menuset1 and "Soap" is stored in menuset2. Control is passed back to morning_menu2 and because of the values stored by the set, "Go shower" is now hidden and so you'll never be able to pick "Shampoo" (even though it is technically still available).

Edit: Sec... trying to make sense of your second post.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,608
2,256
Okay. Sounds like this is what you are aiming for...

Python:
label start:

    $ menuset1 = []
    menu morning_menu2:
        set menuset1
        "What should I do this morning?"

        "Go shower.":
            "Text"
            $ menuset2 = []
            menu morning_menu2a:
                set menuset2
                "How?"

                "Soap":
                    "Text"
                    jump morning_menu2a

                "Shampoo"
                    "Test"
                    jump morning_menu2a

            jump morning_menu2

        "Eat":
            "Text"
            jump morning_menu2

I'm introducing something new here, which you may not have already come across... the fact you can name a menu and use it as a label.

If your "Eat" menu has sub-options stored by set, those should probably be menuset3.

This is actually one of the few occasions I wouldn't recommend default. Since you SHOULD clear the array down right before you invoke the menu anyway. Not that it does any real harm, I guess.

Make sense?

Edit: Moved the initialization of menuset2. Makes it easier to have multiple layers of menusets within menusets. Doesn't solve your problem below, but is a better example for others in the future.
 
Last edited:
  • Like
Reactions: _13_

_13_

Active Member
Game Developer
Oct 8, 2020
802
2,714
Okay. Sounds like this is what you are aiming for...

//clip//


I'm introducing something new here, which you may not have already come across... the fact you can name a menu and use it as a label.

If your "Eat" menu has sub-options stored by set, those should probably be menuset3.

This is actually one of the few occasions I wouldn't recommend default. Since you SHOULD clear the array down right before you invoke the menu anyway. Not that it does any real harm, I guess.

Make sense?
I'll give it a try. That looks a little different than what I've tried. Of course, it only takes a small difference to work or not.
 

AnimeKing314

Giant Perv
Game Developer
Jun 28, 2018
395
605
Okay. Sounds like this is what you are aiming for...

Python:
label start:

    $ menuset1 = []
    $ menuset2 = []
    menu morning_menu2:
        set menuset1
        "What should I do this morning?"

        "Go shower.":
            "Text"
            menu morning_menu2a:
                set menuset2
                "How?"

                "Soap":
                    "Text"
                    jump morning_menu2a

                "Shampoo"
                    "Test"
                    jump morning_menu2a

            jump morning_menu2

        "Eat":
            "Text"
            jump morning_menu2

I'm introducing something new here, which you may not have already come across... the fact you can name a menu and use it as a label.

If your "Eat" menu has sub-options stored by set, those should probably be menuset3.

This is actually one of the few occasions I wouldn't recommend default. Since you SHOULD clear the array down right before you invoke the menu anyway. Not that it does any real harm, I guess.

Make sense?
Didn't know that you could name menus, this'll be very useful.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,608
2,256
Yeah, I can get rid of some label lines. Very helpful!

I do flip flop between them being a good idea or not.
In your example, it seemed to fit and made the code neater.

However, in general, I would normally code both a label and menu:. Primarily because it makes it easier to follow a jump my_label_23 if you can then search for "label my_label_23" without worrying if the label is a "real" label or a pseudo label created via menu:. I think my main objection though is that it's "clever" code, and clever code is rarely a good idea in any environment where multiple people might end up working on the code.
 
Last edited:

_13_

Active Member
Game Developer
Oct 8, 2020
802
2,714
So, now the game will start and run, but when I get to the first menu I'm getting:
You don't have permission to view the spoiler content. Log in or register now.

I tried the "$ menuset1 = []" and with "$ menuset1 = set()" but get the same error. So... here's the section of script in question, with some unnecessary parts removed.

You don't have permission to view the spoiler content. Log in or register now.

Some further first menu choices have been removed, but this is the portion that isn't working. The first menuset worked until I tried adding in the second and third.
 
Last edited:

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,608
2,256
So, now the game will start and run, but when I get to the first menu I'm getting:
<snip>

The only way I can imagine this happening is either trying to load a save file which is already in the middle of the menu choices. Or a typo.

Looking at the longer version of the code now...
 

_13_

Active Member
Game Developer
Oct 8, 2020
802
2,714
The only way I can imagine this happening is either trying to load a save file which is already in the middle of the menu choices. Or a typo.

Looking at the longer version of the code now...
I was using a save game, but the save is from before this portion of the script. It's actually saved on chapter 1 and this is on the chapter 2 script.

Edit: Just tried a new game and it gives the same error at that point.
 

_13_

Active Member
Game Developer
Oct 8, 2020
802
2,714
Based on , it seems that each menuset should have it's own name or be cleaned up in between. I'm not quite sure what your error is or what you're trying to do though.

Edit:
Based on you're question (and using your example) I'm assuming you want when the player chooses shower for them to then choose if soap or shampoo happens first, then for them to select the other option afterwards and finally for it to jump back to the initial menu where they could then select to eat (or it just goes to the next scene if they chose to eat before going to the shower. In this case I would recommend having the menus separate instead of nested. So the final code would look something like this:
Python:
default menuset1 = []
default menuset2 = []

label first_menu:
    menu:
        set menuset1
        "What do you want to do?"
        "Shower":
            "Text"
            jump second_menu
        "Eat":
            "Text"
            jump first_menu
    jump next_scene

label second_menu:
    menu:
        set menuset2
        "What first?"
        "Shampoo":
            "Text"
            jump second_menu
        "Soap":
            "Text"
            jump second_menu
    jump first_menu
label next_scene:
This might be the way to go, if I can't figure it out otherwise.
 

AnimeKing314

Giant Perv
Game Developer
Jun 28, 2018
395
605
This might be the way to go, if I can't figure it out otherwise.
Two things I can think of to try: delete persistent data and force recompile then try it, otherwise try defining the menusets using default instead of $.
 
  • Heart
Reactions: _13_

_13_

Active Member
Game Developer
Oct 8, 2020
802
2,714
Two things I can think of to try: delete persistent data and force recompile then try it, otherwise try defining the menusets using default instead of $.
Well shit... Going back to default worked. Thanks!
 

MrSilverLust

MSL Games
Game Developer
May 22, 2021
454
3,091
Just to let you know that I created a new project in renpy, copied your code from above and it worked as intended, no errors (of course only after defining mc, mt, b_points, set keep_key = True and not play the music camroom).

Your problem is where you are defining the menusets. Are they just before the menus? After the label start? In another .rpy file? Strange. Try moving them to somewhere else. Having a .rpy file with all variables defined is usually a good idea.

EDIT: glad you found a solution!
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,968
16,222
So, now the game will start and run, but when I get to the first menu I'm getting:
[...]
Code:
    $ menuset1 = set()
    $ menuset2 = set()
    $ menuset3 = set()

    menu morning_menu2:
[...]
Since it also don't works with a fresh new game, I guess that your code looks like this :
Code:
label whatever:
    [...]
    jump morning_menu2

[...]
    $ menuset1 = set()
    $ menuset2 = set()
    $ menuset3 = set()

    menu morning_menu2:
[...]
What imply that the variables are never created. Replace your $ menuset1 = set() by default menuset1 = set().
 

_13_

Active Member
Game Developer
Oct 8, 2020
802
2,714
79Flavors' code, using "default" instead of "$" worked... in case anyone else was interested.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,608
2,256
Not tested, but I think this is what you need...

You don't have permission to view the spoiler content. Log in or register now.

All I've really done is initialize the menuset right before each menu: rather then before the menu grouping. Try it... it'll work... or it won't.

Edit: I've just seen you've fixed it with default, and yeah... I can imagine that. Except as long as the $ menuset1 = [] type lines were immediately before the first menu: statement, it should have been fine. I only guess now that perhaps they were being set long before the menu: was invoked. Not that it really matters now... working is working. Little point "fixing" something that works. It'll still bug me for a while though.
 
Last edited:

AnimeKing314

Giant Perv
Game Developer
Jun 28, 2018
395
605
Not tested, but I think this is what you need...

You don't have permission to view the spoiler content. Log in or register now.

All I've really done is initialize the menuset right before each menu: rather then before the menu grouping. Try it... it'll work... or it won't.

Edit: I've just seen you've fixed it with default, and yeah... I can imagine that. Except as long as the $ menuset1 = [] type lines were immediately before the first menu: statement, it should have been fine. I only guess now that perhaps they were being set long before the menu: was invoked. Not that it really matters now... working is working. Little point "fixing" something that works. It'll still bug me for a while though.
It's most likely what anne said where he was probably jumping to the menu which skipped over the initialiazation statements.
 
  • Like
Reactions: 79flavors