Having trouble coding second menu screen

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
ButterflyLatte
Regular
Posts: 40
Joined: Fri Mar 18, 2016 3:43 am
Completed: LoveSick, Oceanic Hearts, warm
Projects: Wendy, Alice Is Still Here
Organization: Krispy Cat
Tumblr: butterfly-latte
Deviantart: ButterflyLatte
itch: krispycat
Location: USA
Contact:

Having trouble coding second menu screen

#1 Post by ButterflyLatte » Thu Jul 13, 2017 2:08 pm

I'm trying to code my game so that, when you get all the endings, the main menu screen changes. I've followed the instructions on persistent data and changing screens to the best of my knowledge, but something is still going wrong.

When I click Launch Project, this pops up instead of the menu.

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/screens.rpy", line 355, in prepare_screen
    screen main_menu():
  File "game/screens.rpy", line 355, in prepare
    screen main_menu():
  File "game/screens.rpy", line 360, in prepare
    if persistent.ending == [b][endings cut for spoilers][/b]:
  File "game/screens.rpy", line 360, in prepare
    if persistent.ending == [b][endings cut for spoilers][/b]:
And it claims that 'main_menu_2' does not exist.

My screens editra looks like this:

Code: Select all

screen main_menu():

    # This ensures that any other menu screen is replaced.
    tag menu

    if persistent.ending == [b][cut for spoilers][/b]:
        use main_menu_2
    else:
        use main_menu

    add gui.main_menu_background
    add gui.main_menu_2
And yes, I have named the other menu "main_menu_2" in the GUI folder.

Where am I going wrong here?
Current Project:
Image

User avatar
Milkymalk
Miko-Class Veteran
Posts: 752
Joined: Wed Nov 23, 2011 5:30 pm
Completed: Don't Look (AGS game)
Projects: KANPEKI! ★Perfect Play★
Organization: Crappy White Wings
Location: Germany
Contact:

Re: Having trouble coding second menu screen

#2 Post by Milkymalk » Thu Jul 13, 2017 2:13 pm

Does persistent.ending already exist? If you try to compare it before actually setting it, you get an error.

I'm assuming "[endings cut for spoilers]" is not what's in your code. Please try to avoid something like that and instead change the word to something unspoilery.
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: Having trouble coding second menu screen

#3 Post by Scribbles » Thu Jul 13, 2017 2:16 pm

I believe the problem is you're telling it to use and it's trying to use a menu not an image

instead of use main_menu try:

add #your image file here

in your if statement.

I'm sorry I know I'm explaining it badly, but "use" isn't used for adding images, it would only work if you had a second screen named main_menu_2
Image - Image -Image

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Having trouble coding second menu screen

#4 Post by Remix » Thu Jul 13, 2017 2:54 pm

On an aside... and this will not likely fix the missing screen...

use likely evaluates the screen from the start, so when you have the else you are effectively saying
else: use self and run the test again, else: use self and ... you get the gist?

It would be better (and more logically readable) to just indent the items after else:

Code: Select all

screen main_menu():

    # This ensures that any other menu screen is replaced.
    tag menu

    if persistent.ending == "something":
        use main_menu_2() # <-- maybe try adding the parenthesis if main_menu2 definition has them
    else:
        add gui.main_menu_background
        add gui.main_menu_2
        # and the rest indented to this level
Frameworks & Scriptlets:

User avatar
ButterflyLatte
Regular
Posts: 40
Joined: Fri Mar 18, 2016 3:43 am
Completed: LoveSick, Oceanic Hearts, warm
Projects: Wendy, Alice Is Still Here
Organization: Krispy Cat
Tumblr: butterfly-latte
Deviantart: ButterflyLatte
itch: krispycat
Location: USA
Contact:

Re: Having trouble coding second menu screen

#5 Post by ButterflyLatte » Thu Jul 13, 2017 6:10 pm

If it helps, I have a bunch of endings and am trying to change the menu screen if you get all of them. So my code looks something like

Code: Select all

screen main_menu():

    # This ensures that any other menu screen is replaced.
    tag menu

    if persistent.ending == "End1" and "End2" and "End3":
        use main_menu_2("main_menu_2.png")
    else:
        add gui.main_menu_background
        add gui.main_menu_2
As for the persistent data endings, the choices that lead to an ending look like this.

Code: Select all

    menu:
        "A choice.":
            $ persistent.ending = "End1"
            $ end1 = True
            $ renpy.block_rollback()
            jump endingone
Current Project:
Image

User avatar
Milkymalk
Miko-Class Veteran
Posts: 752
Joined: Wed Nov 23, 2011 5:30 pm
Completed: Don't Look (AGS game)
Projects: KANPEKI! ★Perfect Play★
Organization: Crappy White Wings
Location: Germany
Contact:

Re: Having trouble coding second menu screen

#6 Post by Milkymalk » Thu Jul 13, 2017 6:50 pm

if persistent.ending == "End1" and "End2" and "End3":
This is NOT how if-clauses work.

persistent.ending has one value and one value only. What this line does is:
If persistent.ending is "End1", and the string "End2" is not empty, and the string "End3" is not empty, do this:
You want persistent.ending to be a set. First, get this line in an init block:

Code: Select all

if persistent.endings is None:
    $ persistent.endings = set()
Whenever an ending is achieved, do

Code: Select all

$ persistent.endings.add('End1')
You check with:

Code: Select all

if 'End1' in persistent.endings:
For several endings either:

Code: Select all

if 'End1' in persistent.endings and 'End2' in persistent.endings:
or:

Code: Select all

if set('End1', 'End2').issubset(persistent.endings):
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

User avatar
ButterflyLatte
Regular
Posts: 40
Joined: Fri Mar 18, 2016 3:43 am
Completed: LoveSick, Oceanic Hearts, warm
Projects: Wendy, Alice Is Still Here
Organization: Krispy Cat
Tumblr: butterfly-latte
Deviantart: ButterflyLatte
itch: krispycat
Location: USA
Contact:

Re: Having trouble coding second menu screen

#7 Post by ButterflyLatte » Thu Jul 13, 2017 7:07 pm

Ahhhh, okay. I'll give that a try.

(I'm terrible at coding and some of the instructions I find can be a bit hazy, my apologies.)
Current Project:
Image

User avatar
Milkymalk
Miko-Class Veteran
Posts: 752
Joined: Wed Nov 23, 2011 5:30 pm
Completed: Don't Look (AGS game)
Projects: KANPEKI! ★Perfect Play★
Organization: Crappy White Wings
Location: Germany
Contact:

Re: Having trouble coding second menu screen

#8 Post by Milkymalk » Thu Jul 13, 2017 7:13 pm

If you never coded before you need to take some time grasping basic concepts like logic ("if ... and ... or ..." and such stuff) and data storage in Python (lists, tuples, dictionaries, sets; in this order of importance). If you have that internalized and want to level up your coding skills, read about Python classes and functions.

Good luck!
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3636
Joined: Mon Dec 14, 2015 5:05 am
Location: Your monitor
Contact:

Re: Having trouble coding second menu screen

#9 Post by Imperf3kt » Thu Jul 13, 2017 7:45 pm

Would it not be simpler to use a single screen and modify that instead?
I'd just use a counter and set a route_#_complete flag.
Eg:

Code: Select all

screen main_menu:
    if route_clear = 3:
        #my main_menu_2 content
    else:
        #my main_menu content

Code: Select all

default persistent.routes_clear = 0
default persistent.route_1 = False
default persistent.route_2 = False
default persistent.route_3 = False

label start:
    "Once upon a time..."
    # and so on

label route_1:
    "And they all lived happily ever after."
    "The End"
    if not persistent.route_1:
        $ persistent.route_1 == True
        $ persistent.route_clear += 1
    return

label route_2:
    "And they all died."
    "The End"
    if not persistent.route_2:
        $ persistent.route_2 == True
        $ persistent.route_clear += 1
    return

label route_3:
    "And they all grew wings and flew away."
    "The End"
    if not persistent.route_3:
        $ persistent.route_3 == True
        $ persistent.route_clear += 1
    return
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor
Free Android GUI - Updated occasionally
Twitter
Imperf3kt Blackjack - a WIP blackjack game for Android made using Ren'Py

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Having trouble coding second menu screen

#10 Post by Remix » Fri Jul 14, 2017 3:15 pm

Some quick observations...

persistent.anything uses Revertable versions of List, Set and Dict, so list.add() would not work. (in my brief tests even the AddToSet button action does not work for lists within persistent data)
with using persistent we cannot store un-pickle-able objects, so would likely store ints or strings which means there are aspects of looping them that would not be too friendly in screens.rpy

give me a while and I will try to run up some brief demo code to illustrate what we would need if looping within screens...
just popping out first...
Frameworks & Scriptlets:

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Having trouble coding second menu screen

#11 Post by Remix » Fri Jul 14, 2017 4:37 pm

If you ran this...

it should run fine in a new project by just replacing all of script.rpy with it
just find 6 backgrounds and name them 'bg 0.png' (default) to 'bg 4.png' and 'bg 99.png' (bonus)

As paths unlock, the buttons to choose layout become active.
Once all paths are clear, the bonus becomes available

Anyway...

Code: Select all

default persistent.endings_found = [0] # 0 is our default screen
default possible_endings = range(0, 5) ## start, end minus one - so 1,5 would be 4 endings plus a zero 0 for our default
default persistent.displayed_ending = 0

# then screen menu code along the lines of

screen test_screen():
    tag menu

    frame:
        area (0.0, 0.0, 1.0, 1.0)
        background renpy.display.im.Image( "images/bg {0}.png".format(persistent.displayed_ending) )
        vbox:
            # Some info
            text "Showing 'images/bg {0}.png' as background".format(persistent.displayed_ending) xalign 0.5
            text "Found {0} from {1} and displaying {2}".format(persistent.endings_found,
                                                                possible_endings,
                                                                persistent.displayed_ending).replace("[","[[")
    # add the select view buttons
    #
    use buttons_for_menu_choice

    # I think if you wanted to do "use sub_menu_variant_x" you might need
    # to just test if, elif, else on persistent.displayed_ending and hardcode the "use .... " lines

screen buttons_for_menu_choice():
    # some buttons (on the right side) to choose a display to use
    vbox:
        area (0.8, 0.3, 0.2, 0.4)
        for k in possible_endings:
            add renpy.display.behavior.TextButton( "{0}".format("Ending {0}".format(k) if k else "Default Ending"), 
                                                   action=[SetField(persistent, 'displayed_ending', k),
                                                           SelectedIf(k == persistent.displayed_ending),
                                                           SensitiveIf(k in persistent.endings_found)]
                                                 )
        add renpy.display.behavior.TextButton( "Bonus Ending", 
                                               action=[SetField(persistent, 'displayed_ending', 99),
                                                       SelectedIf(99 == persistent.displayed_ending),
                                                       SensitiveIf( len(persistent.endings_found) >= len(possible_endings) )]
                                             )


define e = Character("") # hmmm

label start:
    # just showing the screen here to test
    show screen test_screen
    "First Line"
    # using buttons to test behaviour
    menu:
        "Choose an option"
        "A choice.":
            python:
                ending_number = 1 # change number per ending
                #
                # we have to use test then append as persistence uses revertable list
                # which has no .add method.
                # Even AddToSet action seems to fail, just more silently
                if ending_number not in persistent.endings_found:
                    persistent.endings_found.append( ending_number ) 
                # using the SetField action here is a no go, so
                persistent.displayed_ending = ending_number
                # also changed so that the menu shows this route next show
                #
                renpy.block_rollback()
            jump choose_again
        "B choice.":
            python:
                ending_number = 2 # change number per ending
                if ending_number not in persistent.endings_found:
                    persistent.endings_found.append( ending_number ) 
                persistent.displayed_ending = ending_number
                renpy.block_rollback()
            jump choose_again
        "C choice.":
            python:
                ending_number = 3 # change number per ending
                if ending_number not in persistent.endings_found:
                    persistent.endings_found.append( ending_number ) 
                persistent.displayed_ending = ending_number
                renpy.block_rollback()
            jump choose_again
        "D choice.":
            python:
                ending_number = 4 # change number per ending
                if ending_number not in persistent.endings_found:
                    persistent.endings_found.append( ending_number ) 
                persistent.displayed_ending = ending_number
                renpy.block_rollback()
            jump choose_again
    "Last Line"
    return

label choose_again:
    jump start
    return
Inline comments added to hopefully make it clearer
Frameworks & Scriptlets:

Post Reply

Who is online

Users browsing this forum: Alex, nyeowmi