[Solved] Readback.rpy and "extend"

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.
Message
Author
Levrex
Veteran
Posts: 280
Joined: Mon Jun 18, 2012 12:16 pm
Contact:

Re: [Solved] Readback.rpy and "extend"

#16 Post by Levrex »

apricotorange wrote:You can then trigger the readback yourself with the action (SetVariable("readback_yvalue", 1.0), ShowMenu("text_history")); maybe put it on a screen which you show at the start of the game, then hide at certain key points.
Well, that's no option, really.
Will "not appending the overlay functions list" solve the problem? Or appending the same list with required keys (for yes/no) in init +2 block, for example?

And if i would like the readback module do not remember some parts of the script (not those of the main story, but Translation Notes), is it necessary to use another list to store the previous state and then override readback_buffer with that list?
Last edited by Levrex on Sun Jul 29, 2012 12:38 pm, edited 2 times in total.
If your question is solved, please add [Solved] to theme's name by editing its first post, so that the helpful guys out there wouldn't mistakenly think the problem is still unanswered and waste their time.

apricotorange
Veteran
Posts: 479
Joined: Tue Jun 05, 2012 2:01 am
Contact:

Re: [Solved] Readback.rpy and "extend"

#17 Post by apricotorange »

Well, that's no option, really.
Why? Something like the following should be roughly equivalent to the overlay:

Code: Select all

screen rollkeys:
    key rollback action (SetVariable("readback_yvalue", 1.0), ShowMenu("text_history"))
    key rollforward action ui.returns(None)

label start:
    show rollkeys

    #etcetc; you can hide it whenever necessary.
As for getting it to not remember what certain characters say, that's not too hard: just add a couple lines like the following just before the definition of ReadbackADVCharacter:

Code: Select all

    UntrackedADVCharacter = ADVCharacter
    UntrackedNVLCharacter = NVLCharacter
Then, use "define translation_note = UntrackedNVLCharacter(None)" to define a character whose lines don't show up in readback.

Levrex
Veteran
Posts: 280
Joined: Mon Jun 18, 2012 12:16 pm
Contact:

Re: [Solved] Readback.rpy and "extend"

#18 Post by Levrex »

apricotorange wrote:Why? Something like the following should be roughly equivalent to the overlay:
So it can work that way, huh? Pretty much a pleasant surprise.
I just added it to the nvl screen, and, from what i can see by reading two minutes of the prologue, it works nicely... Hope it'll stay so.

Code: Select all

screen nvl:

    key "rollback" action (SetVariable("readback_yvalue", 1.0), ShowMenu("text_history"))
    key "rollforward" action ui.returns(None)
As for getting it to not remember what certain characters say, that's not too hard: just add a couple lines like the following just before the definition of ReadbackADVCharacter:

Code: Select all

    UntrackedADVCharacter = ADVCharacter
    UntrackedNVLCharacter = NVLCharacter
Then, use "define translation_note = UntrackedNVLCharacter(None)" to define a character whose lines don't show up in readback.
Well, i just use the same character named "n" (plus special ones) for everything, and just have the screen at the end of an each day to jump to different labels in the script, but it should not be much of a trouble to make a new character and replace the old one with it, because notes are stored in the different file.

That screen looks like this, by the way. I'm still trying to figure how to make both text history work in the labels it jumps to and to return to proper screen with keeping the old (main story) context.
Maybe i should just replace the "Return" button action with "ShowMenu("day_completed", tips=onikakusi)". Day_result is stored outside of a screen, so there should be no trouble with jumping to the next day or TIPS or save/load screen. Maybe.

Code: Select all

screen translation_notes:
    tag menu
    
    key "game_menu" action NullAction()
    
    if filter(lambda x: x.isdigit(), day_result) <= "05":
        add "scenes/bg_041_zakat.jpg"
    elif filter(lambda x: x.isdigit(), day_result) <= "10":
        add "scenes/bg_246.jpg"
    elif filter(lambda x: x.isdigit(), day_result) <= "15":
        add "scenes/bg_001_zakat.jpg"

    frame:
        style_group "mm_root"
        
        vbox:
            xalign 0.05
            yalign 0.05
        
            textbutton _("###") activate_sound "sound/SE137.ogg" action [Hide("translation_notes", transition=fade), Jump("notes_higurashi")]
            ###

        text "{size=20}###\n{/size}" xalign 0.5 yalign 0.45
        
        vbox:
            xalign 0.2
            ypos 0.55
            
            if filter(lambda x: x.isdigit(), day_result) >= "02":
                textbutton _("###") action [Hide("translation_notes", transition=fade), Jump("notes_onik_day1")]
            # a dozen of same lines.

    textbutton _("Выйти") action Return() xalign 0.5 yalign 0.98

    on "show" action [Play("music", nageki_musicbox, loop=True, fadeout=1.0, if_changed=True), Play("ambient", None), SetVariable("unlock_prompt", True)]
    on "replace" action [Play("music", nageki_musicbox, loop=True, fadeout=1.0, if_changed=True), Play("ambient", None), SetVariable("unlock_prompt", True)]
    on "replaced" action SetVariable("unlock_prompt", False)
If your question is solved, please add [Solved] to theme's name by editing its first post, so that the helpful guys out there wouldn't mistakenly think the problem is still unanswered and waste their time.

apricotorange
Veteran
Posts: 479
Joined: Tue Jun 05, 2012 2:01 am
Contact:

Re: [Solved] Readback.rpy and "extend"

#19 Post by apricotorange »

I just added it to the nvl screen, and, from what i can see by reading two minutes of the prologue, it works nicely... Hope it'll stay so.
That should work, as long as you set "config.rollback_enabled = False".
I'm still trying to figure how to make both text history work in the labels it jumps to and to return to proper screen with keeping the old (main story) context.
Ah, hmm... if you want to juggle multiple contexts for readback, the only actual state you need to save/restore is the variable "readback_buffer". You can do something like the following:

Code: Select all

label translation_notes:
    main_story_readback_buffer = readback_buffer
    readback_buffer = []
    "blah blah blah"
    # etc
    readback_buffer = main_story_readback_buffer
    return
It might make more sense to show the translation notes as a screen, like you're saying, though. You can use a combination of SetScreenVariable and if statements to write a screen which displays completely different things as you interact with it.

Levrex
Veteran
Posts: 280
Joined: Mon Jun 18, 2012 12:16 pm
Contact:

Re: [Solved] Readback.rpy and "extend"

#20 Post by Levrex »

apricotorange wrote: Ah, hmm... if you want to juggle multiple contexts for readback, the only actual state you need to save/restore is the variable "readback_buffer".
No-no, i already figured all out, thanks to your advices and programming.
May i mention you in the credits for the game port... if i live long enough to complete it?

The only problem i still have (which is actually not that much of a problem) is:
While i'm at any of the TIPS or Notes labels, nor the readback, neither the text history (now it works, though, but do not hides the text on the screen), i don't even mention skipping, are working properly.

Changing "Jump" to "ui.jumpsoutofcontext" makes them work, but, well, the main context will be left behind and you'll return to the main menu instead of "day completed" screen. A vicious cycle, you would call this.

===
And, for readback, actually, after more testing, it seems that the previous state (config.readback_full = True) was better. It's not like you can run from the yes/no prompt anyway, so i guess i'll just call that a "feature".
If your question is solved, please add [Solved] to theme's name by editing its first post, so that the helpful guys out there wouldn't mistakenly think the problem is still unanswered and waste their time.

apricotorange
Veteran
Posts: 479
Joined: Tue Jun 05, 2012 2:01 am
Contact:

Re: [Solved] Readback.rpy and "extend"

#21 Post by apricotorange »

You probably want something like the following:

Code: Select all

screen translation_notes:
    vbox:
        textbutton "Translation notes day 1" action Jump("translation_notes_1")
        textbutton "Translation notes day 2" action Jump("translation_notes_2")
        textbutton "Done" action Return()

label day_completed:
    call screen translation_notes
    return

label translation_notes_1:
    "Here are my notes"
    jump day_completed

# Then, from the main script
    call day_completed
Your description sounds like you're trying to use ShowMenu or something like that to show your translation_notes screen, which has all sorts of weird effects which you don't want here.

Levrex
Veteran
Posts: 280
Joined: Mon Jun 18, 2012 12:16 pm
Contact:

Re: [Solved] Readback.rpy and "extend"

#22 Post by Levrex »

apricotorange wrote: Your description sounds like you're trying to use ShowMenu or something like that to show your translation_notes screen, which has all sorts of weird effects which you don't want here.
True it is. But if i don't use ShowMenu, then Return() button takes the player to the main menu... which is why i have to use ShowMenu. Yeah, it can be worked out by changing the action of the button... but i'd have to add the additional check variable, whether the player is going into the TIPS screen from the main menu or the game itself, so that the game decides where to return. I don't like to multiply variables, if that's unnecessary.

The very end of my labels looks like:

Code: Select all

call screen day_completed(tips="onikakusi")
, which is a screen with buttons, one of them changes its value throughout the Arc (the one which jumps to the next label in the script), and two of them take "tips" value to show the corresponding Notes and TIPS screens.

TIPS and Notes endings look the same, except they also have a "return" statement after each "call screen" statement. Just for an insurance.

Code: Select all

    call screen tips_onik
    return
If your question is solved, please add [Solved] to theme's name by editing its first post, so that the helpful guys out there wouldn't mistakenly think the problem is still unanswered and waste their time.

apricotorange
Veteran
Posts: 479
Joined: Tue Jun 05, 2012 2:01 am
Contact:

Re: [Solved] Readback.rpy and "extend"

#23 Post by apricotorange »

But if i don't use ShowMenu, then Return() button takes the player to the main menu... which is why i have to use ShowMenu
Return() only takes the player to the main menu if you're in the context of the main menu. Don't do that; use Start("day_completed_from_main_menu") to jump to the day completed screen.

Levrex
Veteran
Posts: 280
Joined: Mon Jun 18, 2012 12:16 pm
Contact:

Re: [Solved] Readback.rpy and "extend"

#24 Post by Levrex »

Context, you say? So, in other words, all i need is to remove the "menu" tag for my "day completed label jump-to" screens and assign the group of in-game screens an another?

Though, that possibly won't work, since i also have a "save" button in "day_completed" screen, which needs to have the "menu" tag... But it's better to ask anyway.
apricotorange wrote:Don't do that; use Start("day_completed_from_main_menu") to jump to the day completed screen.
Is "_from_main_menu" a special thing or i shall create another label to hold it?
If your question is solved, please add [Solved] to theme's name by editing its first post, so that the helpful guys out there wouldn't mistakenly think the problem is still unanswered and waste their time.

apricotorange
Veteran
Posts: 479
Joined: Tue Jun 05, 2012 2:01 am
Contact:

Re: [Solved] Readback.rpy and "extend"

#25 Post by apricotorange »

Is "_from_main_menu" a special thing
No, not special; you'll need to write your own label.
all i need is to remove the "menu" tag for my "day completed label jump-to" screens
The tag doesn't matter here; the "context" here is really an internal implementation detail which isn't really well-documented. The fundamental thing here is to avoid Jumping from the main menu, or any other screen shown using ShowMenu.
since i also have a "save" button in "day_completed" screen, which needs to have the "menu" tag
The "save" screen gets triggered with ShowMenu; that should show up the same way it would in any other part of the game which isn't part of the menus.

Levrex
Veteran
Posts: 280
Joined: Mon Jun 18, 2012 12:16 pm
Contact:

Re: [Solved] Readback.rpy and "extend"

#26 Post by Levrex »

The problem is almost resolved.

After a lot of brute-forcing i finally figured the way it works.
You were true about "ShowMenu", yeah.
It seems that the "Start" action will raise a "JumpOutException" if in a new label, so there is no other way, but to use "Show".
That way "Jump" works properly, with working readback and anything i would want.

This leads to the need to change the "day_completed" screen this way, though:

Code: Select all

        if tips == "onikakusi":
            hotspot (208, 96, 224, 48) activate_sound "sound/SE137.ogg" action [Show("tips_onik"), SetVariable("tips", "onikakusi")]
That ensures the "tips" variable replacement, so we don't get to return to the MainMenu after reading any TIPS. The in-game call will work totally as intended now.

But! If accessing TIPS from main menu, then it won't work as in called in-game. You have to have the game started with a Start label. However, you can not use Start for all TIPS because of mentioned above. After going through the first label, the next Start label will raise an error.

So we have no way but to use "Jump" for the TIPS labels, and call "Start" once. From the screen that divides TIPS into chapters (i.e. you select which chapter you want to view for TIPS).

Instead of Show("tips_onik", transition=fade), there should be Start("context_tips_onik").

Then i added the label to the TIPS file.

Code: Select all

label context_tips_onik:
    
    $ unlock_prompt = True
    $ tips = "mainmenu"
    # $ config.overlay_functions.remove(readback_catcher) # do not do this - look below.
    scene black # that's for not removing the readback function, so the background would not be transparent for any reason.
    call screen tips_onik
    return
So that way readback, while preserving its beautifulness, will not ruin my precious TIPS screen. It didn't quite work as planned, though...

The game then checks for tips value to return to the appropriate screens.

Code: Select all

    if tips == "mainmenu":
        jump context_tips_onik
    else:
        $ config.overlay_functions.append(readback_catcher)
        call screen tips_onik
    return
Also i changed the screen for TIPS:

Code: Select all

        if tips == "onikakusi":
            hotspot (245, 420, 150, 48) action Show("day_completed", tips="onikakusi", transition=fade)
        else:
            hotspot (245, 420, 150, 48) action MainMenu(confirm=False)
That way i still can use one screen instead of two for Chapter's TIPS.

Oh, and also i blocked keys associated with "rollback", "dismiss", "hide_windows", "game_menu" in TIPS screen, of course.

Then i had a crazy duel with a readback overlay and mainmenu TIPS button combined. I spent around 10 hours trying to figure out how to disable it for a certain screen. I thought of asking here, started writing, then, after turning computer off, suddenly realized that i've found a solution (StylePreference), It didn't work, though (because current Ren'Py actions don't work with lists), but, not giving up and thanks to SleepKirby's code for Touhou Mecha, i figured out (not familiar with python) how to remove and append list variables accordingly by creating another action in init code above the "-2 python", which is where the readback catcher function is appended.

Maybe somebody will find this function useful.
My Goddess... it actually holds a very big potential for interface (such as hiding/showing analog clock, buying an item with a screen, etc - of course, with some condition or a bit of a work for the latter), while not needing to restart the game. And it's a very big advantage.

Code: Select all

init python:
    
    class ToggleList:
        def __init__(self, list, lpos):
            self.list = list
            self.lpos = lpos
            
        def __call__(self):
            if self.lpos in self.list:
                self.list.remove(self.lpos)
            else:
                self.list.append(self.lpos)
                
            return self.list
Then i just had to add an Action to the each of «on»: "hide" "replace", "replaced", "show" statements of a TIPS screen.

Code: Select all

ToggleList(config.overlay_functions, readback_catcher)

Code: Select all

    on "show" action [Play("music", bgm_tips, loop=True, fadeout=1.0, if_changed=True), ToggleList(config.overlay_functions, readback_catcher), Play("ambient", None), SetVariable("unlock_prompt", True)]
    on "replace" action [Play("music", bgm_tips, loop=True, fadeout=1.0, if_changed=True), ToggleList(config.overlay_functions, readback_catcher), Play("ambient", None), SetVariable("unlock_prompt", True)]
    on "replaced" action [SetVariable("unlock_prompt", True), ToggleList(config.overlay_functions, readback_catcher)]
    on "hide" action [SetVariable("unlock_prompt", True), ToggleList(config.overlay_functions, readback_catcher)]
It works just perfectly in every case, and i didn't even need to use additional labels.


It's even possible to use it (with some modding) for actually CHANGING MUSIC IN-GAME.
The currently playing %channelname% needs to be changed, however, for this to take effect.
You'll need to define your music as a list (i.e. not define kowaii_saundo = "iwa.ogg", but define kowaii_saundo = ["iwa.ogg"]. Because the action works with lists only, after all.
It won't save after you re-launch the game, though, but that's easy - just store it in a persistent.variable_name and define kowaii_saundo as that name. That way it'll read the stored info after re-launching, and will still change list in-game. Like so:

Code: Select all

    if not persistent.kowaii_saundov:
        $ persistent.kowaii_saundov = ["iwa.ogg"]
    
    define kowaii_saundo = persistent.kowaii_saundov
Then add to the init python section (it's just a slightly changed ToggleList action, nothing special):

Code: Select all

        class RemoveList(Action):
            
            def __init__(self, list, lpos):
                self.list = list
                self.lpos = lpos
                
            def __call__(self):
                if self.lpos in self.list:
                    self.list.remove(self.lpos)
                    return self.list
                else:
                    return None
                
        class AppendList(Action):
            
            def __init__(self, list, lpos):
                self.list = list
                self.lpos = lpos
                
            def __call__(self):
                if self.lpos in self.list:
                    return None
                else:
                    self.list.append(self.lpos)
                    return self.list
Then just add something like this to the preference screen:

Code: Select all

            frame:
                style_group "pref"
                has vbox
                
                label _("Scary sound")
                textbutton _("1") action [RemoveList(kowaii_saundo, "iwa.ogg"), AppendList(kowaii_saundo, "jaki.ogg")]
                textbutton _("2") action [RemoveList(kowaii_saundo, "jaki.ogg"), AppendList(kowaii_saundo, "iwa.ogg")]
                textbutton _("full") action [AppendList(kowaii_saundo, "iwa.ogg"), AppendList(kowaii_saundo, "jaki.ogg")]
And it'll do. Remember, list is not a string, but strings can be used in a list.
The first button makes only one sound play, when "kowaii_saundo" is played;
the second one plays only another one;
the third button plays both.

Now you can change the music versions.

But whenever you choose any of these options, the game, for some reason, starts running. If you don't have a start label, then you'll get an error.

Why the hell it does so, and how to fix such a behavior?

Traceback:
I'm sorry, but an uncaught exception occurred.

While running game code:
ScriptError: could not find label 'start'.

-- Full Traceback ------------------------------------------------------------

Full traceback:
File "E:\Call of Pripyat\gamedata\Matsuri\bgitools\RenPy\Test\renpy\execution.py", line 265, in run
File "E:\Call of Pripyat\gamedata\Matsuri\bgitools\RenPy\Test\renpy\ast.py", line 1267, in execute
File "E:\Call of Pripyat\gamedata\Matsuri\bgitools\RenPy\Test\renpy\script.py", line 485, in lookup
ScriptError: could not find label 'start'.

Windows-XP-5.1.2600-SP2
Ren'Py 6.13.12.1728
A Ren'Py Game 0.0
If your question is solved, please add [Solved] to theme's name by editing its first post, so that the helpful guys out there wouldn't mistakenly think the problem is still unanswered and waste their time.

apricotorange
Veteran
Posts: 479
Joined: Tue Jun 05, 2012 2:01 am
Contact:

Re: [Solved] Readback.rpy and "extend"

#27 Post by apricotorange »

If you have an action which returns a value other than None, it will end the current interaction; in the main menu, that's equivalent to starting the game.

Levrex
Veteran
Posts: 280
Joined: Mon Jun 18, 2012 12:16 pm
Contact:

Re: [Solved] Readback.rpy and "extend"

#28 Post by Levrex »

So if i instead do it as a function, it will behave properly?
If your question is solved, please add [Solved] to theme's name by editing its first post, so that the helpful guys out there wouldn't mistakenly think the problem is still unanswered and waste their time.

apricotorange
Veteran
Posts: 479
Joined: Tue Jun 05, 2012 2:01 am
Contact:

Re: [Solved] Readback.rpy and "extend"

#29 Post by apricotorange »

The issue is that the __call__ member of your AppendList/RemoveList has the line "return self.list"; it should be "return None".

Levrex
Veteran
Posts: 280
Joined: Mon Jun 18, 2012 12:16 pm
Contact:

Re: [Solved] Readback.rpy and "extend"

#30 Post by Levrex »

Ah, thanks!
Now it works all fine.
If your question is solved, please add [Solved] to theme's name by editing its first post, so that the helpful guys out there wouldn't mistakenly think the problem is still unanswered and waste their time.

Post Reply

Who is online

Users browsing this forum: No registered users