Ren'Py [Solved] Problem with screens when jump to the label?

Midzay

Member
Game Developer
Oct 20, 2021
248
642
Friends, got stumped with my task, can you help?
I'm making a table of contents for a VN, like in a book. The reader can jump to any chapter or page of the book through the table of contents.
What I've done:
1/ with the Script file, I create a numbered label for each page.

Python:
label start:

# Page1
label сhapter_1:
    scene image_1
    author "text here{nw}"
    pers "text here"
    nvl clear

# Page2
label сhapter_2:
    scene image_2
    author "text here{nw}"
    pers "text here"
    nvl clear
    
    return
In the quick menu, I created an item called "Pages":

Python:
screen quick_menu():

    zorder 100

    if quick_menu:

        hbox:
            style_prefix "quick"
            textbutton _("Pages") action ShowMenu("pages")
# ets
In the screen "pages", I created buttons to jump to labels:

Python:
screen pages():
    use game_menu(_("Pages"), scroll="viewport"):
        vbox:
            textbutton "Chapter 1" action Jump("сhapter_1")
            textbutton "Chapter 2" action Jump("сhapter_2")
#etc
1737028168053.png

I was happy it was working until I saw that:
1/ the Quick menu disappeared
2/ The splitting text stopped working, now it fills the entire available height.

Untitled-1.jpg

This continues until I reach the Return command at the end of the script. Probably Jump is doing the transition in the Pages window and not in the window: screen nvl(dialogue, items=None): ...

Can you give me a direction for finding information on how to fix the table of contents of a book. I have not found a ready example of a table of contents.
 

moskyx

Forum Fanatic
Jun 17, 2019
4,392
14,757
Until the real experts show up, have you tried using Call instead of Jump?
 
  • Like
Reactions: Midzay

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,638
2,305
Quoting this post by PyTom:


Pytom said:
action Start() only works in the main menu, and action Jump() only works outside the main menu.
If you need code that works in both places, you can use:
Python:
    textbutton "Chapter 2": 
        if main_menu:
            action Start("chapter_2")
        else:
            action Jump("chapter_2")

For you I'm going to guess you might want something like:

Python:
screen pages():
    use game_menu(_("Pages"), scroll="viewport"):
        vbox:
            if main_menu:
                textbutton "Chapter 1" action Start("сhapter_1")
                textbutton "Chapter 2" action Start("сhapter_2")
            else:
                textbutton "Chapter 1" action Jump("сhapter_1")
                textbutton "Chapter 2" action Jump("сhapter_2")
 
Last edited:
  • Like
Reactions: anne O'nymous

Quintillian

Member
Apr 15, 2019
138
253
Quoting this post by PyTom:




Python:
    textbutton "Chapter 2":
        if main_menu:
            action Start("chapter_2")
        else:
            action Jump("chapter_2")

For you I'm going to guess you might want something like:

Python:
screen pages():
    use game_menu(_("Pages"), scroll="viewport"):
        vbox:
            if main_menu:
                textbutton "Chapter 1" action Start("сhapter_1")
                textbutton "Chapter 2" action Start("сhapter_2")
            else:
                textbutton "Chapter 1" action Jump("сhapter_1")
                textbutton "Chapter 2" action Jump("сhapter_2")
He is never in the main_menu though. He is always in the quick_menu.

Using ShowMenu outside of the main menu does a call_in_new_context underneat. My guess here, is that the quick menu is still shown but in the old Context. Any Jumps or Calls will execute in this Context until a Return, and then control goes back to where ShowMenu was called in the original Context.

To make a Jump and give control back to the parent Context at the same time, there exist , making the pages code, like this:

Python:
screen pages():
    use game_menu(_("Pages"), scroll="viewport"):
        vbox:
            textbutton "Chapter 1" action Function(renpy.jump_out_of_context, "chapter_1")
            textbutton "Chapter 2" action Function(renpy.jump_out_of_context, "chapter_2")
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
11,640
17,894
Using ShowMenu outside of the main menu does a call_in_new_context underneat. My guess here, is that the quick menu is still shown but in the old Context.
Your guess is almost correct. The quick menu is not shown in the old context, but hidden, with all other overlay, when entering the "main menu" context. And like by Jumping to the label he stay in that context, it and all possible overlay stay hidden.


To make a Jump and give control back to the parent Context at the same time, there exist [...]
Using Start() as 79Flavors said would works as well, since it's precisely what it does:
Python:
        def __call__(self):
            renpy.jump_out_of_context(self.label)
It also ensure that the code will be compatible with any future changes that would imply more cleaning when leaving the "main menu" context.



All this being said, did OP really need to open the screen in an actual "main menu" context?

Like the navigation bar do not have links to access the selection page, opening it as modal pop-up directly in the game context would do the same, without adding the complication due to the "main menu" context:

Python:
screen quick_menu():
[...]
        hbox:
            style_prefix "quick"
            textbutton _("Pages") action Show("pages")
[...]

screen pages():
    modal True

    # Fade the background
    add Solid( "#000000DD" ) size ( config.screen_width, config.screen_height )

    frame:
        # center
        xpos 0.5
        ypos 0.5

        has vbox

        textbutton "Chapter 1" action Jump("сhapter_1")
        textbutton "Chapter 2" action Jump("сhapter_2")
        [...]

        # A bit of separation
        null height 20

        textbutton "Cancel" action Hide()
 

Turning Tricks

Rendering Fantasies
Game Developer
Apr 9, 2022
1,610
3,018
Am I missing something here?

The OP made the chapter label blocks with returns, yet the code is using jump to get to them. Wouldn't that cause issues with return closing a call off the stack that is totally unrelated?
 

Midzay

Member
Game Developer
Oct 20, 2021
248
642
All this being said, did OP really need to open the screen in an actual "main menu" context?
You are right, there is no need to go into the menu to simplify.
Your script almost worked. After the first page selection under the overlay I see the correct (incomplete) text filling the page. Then I do Cancel to return to the page and the empty space is filled with text. Then the script stops working.
I'll check the other options the guys above suggested.

1737055696208.png

If the Table of Contents is done not through a window in the Menu but, as in a real book, on the first page of the novel, it should be easier? You can jump to the Table of Contents through a fixed button in the corner of the screen.
 

Quintillian

Member
Apr 15, 2019
138
253
Am I missing something here?

The OP made the chapter label blocks with returns, yet the code is using jump to get to them. Wouldn't that cause issues with return closing a call off the stack that is totally unrelated?
Nah. If the stack is empty, the return statement restarts Ren'Py, throwing you back into the main menu.
 

Midzay

Member
Game Developer
Oct 20, 2021
248
642
He is never in the main_menu though. He is always in the quick_menu.

Using ShowMenu outside of the main menu does a call_in_new_context underneat. My guess here, is that the quick menu is still shown but in the old Context. Any Jumps or Calls will execute in this Context until a Return, and then control goes back to where ShowMenu was called in the original Context.

To make a Jump and give control back to the parent Context at the same time, there exist , making the pages code, like this:

Python:
screen pages():
    use game_menu(_("Pages"), scroll="viewport"):
        vbox:
            textbutton "Chapter 1" action Function(renpy.jump_out_of_context, "chapter_1")
            textbutton "Chapter 2" action Function(renpy.jump_out_of_context, "chapter_2")
It's crashing the game.
ScriptError: could not find label 'chapter_2'. :oops:
 

Midzay

Member
Game Developer
Oct 20, 2021
248
642
Quoting this post by PyTom:




Python:
    textbutton "Chapter 2":
        if main_menu:
            action Start("chapter_2")
        else:
            action Jump("chapter_2")

For you I'm going to guess you might want something like:

Python:
screen pages():
    use game_menu(_("Pages"), scroll="viewport"):
        vbox:
            if main_menu:
                textbutton "Chapter 1" action Start("сhapter_1")
                textbutton "Chapter 2" action Start("сhapter_2")
            else:
                textbutton "Chapter 1" action Jump("сhapter_1")
                textbutton "Chapter 2" action Jump("сhapter_2")
Brother, it didn't change the behavior in any way.
 

Turning Tricks

Rendering Fantasies
Game Developer
Apr 9, 2022
1,610
3,018
Nah. If the stack is empty, the return statement restarts Ren'Py, throwing you back into the main menu.
That's what I meant though. They are jumping to a block that has no other exit except return, which either exits the main game loop or returns a call that might be on the stack.

Further, if the OP's code example is complete, the chapter_1 block has no exit at all, the game will show chapter_1 then go right to the chapter_2 block below, and that block has a return.

The way I would probably try and do this is make each page summary a special screen and then have a text button that just toggles that screen on and off. I'd avoid label blocks altogether.
 

Quintillian

Member
Apr 15, 2019
138
253
The way I would probably try and do this is make each page summary a special screen and then have a text button that just toggles that screen on and off. I'd avoid label blocks altogether.
That seems over-engineered to me. But just to confirm I understand you, are concerned OP may accidentally restart the game with return? If not, what is the error/failed state you're hoping to avoid?
 

Midzay

Member
Game Developer
Oct 20, 2021
248
642
You did remember to change Show('pages') back to ShowMenu('pages'), right? :unsure:
No, but I checked both. The answer's the same.

I'm sorry, but an uncaught exception occurred.

While loading <renpy.display.im.Image object ('gui/game_menu.jpg') at 0x0000000005b790a0>:
File "game/script.rpy", line 66, in script
neighbor "bla bla bla"
ScriptError: could not find label 'chapter_1'.
 

Midzay

Member
Game Developer
Oct 20, 2021
248
642
Guys, I'm going to try to go the other way, make the table of contents not in the menu screens but in a popup window.
 

Quintillian

Member
Apr 15, 2019
138
253
No, but I checked both. The answer's the same.
Ah, I see what you're saying. It seems there is some cursed formatting issue copy-pasting "chapter_1" and "chapter_2".

Even VSCode thinks there is something sus with those "c"s.
1737061865117.png

Luckily, deleting them and putting them back worked for me.

EDIT:
Can confirm, we had an impostor:
1737062284139.png
 
Last edited:

Midzay

Member
Game Developer
Oct 20, 2021
248
642
Ah, I see what you're saying. It seems there is some cursed formatting issue copy-pasting "chapter_1" and "chapter_2".

Even VSCode thinks there is something sus with those "c"s.
View attachment 4451811

Luckily, deleting them and putting them back worked for me.

EDIT:
Can confirm, we had an impostor:
View attachment 4451844
It's "С" in Cyrillic. Both letters on the same key. I'll check your code later.
 
  • Thinking Face
Reactions: Quintillian

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
11,640
17,894
That's what I meant though. They are jumping to a block that has no other exit except return, which either exits the main game loop or returns a call that might be on the stack.
Stack that is supposed to be empty because it didn't messed his call/return flow.


Further, if the OP's code example is complete, the chapter_1 block has no exit at all, the game will show chapter_1 then go right to the chapter_2 block below, and that block has a return.
What looks like the expected behavior:

You starts at whatever label/chapter you want, and Ren'Py will implicitly pass from one label/chapter to the next one, until it reach the end of the last label/chapter, that will send you back to the main menu.
 
  • Like
Reactions: Turning Tricks

Midzay

Member
Game Developer
Oct 20, 2021
248
642
Ah, I see what you're saying. It seems there is some cursed formatting issue copy-pasting "chapter_1" and "chapter_2".

Even VSCode thinks there is something sus with those "c"s.
View attachment 4451811

Luckily, deleting them and putting them back worked for me.

EDIT:
Can confirm, we had an impostor:
View attachment 4451844
File "renpy/common/00action_menu.rpy", line 199, in __call__
renpy.jump_out_of_context(self.label)
JumpOutException: сhapter_1

It's crashing the game. But I've made changes to the code, which I'll describe later today.