Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

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
Mumeishi
Newbie
Posts: 8
Joined: Mon Sep 28, 2020 4:19 pm
Projects: My Untitled VN game
Organization: Dai-Gurren Brigade
Contact:

Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#1 Post by Mumeishi »

I reaaally need help with this one, I haven't found any thread that helps me with this particular problem. I'm making my first Renpy game and I might be a bit too ambitious for a first-timer but I'm trying to completely change the look of the default screens. To be more specific I'm trying to emulate the look of the menus in Katawa Shoujo (which was the first VN game I ever played). I managed to make my Preferences and Gallery look very similar by using modals and frames, but the save/load screen is not working for me. I been looking at countless tutorials and other threads in this forum to find code that will help me achieve that particular look but I've had no luck.

Here's a screenshot of what I'm refering to:
Image

It has a system where only the slots that you use show up and you can scroll through them, if you add a new save it then shows up at the bottom of the list. I have no idea how to achieve that in my game. Any help will be appreciated!

Here are screenshots of how my game looks right now, the images here are not the definitive yet, they are just placeholders I made but they look close to what I'm going for (my game is in spanish btw, but once I'm finished I will make an english ver):

Main menu
Image

Preferences
Image

Gallery
Image

My horrible save/load screen that doesnt work :( :( :(
Image
"Kick logic to the curb and do the impossible!"
  • -Kamina

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#2 Post by hell_oh_world »

You're actually pretty much close just looking at it. Additional things that I can suggest:
1.) Refer to this to configure the thumbnail/slot size: https://www.renpy.org/doc/html/gui.html ... ot-buttons
2.) Maybe add some xsize width to the viewport or xfill True to span it entirely.
3.) As for the slot buttons that are not empty. Use the FileLoadable() function. https://www.renpy.org/doc/html/gui.html ... ot-buttons
So in your vbox all you gotta do is add a condition using the function.

Code: Select all

screen file_slots(title):
  ...
  vbox:
    if FileLoadable(slot):
      button:
        action FileAction(slot)
  ...

User avatar
Mumeishi
Newbie
Posts: 8
Joined: Mon Sep 28, 2020 4:19 pm
Projects: My Untitled VN game
Organization: Dai-Gurren Brigade
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#3 Post by Mumeishi »

Thank you for the reply! I'm not sure where to add that code. But I get the purpose of using de FileLoadable() function. I pretty much just copied the original code and pasted it to my modal but I'm sure this is the wrong way to do it. My code looks like this right now (is a mess):

Code: Select all

screen my_saves():

    modal True
     
    zorder 200
     
    style_prefix "confirm"

    add "gui/overlay/confirm.png"
    frame:
        xalign 0.5
        yalign 0.5
        xminimum 1080
        xmaximum 1080
        yminimum 800
        ymaximum 800
            
        vpgrid:
            cols 1
            rows 5
            scrollbars "vertical"
            mousewheel True
            side_yfill True
            
            grid 1 5:

                style_prefix "slot"

                xalign 0.0
                yalign 0.5

                spacing 10

                for i in range(1 * 5):

                    $ slot = i + 1

                    button:
                        action FileAction(slot, page="Cargar")

                        has vbox

                        add FileScreenshot(slot) xalign 0.0

                        text FileTime(slot, format=_("{#file_time}%A, %d de %B, %H:%M"), empty=_("vacío")):
                            style "slot_time_text"

                        text FileSaveName(slot):
                            style "slot_name_text"

                        #key "save_delete" action FileDelete(slot)
            
            
        button:
            text "[ Volver ]"
            action Hide("my_saves",transition = dissolve)
"Kick logic to the curb and do the impossible!"
  • -Kamina

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#4 Post by hell_oh_world »

The file_slots screen is the screen for the save and load screens found in screens.rpy, so I just assumed that you're using that one. Anyhow, in your code, you're using grid which is okay too. All you need is to add a condition then in the else block just add Null() to fill the empty cells.

Code: Select all

screen my_saves():

    modal True
     
    zorder 200
     
    style_prefix "confirm"

    add "gui/overlay/confirm.png"
    frame:
        xalign 0.5
        yalign 0.5
        xminimum 1080
        xmaximum 1080
        yminimum 800
        ymaximum 800
            
        vpgrid:
            cols 1
            rows 5
            scrollbars "vertical"
            mousewheel True
            side_yfill True
            
            grid 1 5:

                style_prefix "slot"

                xalign 0.0
                yalign 0.5

                spacing 10

                for i in range(1 * 5):

                    $ slot = i + 1
                    
                    if FileLoadable(slot):
                      button:
                          action FileAction(slot, page="Cargar")

                          has vbox

                          add FileScreenshot(slot) xalign 0.0

                          text FileTime(slot, format=_("{#file_time}%A, %d de %B, %H:%M"), empty=_("vacío")):
                            style "slot_time_text"

                          text FileSaveName(slot):
                            style "slot_name_text"

                          #key "save_delete" action FileDelete(slot)

                    else:
                      add Null()
            
            
        button:
            text "[ Volver ]"
            action Hide("my_saves",transition = dissolve)
Not sure with this though, iirc, a grid's cell must be the same size with others, so this approach might result in displaying an empty cell but with a large gap representing each cell. That's why in your kind of setup, where displayables are aligned vertically, it is better to use a plain vbox and contain it inside a viewport, in that way you won't be having a problem in filling empty cells and you can independently size each row of saves etc.

User avatar
Mumeishi
Newbie
Posts: 8
Joined: Mon Sep 28, 2020 4:19 pm
Projects: My Untitled VN game
Organization: Dai-Gurren Brigade
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#5 Post by Mumeishi »

Thank you again! I'll try using your code and see how it works. When you tell me to use a vbox contained in a viewport you mean replacing the vpgrid for viewport and grid for vbox, is that correct?
"Kick logic to the curb and do the impossible!"
  • -Kamina

User avatar
Mumeishi
Newbie
Posts: 8
Joined: Mon Sep 28, 2020 4:19 pm
Projects: My Untitled VN game
Organization: Dai-Gurren Brigade
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#6 Post by Mumeishi »

Now it looks waaay better!

Image

Thanks a lot! Now it only shows the slots with saved games and you can scroll. I also followed your advice and made it into a viewport with a vbox but I had no idea what I had to write inside this part:

Code: Select all

for i in range(1):

                    $ slot = i + 1
                    
                    if FileLoadable(slot):
                      button:
                          action FileLoad(slot)
In the range I originally wrote 1*5 because my grid was 1 col 5 rows (and that made sense to me) :? . But now I wrote 1 because I only want one slot to apper a at a time?...right? I dont know much about how this works... But in any case, it looks good, and the game doesnt crash (YET).

It looks closer to what I'm aiming for. A couple of things missing is that I don't want to be able to SAVE or overwrite by clicking on the image/slot I want to add a button (it might be just a textbutton) to make new saves. I only want to be able to LOAD by clicking the image/slot. Again, this is in keeping with the way it worked in KS which I liked better that the default Renpy system.

Do you have any idea of how that would work?
"Kick logic to the curb and do the impossible!"
  • -Kamina

User avatar
Mumeishi
Newbie
Posts: 8
Joined: Mon Sep 28, 2020 4:19 pm
Projects: My Untitled VN game
Organization: Dai-Gurren Brigade
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#7 Post by Mumeishi »

Ok, I made it possible only to LOAD by clicking on the thumbnail. But I still need to make a button that allows users to SAVE and show that saved game in the list under the first slot. I tried making one but it didn't work, I get an error saying the "ZipFileImage is not callable" (I don't know what that means, but I guess is something about how I tried to "save" the game with my button).

You can see the button I made in this pic:

Image

This is the code I'm using now:

Code: Select all

screen my_saves():

    modal True
     
    zorder 200
     
    style_prefix "confirm"

    add "gui/overlay/confirm.png"
    frame:
        xalign 0.5
        yalign 0.5
        xminimum 1080
        xmaximum 1080
        yminimum 800
        ymaximum 800
            
        viewport:
            scrollbars "vertical"
            mousewheel True
            side_yfill True
            
            vbox:

                style_prefix "slot"

                xalign 0.0
                yalign 0.5

                spacing 10

                for i in range(1):

                    $ slot = i + 1
                    
                    if FileLoadable(slot):
                      button:
                          action FileLoad(slot)

                          has vbox

                          add FileScreenshot(slot) xalign 0.0

                          text FileTime(slot, format=_("{#file_time}%A, %d de %B, %H:%M"), empty=_("vacío")):
                            style "slot_time_text"

                          text FileSaveName(slot):
                            style "slot_name_text"

                          #key "save_delete" action FileDelete(slot)

                    else:
                      add Null()
            
        vbox:
            xalign 1.0
            yalign 1.0
            xsize 200
            ysize 100
            button:
                text "[ Volver ]"
                action Hide("my_saves",transition = dissolve)
                
        vbox:
            xalign 0.0
            yalign 1.0
            xsize 200
            ysize 100
            
            for i in range(1):

                    $ slot = i + 1
                    
                    if FileNewest(slot):
                      button:
                          
                          text "[Guardar]"
                          action [ FileSave(slot),FileScreenshot(slot),FileTime(slot) ]
"Kick logic to the curb and do the impossible!"
  • -Kamina

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#8 Post by hell_oh_world »

Thanks a lot! Now it only shows the slots with saved games and you can scroll. I also followed your advice and made it into a viewport with a vbox but I had no idea what I had to write inside this part:
Try this. Use FileUsedSlots() function to get only the loadable slots.

Code: Select all

screen my_saves():

    modal True
     
    zorder 200
     
    style_prefix "confirm"

    add "gui/overlay/confirm.png"
    frame:
        xalign 0.5
        yalign 0.5
        xminimum 1080
        xmaximum 1080
        yminimum 800
        ymaximum 800
            
        viewport:
            scrollbars "vertical"
            mousewheel True
            side_yfill True
            
            vbox:

                style_prefix "slot"

                xalign 0.0
                yalign 0.5

                spacing 10

                for slot in FileUsedSlots(highest_first=False): # the function returns a list containing only the loadable slots, so you can do it without having a condition now...  
                      button:
                          action FileLoad(slot)

                          has hbox # let's align the save slot like what is shown in your ideal layout...

                          add FileScreenshot(slot) xalign 0.0
                          
                          vbox:
                            text FileTime(slot, format=_("{#file_time}%A, %d de %B, %H:%M"), empty=_("vacío")):
                              style "slot_time_text"

                            text FileSaveName(slot):
                              style "slot_name_text"
            
        vbox:
            xalign 1.0
            yalign 1.0
            xsize 200
            ysize 100
            button:
                text "[ Volver ]"
                action Hide("my_saves",transition = dissolve)
May I also suggest that after adapting to this new approach and trying it to delete all of existing saves in the save directory of your game and then go to the launcher and clear the persistent (renpy launcher -> delete persistent).
Haven't also tried this, so sorry if the hbox messed up your layout :)

User avatar
Mumeishi
Newbie
Posts: 8
Joined: Mon Sep 28, 2020 4:19 pm
Projects: My Untitled VN game
Organization: Dai-Gurren Brigade
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#9 Post by Mumeishi »

Hello again. Thanks to your help + some extra tweaking I managed to achieve a very similar look to the KS save screen so far. I added your code plus a small button that lets you delete the save by adding this part:

Code: Select all

add FileScreenshot(slot) xalign 0.0
                          
                          hbox:
                              xalign 0.5
                              yalign 0.5
                              xminimum 400
                              xmaximum 400
                              text FileTime(i, format=_("{#file_time}%A, %d de %B, %H:%M"), empty=_("vacío")):
                                  xalign 0.7
                        
                          hbox:
                             xalign 0.7
                             yalign 0.5
                             xsize 50
                             ysize 50
                             button:
                                 text "(X)"
                                 xalign 0.7
                                 action FileDelete(slot)
And I changed the code for my SAVE button (but it doesnt work the way it should...more on that later) :(

I also tried deleting my saves even before you suggested it but it led to a problem. I can't save unless there's an older save slot visible and all it can do is rewrite that same slot. My save button can only rewrite a previous save, if there are no saves visible then it supposedly "saves" but nothing shows up on the list.

So, for now my save screen can only show one slot with thumbnail and if the user clicks the SAVE button it overwrites that one instead of creating a new one underneath.

Once again, thank you for all your help. There has been a great progress so I'll just keep looking for ways to make the code work the way I need, so if you have more ideas please let me know. :D :D

:mrgreen: This is how it looks now:

Image

BTW the code for my "save game" button is this:

Code: Select all

vbox:
            xalign 0.0
            yalign 1.0
            xsize 200
            ysize 100
            button:
                text "[Guardar]"
                action FileAction(slot)
"Kick logic to the curb and do the impossible!"
  • -Kamina

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#10 Post by hell_oh_world »

PRIORITY: In deleting the save, delete first the saves in your game directory then delete the saves folder for your game in the temp folder of your system. For windows, hit winkey + r then type this %appdata%, then hit enter then find the RenPy directory, inside that directory find your game name and delete that folder, after doing this all of the conflicting saves from the old approach should be removed by now.

For the saving, the action I think should be like this instead.

Code: Select all

action FileAction(max(FileUsedSlots() or [0]) + 1) # I think this would work, also FileSave might be the best one to use here instead of FileAction
or I think something like this should also do the trick (Much less verbose).

Code: Select all

action FileAction(None) # FileSave(None) should also work
Haven't tried all of these, but should work *I think*, find what suits your need the most :D

User avatar
Mumeishi
Newbie
Posts: 8
Joined: Mon Sep 28, 2020 4:19 pm
Projects: My Untitled VN game
Organization: Dai-Gurren Brigade
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#11 Post by Mumeishi »

To better explain how the system is currently working I made a short demo video:

https://youtu.be/jYXojNB6_7c

8) I feel like we are getting SO close to it working perfectly! Right now there are a couple issues, one is that there's a blank space above the list of save slots at all times, I don't know why that happens, but I think it may have something to do with how I use a variable with $ slot = slot + 1, I know you told me to drop the variable but thanks to it I'm able to keep saving on new slots instead of just overwriting the same one. If you have a better solution please tell me.

Another problem is that when I use the (X) to delete the saves it only works fine if I delete the last one on the list, if I try to delete another one on the top then it deletes 2 slots, the one I want and the one right below. Again, I think this is beacues of that variable, but I can't find a better way to achieve something that works the way I need :cry: :cry:

I added your code for the SAVE button, it works great! I'm working on an old Macbook so I don't know how to find the saves on the temp folder you mentioned, I will look into it, but I have already deleted the saves in the project folder and the persistent data as you previously suggested.

I can't thank you enough for all your help :mrgreen: . If you know a way to fix these issues or a better way to work around them then please tell me.

This is the code right now:

Code: Select all

screen my_saves():

    modal True
     
    zorder 200
     
    style_prefix "confirm"

    add "gui/overlay/confirm.png"
    frame:
        xalign 0.5
        yalign 0.5
        xminimum 1080
        xmaximum 1080
        yminimum 800
        ymaximum 800
            
        viewport:
            yminimum 500
            ymaximum 500
            scrollbars "vertical"
            mousewheel True
            side_yfill True
            
            vbox:

                style_prefix "slot"

                xalign 0.0
                yalign 0.1

                spacing 25
                
                for slot in FileUsedSlots(highest_first=False):
                    
                    $ slot = slot + 1
                    
                    if FileLoadable(slot):
                        
                        button:
                            action FileLoad(slot)

                            has hbox

                            add FileScreenshot(slot)
                          
                            hbox:
                                xalign 0.5
                                yalign 0.5
                                xminimum 400
                                xmaximum 400
                                
                                text FileTime(slot, format=_("{#file_time}%A, %d de %B, %H:%M"), empty=_("vacío")):
                                    xalign 0.7

                                text FileSaveName(slot):
                                    xalign 0.7
                            
                            hbox:
                                xalign 1.0
                                yalign 0.5
                                
                                button:
                                    text "(X)"
                                    action FileDelete(slot)
            
                    else:
                      add Null()
            
        vbox:
            xalign 1.0
            yalign 1.0
            xsize 200
            ysize 100
            button:
                text "[ Volver ]"
                action Hide("my_saves",transition = dissolve)
                
        vbox:
            xalign 0.0
            yalign 1.0
            xsize 200
            ysize 100
            button:
                text "[Guardar]"
                action FileAction(max(FileUsedSlots() or [0]) + 1) 
"Kick logic to the curb and do the impossible!"
  • -Kamina

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#12 Post by hell_oh_world »

It looks okay on me though. I just copied and pasted your code in this one, left the styles to default and didn't add any. So I suggest checking your styles if ever you changed the styles for the slots or confirm.
2020-09-30 12_50_11-The Question.png
If you really cant figure out why it has a gap then maybe try the inspector? On one of your saves, hover your cursor onto the screenshot of the save then hit shift + i then see the structure in the inspector and click the style for the vbox or the viewport to see if you added some styles that might have caused the gap.
check_styles.jpg
Maybe its because of this part? Not sure though, but you wont be needing this. It's only applicable in your old method where you're using a grid instead of vbox. Vboxes don't throw an error when there's a missing child or what.

Code: Select all

else:
  add Null()
In my previous post, I actually eliminated the conditionals, the if FileLoadable(slot) part.
hell_oh_world wrote: Tue Sep 29, 2020 2:49 am
This one...

Code: Select all

$ slot = slot + 1
Is kinda bad though, I tried this one, if you have no saves (empty) then click the save button, the first save slot wont show even though its saved, on the 2nd click of the save button it will show one save instead of showing 2.
And it works well for me without any issue with this line of code being dropped and with the save button's action that I suggested.
I'm working on an old Macbook so I don't know how to find the saves on the temp folder you mentioned
In your config.rpy you should find a variable config.save_directory or config.savedir, something like that. It should contain the path to the temp folder of the game. Another option would be, while in game press shift + o then type config.savedir or config.save_directory then press enter and you should see the path in the console where the temp folder is located.
This might also help, the official doc says... https://www.renpy.org/doc/html/config.h ... _directory
This is used to generate the directory in which games and persistent information are saved. The name generated depends on the platform:

Windows
%APPDATA%/RenPy/save_directory
Mac OS X
~/Library/RenPy/save_directory

Linux/Other
~/.renpy/save_directory
But if not then try the first workarounds that I suggested.
If you found it then it should look something like this.
renpy_temp.jpg
Overall, this how it looks on my side, with the line of code that I said being dropped. (GIF)
2020-09-30_13-27-04.gif

User avatar
Mumeishi
Newbie
Posts: 8
Joined: Mon Sep 28, 2020 4:19 pm
Projects: My Untitled VN game
Organization: Dai-Gurren Brigade
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#13 Post by Mumeishi »

IT WORKS!!! :D :D :mrgreen:

Finally everything works as it should! Here's a short video demo again:

https://youtu.be/w_dU-Nj-aAc

I'm so happy, thanks a lot for your help hell_oh_world! I used your recommendations plus some extra tweaking.

I will put you in the credits of my game once I'm finished! :wink: (I still have a lot of work left to complete it)

As I said in my first message this is my first game so I'll probably be returning to the forums for help with development. I think I will also make a post with a "tutorial" ...or at least just the code so others can customize their save/load screen in this way as I'm sure others would like to have this design.

Thanks again!
"Kick logic to the curb and do the impossible!"
  • -Kamina

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Making a vertical scrollable LOAD/SAVE screen that only shows slots if they are in use

#14 Post by hell_oh_world »

Glad you made it work :o . Good luck and best wishes for your game!

Post Reply

Who is online

Users browsing this forum: No registered users