Ren'Py Customizing/expanding SAVE and LOAD page file slots both horizontally and vertically

| Vee |

Well-Known Member
Jun 2, 2022
1,824
4,184
I just want to increase the slot's number's so that user can have each page for dedicated path(don't ask me why I am just trying to create for fun and new to renpy). For example:

I have 2 ideas

Each page will have 50/100 save and load slots starting from Page1 till Page10, now this can be done by 2 ways by using scroller to scroll vertically on Page1 and so on
OR
by making a 100 by 100 grid.

As you can see you can switch from one page to another horizontally but I want both horizontally and vertically meaning there will be another page switcher/scroller on the right side of the page than I can switch pages column-wise and by default page switcher which you can see below I can switch pages row-wise.

Any one shed some light on it and tell me if you have more efficient way to achieve this and will these many save effect game performance (lag etc). Also how ca I achieve this efficiently. THANK YOU!:D

screenshot0001.png
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,611
2,258
You'll want to take a look at the following groups of configuration variables...
  • /
  • /
  • /

The screen used by the save/load screens (screen file_slot(): is pretty well designed to be re-configurable.

Each of these variables change how the screen appears.
For your example, you'd want to change gui.file_slot_cols to 6 and gui.file_slot_rows to 3.

The problem then becomes that you've said use a 6 x 3 grid, but the buttons are still the same size.
So you need to change gui.slot_button_width / gui.slot_button_height.
I've no idea what to. When I did it, it was a bit of trial and error. Keep adjusting the numbers until you're happy.

You probably won't need to alter gui.slot_button_borders. I mention it, only because all these variables belong together.

The actual thumbnail needs to be smaller than the button it is shown within. Again, a bit of trial and error - but I would suggest trying to stick to 16:9 ratio sizes. Keep in mind that the button might also include things like the name of the save file and/or the date/time of the save. So the thumbnail will usually be significantly smaller than the button size (well, shorter at least).

Finally, I'll mention that the thumbnail width and height are included within the save file itself. If you save a file with the defaults of 100px x 75px and later change it to something like 90px x 51px, any saves before the change will still be shown as 100x75 and not 90x51. So if you are going to change the thumbnail size, change it BEFORE the game is ever released to anyone and after that... NEVER change it.

I will say that 4x3 is a much more comfortable change than 6x3. Keep in mind that your game may end up on a mobile device and if you make things too small, they will be unreadable. Just that small change would mean 12 save slots instead of the usual 6. And you have an infinite number of pages and you can even change the quick page links from showing < A Q 1 2 3 4 5 6 7 8 9 > to something like << A Q 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 > if you really want.

These variables are stored in gui.rpy and options.rpy, if memory serves.
 
Last edited:

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,611
2,258
And if you truly want to have up to 100 file slots per page, you're probably going to add a scrollable viewport as part of the screen file_slots():.

The normal arrangement is that each button is a button which is also a vbox (for the thumbnail and text under it), which is part of a grid, which is part of a fixed.

fixed: -> grid: -> button: / vbox:.

You could make that:

fixed: -> viewport: -> grid: -> button: / vbox:.

Or better still, a .

fixed: -> vpgrid: -> button: / vbox:.

Someone did raise something similar (save slots per story branch) with me at some point, it resulted in this thread:
https://f95zone.to/threads/filterin...d-on-sub-story-identifier.130103/post-8946158

I have to say, I'm not happy with the answer I came up with - since it is so limiting. But it does highlight at least one other option.
 
Last edited:
  • Heart
Reactions: | Vee |

| Vee |

Well-Known Member
Jun 2, 2022
1,824
4,184
THANK YOU! I will look these into consideration. You raised some points some of which I have already experimented and some I will do now that you mentioned those. Really appreciate your help! 79flavors :coffee:
 

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,565
9,079
I used to have a draft of a screen with unlimited save slots somewhere. Basically a "New Save" button with a list of existing saves below. Let's hope it wasn't the only copy on my dead SSD
 
  • Heart
Reactions: | Vee |

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,975
16,230
As you can see you can switch from one page to another horizontally but I want both horizontally and vertically meaning there will be another page switcher/scroller on the right side of the page than I can switch pages column-wise and by default page switcher which you can see below I can switch pages row-wise.
Isn't the vertical scroll defeating the interest to use the native possibility to rename a save/load page ?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,975
16,230
you can have the scrolling only inside the slots vpgrid/viewport so the page name is always on top
What is asked is, "as you can see you can switch from one page to another horizontally but I want both horizontally and vertically [...]".

If you switch from one page to another through a vertical scroll, you'll end with mixed pages. With a 3x3 format, it would be this:
  • 1-4 -> 1-6
  • 1-7 -> 1-9
  • 2-1 -> 2-3
and
  • 1-7 -> 1-9
  • 2-1 -> 2-3
  • 2-4 -> 2-6
In both case it's neither the first page, nor the second one.

Ren'Py works by save pages precisely because it permit to groups your saves depending on a common point.
By example, for a game where you can choose MC's gender, you'll have the first save page for your male playthrough, and the second for the female one.

Then, with the possibility to rename the page themselves, you don't have to use your brain, the first page will be renamed "male MC", the second "female MC", and hop...
If you want you can even use six pages:
"male MC - in progress"
"male MC - crucial choices"
"male MC - end of updates"
"female MC - in progress"
"female MC - crucial choices"
"female MC - end of updates"

But, once again, if the pages and their slots end being mixed, all this lost all interest.
You'll have on the same page the last slots for "male MC - end of updates", and "female MC - in progress"... And a hard time to easily discern them.



There's of course the possibility to switch page by page, but there's no interest in doing this vertically, it would have the exact same result than a horizontal switch. The only difference being that instead of clicking on a number, you click on a scrollbar (what is more abstract).
 
  • Thinking Face
Reactions: | Vee |

| Vee |

Well-Known Member
Jun 2, 2022
1,824
4,184
What is asked is, "as you can see you can switch from one page to another horizontally but I want both horizontally and vertically [...]".

If you switch from one page to another through a vertical scroll, you'll end with mixed pages. With a 3x3 format, it would be this:
  • 1-4 -> 1-6
  • 1-7 -> 1-9
  • 2-1 -> 2-3
and
  • 1-7 -> 1-9
  • 2-1 -> 2-3
  • 2-4 -> 2-6
In both case it's neither the first page, nor the second one.

Ren'Py works by save pages precisely because it permit to groups your saves depending on a common point.
By example, for a game where you can choose MC's gender, you'll have the first save page for your male playthrough, and the second for the female one.

Then, with the possibility to rename the page themselves, you don't have to use your brain, the first page will be renamed "male MC", the second "female MC", and hop...
If you want you can even use six pages:
"male MC - in progress"
"male MC - crucial choices"
"male MC - end of updates"
"female MC - in progress"
"female MC - crucial choices"
"female MC - end of updates"

But, once again, if the pages and their slots end being mixed, all this lost all interest.
You'll have on the same page the last slots for "male MC - end of updates", and "female MC - in progress"... And a hard time to easily discern them.



There's of course the possibility to switch page by page, but there's no interest in doing this vertically, it would have the exact same result than a horizontal switch. The only difference being that instead of clicking on a number, you click on a scrollbar (what is more abstract).
I understand what you are saying!

I may have not used the words correctly to convey what I wanted.

I basically want to increase the limit of save/load slots on every page up to 50 or 100, method's can be different but the end result is 50 or 100 saves on page 1 and so on, in the end each page will be used for one path/major story split.

Default horizontal pages may remain as it is but add a vertical scrollbar(omitting the plan to add vertical page switcher) so that the saves can be navigated vertically on each page which will result in desired outcome.

What do you think?
 

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,565
9,079
What is asked is, "as you can see you can switch from one page to another horizontally but I want both horizontally and vertically [...]".

If you switch from one page to another through a vertical scroll, you'll end with mixed pages. With a 3x3 format, it would be this:
  • 1-4 -> 1-6
  • 1-7 -> 1-9
  • 2-1 -> 2-3
and
  • 1-7 -> 1-9
  • 2-1 -> 2-3
  • 2-4 -> 2-6
In both case it's neither the first page, nor the second one.

Ren'Py works by save pages precisely because it permit to groups your saves depending on a common point.
By example, for a game where you can choose MC's gender, you'll have the first save page for your male playthrough, and the second for the female one.

Then, with the possibility to rename the page themselves, you don't have to use your brain, the first page will be renamed "male MC", the second "female MC", and hop...
If you want you can even use six pages:
"male MC - in progress"
"male MC - crucial choices"
"male MC - end of updates"
"female MC - in progress"
"female MC - crucial choices"
"female MC - end of updates"

But, once again, if the pages and their slots end being mixed, all this lost all interest.
You'll have on the same page the last slots for "male MC - end of updates", and "female MC - in progress"... And a hard time to easily discern them.



There's of course the possibility to switch page by page, but there's no interest in doing this vertically, it would have the exact same result than a horizontal switch. The only difference being that instead of clicking on a number, you click on a scrollbar (what is more abstract).
yeah the way I read it was just a 100x100 grid on each page instead of 6x3 so maybe it's a bit more complicated. a bigger grid is easily doable by replacing the default
Code:
grid gui.file_slot_cols gui.file_slot_rows:
with
Code:
            vpgrid:
                mousewheel True
                scrollbars "vertical"
                cols gui.file_slot_cols
and some slot resizing and maybe additional styling to avoid the slots overlapping with the page name or switching buttons
screenshot0001.png
I have something "almost working" with UNLIMITED SAVE POWER on one page in my older comment but I lost the final version of the screen where I fixed all the overlapping issues
screenshot0001.png
 
  • Like
Reactions: | Vee |

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,565
9,079
since I lost my good unlimited save screen, I might as well try to explain how it works while I'm trying to recreate it in case you might want something like this
screenshot0003.png screenshot0002.png

I use viewport for scrolling instead of grid. You might want to use a vpgrid if you don't like save slots being too long but I can think of all kinds of use for that space
Code:
viewport:
                mousewheel True
                scrollbars "vertical"
                style_prefix "slot"

                xalign 0.5
                yalign 0.5
                has vbox
                spacing gui.slot_spacing
then to get the list of existing saves. I also sort them by update time like normal non-AVN games do (probably should reverse it here because the result is "Newest last" and I just go from end to start when drawing buttons for them)

Code:
$ existing_saves = sorted(FileUsedSlots(page=FileCurrentPage(), highest_first=False), key=lambda x: FileTime(x, format=_("{#file_time}%Y %m %d, %H:%M:%S")))

then calculate what the next save slot should be and make a special "New Save" button at the top (still need to figure out why it overlaps with the page name and why switching buttons are behind save slots when I scroll, hate the part where I need to make things look good)

Code:
if title == "Save" and FileCurrentPage().isnumeric():
                    $ last_save_slot = (FileUsedSlots(page=FileCurrentPage(), highest_first=True) or [0])[0]
                  
                    $ new_slot = last_save_slot + 1
                    button:
                        xsize gui.slot_button_width
                        ysize gui.slot_button_height
                        action FileSave(new_slot)
                        has hbox
                        spacing 5
                        add "#aaa" size(config.thumbnail_width, config.thumbnail_height) xalign 0.5
                        text "New save":
                            style "slot_name_text"
and then show similar buttons for existing saves
Code:
                for slot in existing_saves[::-1]:
                    button:
                        xsize gui.slot_button_width
                        ysize gui.slot_button_height
                        action FileAction(slot)
                        has hbox
                        spacing 5

                        add FileScreenshot(slot) size(config.thumbnail_width, config.thumbnail_height) xalign 0.5
                        text FileTime(slot, format=_("{#file_time}%A, %B %d %Y, %H:%M"), empty=_("empty slot")):
                            style "slot_time_text"

                        text FileSaveName(slot):
                            style "slot_name_text"

                        key "save_delete" action FileDelete(slot)
so the final code will look something like this
Code:
viewport:
                mousewheel True
                scrollbars "vertical"
                style_prefix "slot"

                xalign 0.5
                yalign 0.5
                has vbox
                spacing gui.slot_spacing

                $ existing_saves = sorted(FileUsedSlots(page=FileCurrentPage(), highest_first=False), key=lambda x: FileTime(x, format=_("{#file_time}%Y %m %d, %H:%M:%S")))

                if title == "Save" and FileCurrentPage().isnumeric():
                    $ last_save_slot = (FileUsedSlots(page=FileCurrentPage(), highest_first=True) or [0])[0]
                  
                    $ new_slot = last_save_slot + 1
                    button:
                        xsize gui.slot_button_width
                        ysize gui.slot_button_height
                        action FileSave(new_slot)
                        has hbox
                        spacing 5
                        add "#aaa" size(config.thumbnail_width, config.thumbnail_height) xalign 0.5
                        text "New save":
                            style "slot_name_text"
                                

                for slot in existing_saves[::-1]:
                    button:
                        xsize gui.slot_button_width
                        ysize gui.slot_button_height
                        action FileAction(slot)
                        has hbox
                        spacing 5

                        add FileScreenshot(slot) size(config.thumbnail_width, config.thumbnail_height) xalign 0.5
                        text FileTime(slot, format=_("{#file_time}%A, %B %d %Y, %H:%M"), empty=_("empty slot")):
                            style "slot_time_text"

                        text FileSaveName(slot):
                            style "slot_name_text"

                        key "save_delete" action FileDelete(slot)
FileUsedSlots can also be used to disable pages with no saves on the Load screen but I'll save it for when I figure out overlapping stuff
 
  • Like
Reactions: | Vee |

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,975
16,230
What do you think?
Well, the "it defeat the naming page interest" part disappear, obviously, but personally I don't see the interest.

Of course, the default 6 slots/page is low, but even just 50 seem way too high for a page. A player can create more than this number of save files, but only a really small minority would want to keep them all. For most of them, it would be more than what they'll effectively use, preferring to circle through two or three rows like they have the habit to do with other Ren'Py games.

Plus, have to be kept in mind that the thumbnails should stay big enough to serve their purpose of visual help. This mean that you are limited to 4 slots by rows ; 5 if you move the navigation menu on top/bottom of the page, in place of the left side that is its default place.
As for the number of row themselves, keeping a reasonable size for the thumbnails mean that you can't really have more than 4. Of course, the player would be able to scroll the pages, but wouldn't this be a bit confusing, and more difficult to find the slots you want to find ? With at anytime 6 rows not visible, where's the slot you search ? Above or below the ones you are actually seeing ?

I think that, since in their vast majority, players would already have the habit to use a low number of slots, they would quickly stop using more than the rows directly visible. Not because having more is a bad idea, but because it imply a bit more works and reflection than what they do for any other games.
Would it be with another engine, they would use all what you propose them, because they wouldn't have direct reference and habits. But here you're in concurrence with thousands of games, the majority having the usual 3x2 slots by pages.

If you want, think about it like a situation where there would be works on a road you usually use to go to work. For few days you'll have to use another route, that isn't necessarily longer or more difficult, but that you don't have the habit to use. You'll feel uneasy and you'll be happy the day you'll be able to go back to your usual route.
It will probably be the same here. Most players would feel a bit uneasy and finally limits by themselves the possibilities, using your save/load pages as if there were no vertical scrolling possibilities.
 
  • Like
Reactions: | Vee |

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,611
2,258
I must admit, the largest grid I would normally go to would be 3 x 4 (in part because of Android).

As for the sort of "path per page thing"... I think I would rename the page titles for each route, then use multiple pages.

One feature that a lot of users overlook is that you can click on the page number at the top of the page (like "Page 1") and rename it. That new name is persistent.

So if I had Page 1, page 2 and page 3 all being called "Landlady path" and page 4, page 5 and page 6 all being called "Roommate path" - that would be enough organizing for me. I know, because I've have actual done this for certain games.
Especially once you realize that the < A Q 1 ... 9 > at the bottom is only the initial shortcuts and you can scroll right until you hit page #200 if you really have that sort of patience and then rename page #200 to be "Abstinence path" if you really wanted to.

The more I think about this, the more I return to my usual reply when people are doing stuff like this... Keep it simple, because what's there already works. You may see a reason to customize it, but your players are expecting to see same old boring Save/Load screens - without deciphering your extended implementation.
 
  • Like
Reactions: | Vee |

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,565
9,079
as an amateur screenshot shitposter (unfortunately can't find anyone who'd pay for that so can't call myself a pro in that field) I can totally understand why someone would want 50 saves just so I can easily jump into any point of the script

so here's a full screen with unlimited number of save slots

Code:
screen file_slots(title):

    default page_name_value = FilePageNameInputValue(pattern=_("Page {}"), auto=_("Automatic saves"), quick=_("Quick saves"))

    use game_menu(title):

        vbox:

            ## This ensures the input will get the enter event before any of the
            ## buttons do.
            order_reverse True
         
            ## The page name, which can be edited by clicking on a button.
            button:
                style "page_label"

                key_events True
                xalign 0.5
                action page_name_value.Toggle()

                input:
                    style "page_label_text"
                    value page_name_value

            ## Save slots.
            viewport:
                mousewheel True
                scrollbars "vertical"
                style_prefix "slot"

                xalign 0.5
                yalign 0.5
                has vbox
                spacing gui.slot_spacing

                $ existing_saves = sorted(FileUsedSlots(page=FileCurrentPage(), highest_first=False), key=lambda x: FileTime(x, format=_("{#file_time}%Y %m %d, %H:%M:%S")))

                if title == "Save" and FileCurrentPage().isnumeric():
                    $ last_save_slot = (FileUsedSlots(page=FileCurrentPage(), highest_first=True) or [0])[0]
               
                    $ new_slot = last_save_slot + 1
                    # the button can be smaller and without the fake "screenshot". I just made it the same as all other buttons for simplicity
                    button:
                        xsize gui.slot_button_width
                        ysize gui.slot_button_height
                        action FileSave(new_slot)
                        has hbox
                        spacing 5
                        add "#aaa" size(config.thumbnail_width, config.thumbnail_height) xalign 0.5
                        text "New save":
                            style "slot_name_text"
                             

                for slot in existing_saves[::-1]:
                    button:
                        xsize gui.slot_button_width
                        ysize gui.slot_button_height
                        action FileAction(slot)
                        has hbox
                        spacing 5

                        add FileScreenshot(slot) size(config.thumbnail_width, config.thumbnail_height) xalign 0.5
                        text FileTime(slot, format=_("{#file_time}%A, %B %d %Y, %H:%M"), empty=_("empty slot")):
                            style "slot_time_text"

                        text FileSaveName(slot):
                            style "slot_name_text"

                        key "save_delete" action FileDelete(slot)

            ## Buttons to access other pages.
            vbox:
                style_prefix "page"

                xalign 0.5
                yalign 1.0

                hbox:
                    xalign 0.5

                    spacing gui.page_spacing

                    textbutton _("<") action FilePagePrevious()

                    if config.has_autosave:
                        textbutton _("{#auto_page}A") action FilePage("auto")

                    if config.has_quicksave:
                        textbutton _("{#quick_page}Q") action FilePage("quick")

                    ## range(1, 10) gives the numbers from 1 to 9.
                    for page in range(1, 10):
                        textbutton "[page]" action FilePage(page)

                    textbutton _(">") action FilePageNext()

                if config.has_sync:
                    if CurrentScreenName() == "save":
                        textbutton _("Upload Sync"):
                            action UploadSync()
                            xalign 0.5
                    else:
                        textbutton _("Download Sync"):
                            action DownloadSync()
                            xalign 0.5
screenshot0004.png screenshot0005.png
It really doesn't look that alien if you played anything other than RenPy games. The only reason people are used to the default grid is because it's "good enough" so no one bothers changing it. I wouldn't be surprised if people used to think that way about the default main menu as well but pretty much every VN changes it now
 

ArunPrime

Member
Nov 5, 2022
299
461
Hello everyone,
I want to increase slots in 100 per page so I just changed gui column and rows.
In the game I can't access all slots.
I've readed some thread in this page I can't understand correctly.
Please tell me how to set all slots fit perfectly and scrollable.
 

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,565
9,079
Hello everyone,
I want to increase slots in 100 per page so I just changed gui column and rows.
In the game I can't access all slots.
I've readed some thread in this page I can't understand correctly.
Please tell me how to set all slots fit perfectly and scrollable.
Code:
vpgrid cols gui.file_slot_cols:
                mousewheel True
                arrowkeys True
                draggable True
                scrollbars "vertical"
                side_xalign 0.0
                ypos 450
                ymaximum 770
                style_prefix "slot"
                xalign 0.5
                yalign 0.5
                spacing gui.slot_spacing

                for i in range(1 * 100):

                    $ slot = i + 1

                    button:
                        action FileAction(slot)

                        has vbox

                        add FileScreenshot(slot) xalign 0.5

                        text FileTime(slot, format=_("{#file_time}%m / %d / %Y, %H:%M"), empty=_("Empty Slot")):
                            style "slot_time_text"

                        $ save_name_text = FileSaveName(slot)
                        text "[save_name_text!q]":
                            style "slot_name_text"

                        key "save_delete" action FileDelete(slot)
 
  • Like
Reactions: | Vee |

ArunPrime

Member
Nov 5, 2022
299
461
Code:
vpgrid cols gui.file_slot_cols:
                mousewheel True
                arrowkeys True
                draggable True
                scrollbars "vertical"
                side_xalign 0.0
                ypos 450
                ymaximum 770
                style_prefix "slot"
                xalign 0.5
                yalign 0.5
                spacing gui.slot_spacing

                for i in range(1 * 100):

                    $ slot = i + 1

                    button:
                        action FileAction(slot)

                        has vbox

                        add FileScreenshot(slot) xalign 0.5

                        text FileTime(slot, format=_("{#file_time}%m / %d / %Y, %H:%M"), empty=_("Empty Slot")):
                            style "slot_time_text"

                        $ save_name_text = FileSaveName(slot)
                        text "[save_name_text!q]":
                            style "slot_name_text"

                        key "save_delete" action FileDelete(slot)
Thank You I'm already found it.
Can you please tell me save name (description) add in the screen.
Is this same method like quick menu.