Ren'Py Scene Gallery and Replay help

Nov 14, 2020
20
4
Hi could someone tell why this code below isn't working? I wanted to do a scene gallery with replays of scene from the game, but I'm stuck on the unlocked image no matter what I do, it doesn't show the scene. Can someone tell me what to do to 1) unlock the scene 2) replay it?

Code:
init python:
    galleryItems = []

    class GalleryItem:
        def __init__(self, char, label, lockedImage, unlockedImage, unlockedText, scope=None):
            self.char = char
            self.label = label
            self.lockedImage = lockedImage
            self.unlockedImage = unlockedImage
            self.unlockedText = unlockedText

            if scope is None: self.scope = {}
            else: self.scope = scope

            galleryItems.append(self)

    def updateScope(newScope):
        rv = scopeDict.copy()
        rv.update(newScope)
        return rv

    ## GALLERY ITEMS HERE
    # GalleryItem("CHARACTER", "LABEL", "LOCKED_IMAGE", "UNLOCKED_IMAGE", "UNLOCKED_TEXT", SCOPE)
    GalleryItem("Ashira", "ashirasex1", "PatreonAshiraBlack.jpg", "Day1AshiraApartment.jpg", "Ashira Apartment Day 1")
    GalleryItem("Alero", "myLabel", "PatreonAleroBlack.jpg", "Day1AshiraAleroPool.jpg", "Ashira and Alero Swimming Pool Day 1")

default scopeDict = {}

define galleryMenu = [
    # ["CHARACTER", "IDLE_IMAGE", "HOVER_IMAGE"]
    ["Ashira", "PatreonAshiraQualityFull1.jpg", "patreonashiraqualityfullhovered.jpg"],
    ["Alero", "PatreonAleroQualityFull1.jpg", "patreonaleroqualityfullhovered.jpg"],
    ["Naomi", "PatreonNaomiQualityFull1.jpg", "patreonnaomiqualityfullhovered.jpg"],
    ["Nix", "PatreonNixQualityFull1.jpg", "patreonnixqualityfullhovered.jpg"],
    ["Odessa", "PatreonOdessaQualityFull1.jpg", "patreonodessaqualityfullhovered.jpg"],
    ["Vanessa", "PatreonVanessaQualityFull1.jpg", "patreonvanessaqualityfullhovered.jpg"]
]

screen scene_gallery():
    tag menu

    use game_menu(_("Scene Gallery"), scroll="viewport"):

            grid 2 3:
                spacing 10

                for char in galleryMenu:
                    imagebutton:
                        idle char[1]
                        hover char[2]
                        focus_mask True
                        action Show("scene_selection", character=char[0])


screen scene_selection(character):
    tag menu

    use game_menu(_("Scene Gallery"), scroll="viewport"):

        hbox:
            box_wrap True
            spacing 10

            for galleryItem in galleryItems:
                if galleryItem.char == character:
                    vbox:
                        imagebutton:
                            idle galleryItem.unlockedImage
                            insensitive galleryItem.lockedImage
                            action Replay(galleryItem.label, scope=updateScope(galleryItem.scope))
                        if renpy.seen_label(galleryItem.label):
                            text galleryItem.unlockedText
                        else:
                            text "???"
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,611
2,258
Just tested your code and it works fine (tested with RenPy 7.3.5).

When the specified label has already been seen by the player at least once - the scene is unlocked. If the player has never been through that bit of code before - the scene remains locked.

When the scene is locked, the image is unresponsive.
When the scene is unlocked, clicking on the image replays the game from that label until it encounters a renpy.end_replay() statement.

That seems to be the point of this replay gallery... so yeah... it works.

The only thing I can imagine confusing someone new to this sort of gallery / renpy.seen_label() is that the check is whether the label has been EVER seen. During this playthru or any previous playthru. But that is kinda the point to galleries. Depending on the game, some players may need to play through the game multiple times to unlock all the gallery scenes.

As a result, as the you do more testing... the scenes will all end up unlocked.

The primary way to lock the gallery again is to reset the persistent data. Just go into the RenPy launcher... make sure your game is selected... and then click [Delete Persistent] (it's the 4th option in the "Actions" menu).

My only other thought is that you've made a typo in your question. You've said "I'm stuck on the unlocked image". I wonder if you perhaps mean "I'm stuck on the LOCKED image" ?

If that is the case, then yes... the image won't respond when clicked - because that gallery is still locked. I can only imagine that, as yet, you haven't unlocked that particular gallery by playing through the game far enough to unlock it.

You can bypass this by using the RenPy console ( press [SHIFT+o] ). Then enter the command renpy.jump("ashirasex1") - or whichever label/scene you are trying to replay. This will force RenPy to continue from that scene, but in doing so... mark that label as unlocked.

Edit:

If I'm honest, I don't see WHY this code works.

The imagebutton is not coded to check for renpy.seen_image(), only the text below it is. Instead the button is controlled by either being marked sensitive or insensitive. But I see no code which controls that. Perhaps it's some internal RenPy bullshit linked to the action Replay() or perhaps that scope() code is having some effect I don't understand.

But regardless of my lack of understanding, it did work properly when I tested it. So that sensitive / insensitive status must be being set somewhere - and it does work as intended, with gallery scenes being unlocked by playing through that scene at least once without using the gallery.


Edit2:

Okay. Found it.


Yup. It's an indirect consequence of the action Replay(). When you use Replay( label, locked=None ) (and locked=None is the default option), the replay is automatically locked or unlocked based on whether the label has already been seen or not. Locked replays are flagged as insensitive, whereas unlocked replays are sensitive. That impacts the imagebutton... and everything else flows from there.

btw. Also found out that scope is just a list of variables and their values to be used during the replay.
 
Last edited:

khumak

Engaged Member
Oct 2, 2017
3,833
3,872
Edit2:

Okay. Found it.


Yup. It's an indirect consequence of the action Replay(). When you use Replay( label, locked=None ) (and locked=None is the default option), the replay is automatically locked or unlocked based on whether the label has already been seen or not. Locked replays are flagged as insensitive, whereas unlocked replays are sensitive. That impacts the imagebutton... and everything else flows from there.

btw. Also found out that scope is just a list of variables and their values to be used during the replay.
Thank you. This replay option is exactly what I've been trying to figure out the past few days. Finally have my gallery working now. The only thing I might still change now is to figure out how to tweak it so that locked thumbnails are greyed out and unlocked thumbnails are in color.

Also worth noting, make sure the label you want to replay does not include any references to variables that have not been defined since you're not starting an actual game. I was initially crashing due to calls to a class that was undefined since the definition doesn't happen in that label. I ended up tweaking the scenes that have my gallery entries so that I just call a gallery label that only includes the final series of dialog and video. Works like a charm now.

Edit: Figured out the option for "locked" vs "unlocked" gallery entries. Very pleased. Code at the bottom for anyone interested, it's pretty easy.

gallery.jpg

Code:
                        for q in galleryList:
                            $ qimage = q + ".jpg"           #unlocked gallery images
                            $ qlimage = q + "_locked.jpg"   #locked gallery images
                            if renpy.seen_image(q):        #checks to see if renpy has seen the gallery image (ever, in any playthrough)
                                $ lb_image = im.Scale(qimage, 320, 180)     #scale gallery image to thumbnail size
                            else:
                                $ lb_image = im.Scale(qlimage, 320, 180)    #scale gallery image to thumbnail size
                            imagebutton:
                                idle lb_image
                                hover lb_image
                                action Replay(q)            #plays gallery label "finale" for that scene
 
Last edited:
  • Like
Reactions: Baka_Energy_studios

Rich

Old Fart
Modder
Donor
Respected User
Game Developer
Jun 25, 2017
2,566
7,384
Also worth noting, make sure the label you want to replay does not include any references to variables that have not been defined since you're not starting an actual game. I was initially crashing due to calls to a class that was undefined since the definition doesn't happen in that label. I ended up tweaking the scenes that have my gallery entries so that I just call a gallery label that only includes the final series of dialog and video. Works like a charm now.
There's a way around that. The Replay action accepts an optional scope parameter. If you provide it, this is a Python dictionary that contains the names of variables and the values that should be used for them during the replay. Obviously, you can't "know" the values that might have been set during the game, but it's at least a workaround. In addition, of course, there is the _in_replay variable that Ren'py automatically sets to True during replay, which allows you to tweak behavior as required. Some people also handle variables during replay like this
Code:
label replay_label:
    if _in_replay:
        $ variable1 = value1
        $ variable2 = value2

    scene ....

    ....

    $ renpy.end_replay()
 

khumak

Engaged Member
Oct 2, 2017
3,833
3,872
I forgot about the _in_replay option. I could see there might be situations where you would want to use that. For now I just call a gallery label as the final part of any scene I'm going to put in the gallery with the gallery entry being fairly simple, like this.

Code:
label normal_scene:
    #this part of the scene has variables and stuff that replay might choke on
    call gallery01
    return

label gallery01:  # this part of the scene just has the finale and no variable manipulation other than end replay
    scene gallery01
    show kortney_sex
    kortney "I want to feel that big dick of yours inside me now..."
    rebecca "That little slut..."
    $ renpy.end_replay()
    return
In my case kortney_sex is a video. So my gallery shows image status as either locked or unlocked and then if it's unlocked and you click on it you get to see a finale video (or maybe a series of them if it's a longer scene.)

Next up on my list of things to figure out is to make a tiered gallery where the first gallery entry for each girl takes you to a separate gallery devoted to just that girl with all of her 1 on 1 scenes in there. Will probably have to have a separate section for group scenes. Have seen a few examples of how to do this but haven't tried it yet.

I think I also want to tweak the hover image so it's larger than the idle image so the gallery feels a bit more responsive as you're mousing over the images. Unlocked images would expand a bit as you mouse over them and locked images wouldn't. I think that should be fairly easy to do.

Edit: The expanded hover image is easy and definitely feels more responsive to me.

Code:
                            if renpy.seen_image(q):         #checks to see if renpy has seen this gallery image (ever, in any playthrough)
                                $ lb_image = im.Scale(qimage, 320, 180)     #scale gallery image to thumbnail size
                                $ hover_image = im.Scale(qimage, 336, 189)  #expand unlocked images by 5% as you mouse over them
                            else:
                                $ lb_image = im.Scale(qlimage, 320, 180)    #scale gallery image to thumbnail size
                                $ hover_image = lb_image                    #scale gallery image to thumbnail size (no expanded image since it's locked)
                            imagebutton:
                                idle lb_image
                                hover hover_image
                                action Replay(q)            #plays gallery label "finale" for that scene
Unlocked images expand by 5% when you mouse over them and then snap back to normal when you move on to the next one. Locked images don't do anything when you mouse over them.
 
Last edited: