[SOLVED] Weird "on replace/replaced" behaviour (was: screen tags and on show/on hide transforms)

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
Milkymalk
Miko-Class Veteran
Posts: 753
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:

[SOLVED] Weird "on replace/replaced" behaviour (was: screen tags and on show/on hide transforms)

#1 Post by Milkymalk »

I set up a screen that can show various other screens. There's a button for each possible screen to be shown and these screens should slide in from the bottom, and when hidden again, slide back down. It works, but only until I give them a common tag:

Code: Select all

screen base:
    add Color('#000')
    textbutton "Info":
        pos (1050, 50)
        text_color '#fff'
        action Show('infoscreen')

    textbutton "Trade":
        pos (1050, 130)
        text_color '#fff'
        action Show('tradescreen')

transform screenslide:   
    on show:
        yanchor 0
        ypos 1.0
        easeout 0.5 ypos 0.0        
    on hide:
        easeout 0.5 ypos 1.0
        
screen infoscreen:
    tag hubscreen
    fixed:
        at screenslide
        add "images/screens/infoscreen.png" xalign 0 yalign 0
        textbutton "Close":
            pos (800, 150)
            text_color '#fff'
            action Hide('infoscreen')
        
screen tradescreen:
    tag hubscreen
    fixed:
        at screenslide
        add "images/screens/tradescreen.png" xalign 0 yalign 0
        textbutton "Close":
            pos (800, 150)
            text_color '#fff'
            action Hide('tradescreen')
Without the tag, they slide in and out as they should. With the tag, they instantly replace the former screen without any movement. I'm assuming this happens because the screen is already in place and is just swapped with the other screen of its tag.

Is there a way I can force them to use the transform? Also, how can I delay the appearance of the new screen until the old one has disappeared? I know I can just work a delay into the transform, but I only want to delay it if another screen actually has to be hidden first.
Last edited by Milkymalk on Wed Mar 28, 2018 12:03 pm, edited 3 times in total.
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

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: screen tags and on show/on hide transforms

#2 Post by Remix »

Have you tried
on show, replace:
on hide, replaced: # with a 'd'
?

https://www.renpy.org/dev-doc/html/atl. ... nal-events
Frameworks & Scriptlets:

User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
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: screen tags and on show/on hide transforms

#3 Post by Milkymalk »

I wasn't aware these events even exist, thank you!
It only solves part of the problem, because trying to activate an already shown screen replaces it with itself, leading to it sliding down AND appearing. Also, after a screen has replaced another and been replaced, it only instantly appears again when activated. This resets when I manually close a screen.

The code at this moment:

Code: Select all

screen base:
    add Color('#000')
    textbutton "Info":
        pos (1050, 50)
        text_color '#fff'
        action Show('infoscreen')

    textbutton "Trade":
        pos (1050, 80)
        text_color '#fff'
        action Show('tradescreen')

transform screenslide:  
    on show:
        yanchor 0
        ypos 1.0
        easeout 0.3 ypos 0.0        
    on replace:
        yanchor 0
        ypos 1.0
        pause 0.2
        easeout 0.3 ypos 0.0        
    on hide, replaced:
        easeout 0.3 ypos 1.0
        
screen infoscreen:
    tag hubscreen
    fixed:
        at screenslide
        add "images/screens/infoscreen.png" xalign 0 yalign 0
        textbutton "Close":
            pos (800, 150)
            text_color '#fff'
            action Hide('infoscreen')
        
screen tradescreen:
    tag hubscreen
    fixed:
        at screenslide
        add "images/screens/tradescreen.png" xalign 0 yalign 0
        textbutton "Close":
            pos (800, 150)
            text_color '#fff'
            action Hide('tradescreen')
EDIT: Testing shows that the error occurs once a screen has replaced another and is later replacing a screen again: It just pops up below the screen being replaced, instead of sliding up. This is independent from replacing itself or not.
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
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: screen tags and on show/on hide transforms

#4 Post by Milkymalk »

I'm pushing this after 10 days now because I still haven't found a solution. Anyone?
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

DannX
Regular
Posts: 99
Joined: Mon Mar 12, 2018 11:15 am
Contact:

Re: screen tags and on show/on hide transforms

#5 Post by DannX »

I've been testing this for while. The only thing that has worked for me has been to make each button check if each screen is showing and program it to hide myself using If screen action.

Code: Select all

    textbutton "Info":
        pos (1050, 50)
        text_color '#fff'
        action [If(not renpy.get_screen('infoscreen'), Show('infoscreen')),
                If(renpy.get_screen('tradescreen'), Hide('tradescreen'))]
                
    textbutton "Trade":
        pos (1050, 80)
        text_color '#fff'
        action [If(not renpy.get_screen('tradescreen'), Show('tradescreen')),
                If(renpy.get_screen('infoscreen'), Hide('infoscreen'))]
I don't know if this is the behaviour you want, and I had to remove the tags but at least it seems like the screens replace each other properly and clicking the same button doesn't make the screen appear again.
Last edited by DannX on Mon Mar 19, 2018 3:24 pm, edited 1 time in total.

User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
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: screen tags and on show/on hide transforms

#6 Post by Milkymalk »

Thank you for taking the time to fiddle around with this problem!

I thought of this workaround too, but these two won't stay the only screens in this system (with this tag) and it's not very elegant. So as it stands I have to assume that replace/replaced is bugged in the current built and I have to manually check every single screen for each button.

I also don't know how to give the replacing screen a little delay with this method, but I will look into it.
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

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: Weird "on replace/replaced" behaviour (was: screen tags and on show/on hide transforms)

#7 Post by Remix »

Finally got this vaguely working using an ATL function and a mid move display swap...

Got work in 6hrs or so so will leave it with you to tinker around with:

Code: Select all

### Tweak 'warper', 'duration' (note 'last_st' should be bigger and negative), 'ypos' as wanted

default panel_info = {
    'showing' : None,
    'pending' : None,
    'last_st' : -5.0,
    'warper' : {'in':'easein_bounce', 'out':'easeout_back'},
    'duration' : 3.0,
    'ypos' : [600, 150]
}

init python:

    def panel_slider(trans, st, at):

        global panel_info

        if not panel_info['last_st']:
            panel_info['last_st'] = st

        # default closed
        ypos = panel_info['ypos'][0]

        if panel_info['last_st'] + panel_info['duration'] >= st:
            # we should be moving
            if not panel_info['showing']:
                panel_info['showing'] = panel_info['pending']

                #### Here we want to force redraw/refresh the info_panel screen

                renpy.restart_interaction()

            yrange = panel_info['ypos'][1] - panel_info['ypos'][0]
            portion = float(st - panel_info['last_st']) / panel_info['duration']

            if panel_info['pending'] == panel_info['showing']:
                # showing
                warp_portion = renpy.atl.warpers[ panel_info['warper']['in'] ]( portion )
                ypos += yrange * warp_portion
            else:
                # hiding
                warp_portion = renpy.atl.warpers[ panel_info['warper']['out'] ]( portion )
                ypos = panel_info['ypos'][1] - yrange * warp_portion

        else:
            # we are either open or closed
            if not panel_info['pending'] and not panel_info['showing']:
                # closed with no pending action
                pass
            elif panel_info['pending'] != panel_info['showing']:
                # fully closed
                panel_info['showing'] = panel_info['pending']
                if panel_info['showing']:
                    # swapped to new

                    panel_info['last_st'] = st
                
                #### Here we want to force redraw/refresh the info_panel screen etc

                renpy.restart_interaction()
            else:
                # fully open
                ypos = panel_info['ypos'][1]

        panel_info['cur_ypos'] = int(ypos)
        panel_info['cur_st'] = st
        trans.ypos = int(ypos) 
        return 0.04


transform panel_slide:
    function panel_slider

screen panel_control():
    default panels = [ 'info', 'trade' ]
    fixed:
        # x,y,w,h
        area (0.635, 0.1, 0.365, 0.6)
        vbox:
            for panel in panels:
                textbutton "{0}".format("Close" if panel_info['showing'] == panel else panel.capitalize()):
                    action [
                        SetDict(panel_info, 'last_st', None),
                        SetDict(panel_info, 'pending', None if panel_info['showing'] == panel else panel)
                    ]


screen info_panel():
    fixed at panel_slide:
        area (400,600, 200, 450)
        if panel_info['showing'] == 'info':
            # use infoscreen
            add Color('#770')
            text "Info"
        elif panel_info['showing'] == 'trade':
            # use tradescreen
            add Color('#077')
            text "Trade"
        else:
            add Color('#777')
            text "Hidden"

screen debug():
    vbox:
        text "\n\nDEBUG"
        for k in panel_info:
            $ v = str(panel_info[k]).replace('[','[[').replace('{','{{')
            text "[k] = [v]"

init python:
    config.overlay_screens.append('panel_control')
    config.overlay_screens.append('info_panel')

    config.overlay_screens.append('debug')
    config.per_frame_screens.append('debug')

    # config.per_frame_screens.append('panel_control')
    # config.per_frame_screens.append('info_panel')


label start:
    "Start"

    "End"

    return
If you want a Close All type button, use: action [ SetDict(panel_info, 'last_st', None), SetDict(panel_info, 'pending', None) ]
I left the debug panel/screen bit in just for extra info...
Realistically it might be best to tweak the 'return 0.04' so it runs fast while moving then slows while inactive...

Note: I used pixel positions... If you alter panel_info['ypos'] to use floats, also amend the " trans.ypos = int(ypos) " at the end. It should still work with floats.

Should be online late tomorrow if needed
Frameworks & Scriptlets:

User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
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: Weird "on replace/replaced" behaviour (was: screen tags and on show/on hide transforms)

#8 Post by Milkymalk »

Remix wrote: Mon Mar 19, 2018 8:02 pm Finally got this vaguely working using an ATL function and a mid move display swap...

Got work in 6hrs or so so will leave it with you to tinker around with:
You are either insane or you really like to test yourself with near-impossible ATL problems ... thank you :) This isn't the first time you do this for me either.

This is crazy ... all this just to work around a bug in screen tag behaviour? :|
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

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: Weird "on replace/replaced" behaviour (was: screen tags and on show/on hide transforms)

#9 Post by Remix »

Milkymalk wrote: Thu Mar 22, 2018 7:07 pm You are either insane or you really like to test yourself with near-impossible ATL problems ...
I wanted something along these lines for the game I am working on so figured the answer was a good learning experience.
... wrote: This is crazy ... all this just to work around a bug in screen tag behaviour? :|
Not really a bug as such. It basically bubbles down to Ren'py not wanting to guess when an event has multiple actions... does it always wait until a Hide transform finishes before starting a Show, is that only if the screen is the same, does that include tags, if different screens should there be a toggle-able trigger... etc etc ?

In my view it would be nicer (for advanced systems) to have something like:

action [ [ActionA(), ActionB()], ActionC(), [ActionD(), ActionE()] ]

wherein ActionA and B are called without waiting, ActionC is only called when A and B are both finished, D and E run after C finishes.
Then we could have action [Hide('j'), Show('k')] to wait for j to hide before showing k or action [ [Hide('j'), Show('k')] ] to start both at same time.
It would complexify the system though, maybe need inverting (for legacy code) and likely not be easy to integrate anyway.
Plus there are always workarounds anyway ;)
Frameworks & Scriptlets:

User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
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: Weird "on replace/replaced" behaviour (was: screen tags and on show/on hide transforms)

#10 Post by Milkymalk »

I still think it's a bug because replacing with a screen that already triggered its replace event in the current tag batch reacts differently than with a screen that hasn't already replaced another screen at least once. To put it in simpler words: It's not a matter of replace or show, but whether it's the first replace for the screen or not (and then doesn't even trigger any event at all). That's inconsistent and should be considered a bug :(
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

User avatar
Milkymalk
Miko-Class Veteran
Posts: 753
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: Weird "on replace/replaced" behaviour (was: screen tags and on show/on hide transforms)

#11 Post by Milkymalk »

The newest version solves this bug. Screens still use their transforms if they replace themselves (which is okay), but the inconsistent event triggering has been fixed!
Crappy White Wings (currently quite inactive)
Working on: KANPEKI!
(On Hold: New Eden, Imperial Sea, Pure Light)

Post Reply

Who is online

Users browsing this forum: No registered users