Ren'Py Button to call screen then return back

CrimsonAxisStudio

Member
Game Developer
Nov 7, 2017
271
1,585
Hey hey.

Trying to make a button I can place in the UI that allows time skipping but stays on the same label. Having an issue where the button is just returning to main menu.

Code:
label changetime:
    $ dt += 2
    if dt >= maxdt:
        $ dt = 1
        $ daytime = _("MORNING")
    return
This works fine when using "call changetime", but that is only when it's inside a different label.

Code:
label mcpool:
    $ hide_all1234()
    show screen m_menu
    scene mcbackyard
    show screen img_butn4("images/buttons/timeskip.png",(0,0),"changetime")
    call screen img_butn3("images/buttons/mchall_kit.png",(0,0),"mckitchen")
Clicking timeskip just returns to main menu.

And for reference, this is how the buttons are built in my screen file:

Code:
screen img_butn3(img_idle, posXY, jump_place):
    imagebutton:
        pos (posXY)
        focus_mask True
        idle img_idle
        hover If(action_area_lighting,true=(im.MatrixColor(img_idle,im.matrix.brightness(0.15))),false=img_idle)
        action [Hide("img_butn3",transition=dissolve), If(jump_place == None, Return(1), Jump(jump_place))]

Essentially, I need to create a button that is on most screens during navigation through the game world allows the player to skip time and change the dt variable +2, and stay on that label.

If I could put that button inside my m_menu screen, that would be great, but I would also be happy with something that needs to go into each label.

This is the last thing I need to fix before launching the next update to my game, so I would appreciate any help!

Thanks!

EDIT:

Also, I know it has something to do with the jump action in my button. I just don't know how to create a button that changes a variable and stays in the same label.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
Okay... it seems you're mixing a couple of things in there that aren't quite intended to work together.

There's two ways of putting a screen onto the UI.
  • call screen - intended to put the screen on to the UI and wait for a player action. Usually used with the modal screen option.
  • show screen - intended to put a screen onto the UI and leave it there. No other actions intended, without clicking something that's part of that screen. The game just leaves it there and carries on regardless.
call screen might be something like displaying a mobile phone or a stats screen.
show screen might be a stats bar permanently shown on screen or set of room navigation buttons... or an advance time button.

So you're using the right method, at least to invoke the button. But you're then following that up with an action that features a Return(1).

Return() can be used for a call screen and is usually used to pass a value back via the reserved _return variable.

Except... return is also used when you call a label too. Each time a game uses call, that line's reference number is added to what is sometimes called the "call stack". Each new call adds another line identifier onto the end of the stack. Then each time the code bumps into a return statement, the latest line identifier is pulled off the call stack and used to return to wherever the call was made. Written correctly, there is a matching return statement for every call statement.

It matters here, because the game's main menu uses call start to start the game. It's why the last statement of the game is return. It returns to the main menu, because the call stack is empty except that final call from the main menu... So when you use return in your show screen, it's doing what you asked... and returning to the main menu - because the call stack only has that one entry in it and you've shown the screen rather than called it.

Notably, you don't actually need to code a return for either a shown or called screen, since neither statement uses the call stack the way I described earlier. It gets a little confusing, because both commands use "call", but call and call screen are very different beasts. If anything, call screen is much more like jump than anything else, with the exception of the action(Return()).

It's difficult to see exactly what the solution is, without some other context... but I'm guessing it's going to be something like this...

Python:
screen img_butn3(img_idle, posXY,):
    imagebutton:
        pos (posXY)
        focus_mask True
        idle img_idle
        hover If(action_area_lighting,true=(im.MatrixColor(img_idle,im.matrix.brightness(0.15))),false=img_idle)
        action [Call "changetime"]

That said, I don't think that's going to be correct in and of itself. Just pressing a button and advancing the time might answer your immediate question, but invariably the game will need to do more than that. Perhaps advancing time will need to move the player back to their bedroom or some other central hub. Perhaps something new needs to happen if the time gets past midnight or 4am or something. In which case, maybe you'd need something more involved... perhaps...

Python:
        action [Call "changetime", If(dt == 1, Jump("a_new_day_begins"))]
or something similar.
 
Last edited:
  • Like
Reactions: anne O'nymous

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,192
For once, it's 79flavors that gave the solution, and me that will explain the effective problem ;)

The code is :
Python:
label changetime:
    [...]
    # Because of this, the label MUST be called and can ONLY be called.
    return

[...]
   # The screen is given a /jump_place/ value.
   show screen img_butn4("images/buttons/timeskip.png",(0,0),"changetime")
[...]

screen img_butn3(img_idle, posXY, jump_place):
[...]
        # /jump_place/ value is not /None/, so there will be a *jump*.
        action [Hide("img_butn3",transition=dissolve), If(jump_place == None, Return(1), Jump(jump_place))]
You're jumping to the changetime label, but the said label is wrote to be called. Therefore, when it reach the return statement that end it, Ren'py found an empy calling stack, and do what it's said to do in such case, it return to the main menu.
 
  • Like
Reactions: 79flavors