[Solved] How to show the MC's name and the slot page-number on file slots?

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
Adabelitoo
Regular
Posts: 86
Joined: Sat Apr 13, 2019 2:32 pm
Contact:

[Solved] How to show the MC's name and the slot page-number on file slots?

#1 Post by Adabelitoo »

I'm trying to customize the save/load slots and make them show the player's name, the page and slot number, the custom save name, the save's date, and finally the game's name and version. On the other hand, if the file slot is empty, I want it to show nothing at all except for the page and slot number.

This is how I'd like to make it look and what I currently have. As you will see, it's a mess.
Image

I've been reading previous posts about how to store the player's name for each save but honestly I didn't understand it, and copy-pasting random code on my game didn't work. I still have no idea how to show each page-slot number, and I guess that's already stored in the game. I can't make empty slots look empty (I forgot to delete the "empty slot" code when I took the screenshot), and lastly, since everything is in a vbox, things move up and down depending on how much space previous thing take. I'd like them to be at a specific place regardles of other things.

This is my code so far:

Code: Select all

grid gui.file_slot_cols gui.file_slot_rows:
                style_prefix "slot"
                xalign 0.5
                yalign 0.44
                spacing gui.slot_spacing
                for i in range(gui.file_slot_cols * gui.file_slot_rows):
                    $ slot = i + 1
                    button:
                        if persistent.saveName:
                            action If(renpy.get_screen("save"), true=Show("savegameName", accept=FileSave(slot)), false=FileLoad(slot))
                        else:
                            action FileAction(slot)
                        hbox:
                            add FileScreenshot(slot) xalign 0.5
                            vbox xpos 7:
                                text "{size=38}[mc]":
                                    style "slot_name_text"
                                text "{size=28}P-S":
                                    xpos 285
                                    ypos -35
                                    style "slot_name_text"
                                if FileSaveName(slot):
                                    $ fn = FileSaveName(slot)
                                    if fn and ("-" in fn):
                                        $ y = fn.split("-")
                                    text fn:
                                        style "slot_name_text"
                                text FileTime(slot, format=_("{size=20}{#file_time}%A, %B %d %Y, %H:%M")):
                                    style "slot_time_text"
                                hbox:
                                    text "{size=20}[config.name!t]":
                                        style "slot_time_text"
                                    text "  "
                                    text "{size=20}v{#file_version}[config.version!t]":
                                        style "slot_time_text"

                            key "save_delete" action FileDelete(slot)
Lastly, is it possible to increase only the horizontal spacing between the columns? I'd like them to have them a little farther from each other to reduce the empty space at the sides. I tried changing spacing gui.slot_spacing but that changes both the vertical and horizontal spcae. Thanks for reading.
Last edited by Adabelitoo on Wed Feb 07, 2024 4:27 pm, edited 1 time in total.

User avatar
MrXotic
Newbie
Posts: 6
Joined: Sat Nov 11, 2023 2:02 am
Contact:

Re: How to show the MC's name and the slot page-number on file slots?

#2 Post by MrXotic »

First of all, to save the player's name and display it for each save operation, you can use persistent variables in Ren'Py. For example, you could prompt the player for their name at the beginning of the game and then save it in a persistent variable:

label start:
$ persistent.player_name = renpy.input("Please enter your name:")

Then you can use this variable to display the player's name in your save slots:
text "[persistent.player_name]"

To display the page and slot number, you can simply use the index variable you're already using in your loop:

text "Page: [i // gui.file_slot_cols + 1], Slot: [i % gui.file_slot_cols + 1]"

To check if a slot is empty, you can use the FileExists function:

if FileExists(slot):
# Slot is not empty
# Show information
else:
# Slot is empty
# Show nothing or whatever you prefer

Finally, to ensure that the elements in your save slots are positioned independently of each other, you can work with absolute positions instead of relative positions. For example, you could use hbox and vbox for each element separately and then set the position of each element absolutely.

Here's a revised excerpt of your code with some of these changes:

grid gui.file_slot_cols gui.file_slot_rows:
style_prefix "slot"
xalign 0.5
yalign 0.44
spacing gui.slot_spacing
for i in range(gui.file_slot_cols * gui.file_slot_rows):
$ slot = i + 1
button:
if FileExists(slot):
action FileLoad(slot)
hbox:
# Display for saved slots here
else:
# Display for empty slots here

I hope that helps!

User avatar
Adabelitoo
Regular
Posts: 86
Joined: Sat Apr 13, 2019 2:32 pm
Contact:

Re: How to show the MC's name and the slot page-number on file slots?

#3 Post by Adabelitoo »

Thanks for replaying.
MrXotic wrote: Tue Feb 06, 2024 1:47 am First of all, to save the player's name and display it for each save operation, you can use persistent variables in Ren'Py. For example, you could prompt the player for their name at the beginning of the game and then save it in a persistent variable:
How early are we talking about? Because in this project I still have no content so the MC name is at the beginning but in the real story it takes a few minutes to get to that point.
MrXotic wrote: Tue Feb 06, 2024 1:47 am To display the page and slot number, you can simply use the index variable you're already using in your loop:

text "Page: [i // gui.file_slot_cols + 1], Slot: [i % gui.file_slot_cols + 1]"
This isn't working. If the page has 6 slots then it should say 1-1,1-2,1-3,...,1-6 in Page 1 and then 2-1,2-2,...,2-6 in Page 2 and so on, but that way it shows 1-1,1-2,2-1,2-2,3-1,3-2 in all pages.
MrXotic wrote: Tue Feb 06, 2024 1:47 am To check if a slot is empty, you can use the FileExists function:

if FileExists(slot):
# Slot is not empty
# Show information
else:
# Slot is empty
# Show nothing or whatever you prefer
I guess I'm missing something here and taking this too literal because I get NameError: name 'FileExists' is not defined
MrXotic wrote: Tue Feb 06, 2024 1:47 am Finally, to ensure that the elements in your save slots are positioned independently of each other, you can work with absolute positions instead of relative positions. For example, you could use hbox and vbox for each element separately and then set the position of each element absolutely.

Here's a revised excerpt of your code with some of these changes:

grid gui.file_slot_cols gui.file_slot_rows:
style_prefix "slot"
xalign 0.5
yalign 0.44
spacing gui.slot_spacing
for i in range(gui.file_slot_cols * gui.file_slot_rows):
$ slot = i + 1
button:
if FileExists(slot):
action FileLoad(slot)
hbox:
# Display for saved slots here
else:
# Display for empty slots here

I hope that helps!
This works better than expected, but the issue now is that the long wwwwww save name I made for showcase doesn't break lines, it's so long that starts over the picture while the numbers save name starts at a razonable place. Another question related to this, if I want to move these texts grabing them from the left side, what position propertie should I use?

User avatar
m_from_space
Miko-Class Veteran
Posts: 975
Joined: Sun Feb 21, 2021 3:36 am
Contact:

Re: How to show the MC's name and the slot page-number on file slots?

#4 Post by m_from_space »

MrXotic wrote: Tue Feb 06, 2024 1:47 am First of all, to save the player's name and display it for each save operation, you can use persistent variables in Ren'Py. For example, you could prompt the player for their name at the beginning of the game and then save it in a persistent variable:
That's a misconception. A persistent variable is used for data regardless of a specific game, e.g. if a gallery was unlocked that is accessible via the main menu. But OP wants to save the character's name for each game being played (whether by the same player or different players). The character will have different names, so a single persistent variable won't do.
Adabelitoo wrote: Tue Feb 06, 2024 1:27 am I'm trying to customize the save/load slots and make them show the player's name, the page and slot number, the custom save name, the save's date, and finally the game's name and version. On the other hand, if the file slot is empty, I want it to show nothing at all except for the page and slot number.
Page and slot number are implicit and available, you don't have to save them. Date is already saved, as you can see in a default Renpy project. You can access it using FileTime(slot)

Save name and version are available via https://www.renpy.org/doc/html/screen_a ... l#FileJson

I don't know what you mean by "game's name" - does your game's name change?

Any other information you want to save, you just pass via a Json callback described here: https://www.renpy.org/doc/html/config.h ... _callbacks

Code: Select all

default mc_name = "Eileen"

init python:
    def jsoncallback(d):
        # whenever a game is saved, also save this name with it
        d["mc_name"] = store.mc_name

    config.save_json_callbacks.append(jsoncallback)
You can access all this data later like this:

Code: Select all

for i in range(gui.file_slot_cols * gui.file_slot_rows):
    $ slot = i + 1

    # character name (saved via jsoncallback function)
    $ save_mc_name = FileJson(slot, "mc_name")
    if save_mc_name:
        text "Character name: [save_mc_name]"

    # version (saved automatically by Renpy)
    $ save_version = FileJson(slot, "_version")
    if save_version:
        text "Version: [save_version]"

User avatar
Adabelitoo
Regular
Posts: 86
Joined: Sat Apr 13, 2019 2:32 pm
Contact:

Re: How to show the MC's name and the slot page-number on file slots?

#5 Post by Adabelitoo »

Thanks for replaying.
m_from_space wrote: Tue Feb 06, 2024 10:05 am Page and slot number are implicit and available, you don't have to save them.
How can I show them on the save slots?
m_from_space wrote: Tue Feb 06, 2024 10:05 am Any other information you want to save, you just pass via a Json callback described here: https://www.renpy.org/doc/html/config.h ... _callbacks

Code: Select all

default mc_name = "Eileen"

init python:
    def jsoncallback(d):
        # whenever a game is saved, also save this name with it
        d["mc_name"] = store.mc_name

    config.save_json_callbacks.append(jsoncallback)
You can access all this data later like this:

Code: Select all

for i in range(gui.file_slot_cols * gui.file_slot_rows):
    $ slot = i + 1

    # character name (saved via jsoncallback function)
    $ save_mc_name = FileJson(slot, "mc_name")
    if save_mc_name:
        text "Character name: [save_mc_name]"

    # version (saved automatically by Renpy)
    $ save_version = FileJson(slot, "_version")
    if save_version:
        text "Version: [save_version]"
That jsoncallback thing is what I didn't get from previous posts. I planned to allow the player to change their name mid-game if they wish, so if the player's name is (let's suppose) "Mark", all saves should say "Mark", but if the player's name changes to "Rocky", all saves before that should keep saying "Mark" while new saves should say "Rocky".

Code: Select all

default mc = " "                     #The current one used during the game                                                   
default saved_name = " "             #To show it on the file slots at the moment of making the save
How do I apply that to your code? Having mc_name at both sides is confusing me.

User avatar
m_from_space
Miko-Class Veteran
Posts: 975
Joined: Sun Feb 21, 2021 3:36 am
Contact:

Re: How to show the MC's name and the slot page-number on file slots?

#6 Post by m_from_space »

Adabelitoo wrote: Tue Feb 06, 2024 2:31 pm Thanks for replaying.
m_from_space wrote: Tue Feb 06, 2024 10:05 am Page and slot number are implicit and available, you don't have to save them.
How can I show them on the save slots?
So both "page" and "slot" are usually numbers from 1 to infinity (or let's say the highest integer). Renpy just uses those numbers for creating a filename that has the format "page-slot", so for example "1-1" is the first slot on page 1, "1-2" is the second slot on page 1. By default you have 6 slots for each page, but that's not set in stone. You can configure it by changing the <gui.rpy> variables ("page" can also be the strings "auto" or "quick" for the special pages for auto saves and quick saves).

The file_slots() screen is special and therefore... a bit weird. So for example it's unclear how Renpy determines the current page it is on. I guess it's an internal variable. But you have access to this variable inside the file_slots screen by calling FilePageName() (returns a normal number for a normal page, otherwise "quick" or "auto" if you're on these special pages).

Both "slot" and "page" are shown by default - "slot" refers to the slot number on the page. If you have 6 slots, the first slot is slot 1. And page is the current page you're on, you can see it when looking at all those page values you can click on (usually 1 to 9, but also not set in stone).

Renpy always knows what page you're on, so you just have to use the slot number to determine the saved game you mean. Yes, I said it's weird. But also convenient. :)

Code: Select all

default mc = " "                     #The current one used during the game                                                   
default saved_name = " "             #To show it on the file slots at the moment of making the save
How do I apply that to your code? Having mc_name at both sides is confusing me.
Alright, I lead you through it. You definitely don't need a "default" variable for the saved_name. It's just used in the moment we want to display it as part of the main menu.

Here we have your global variable that will save a character's name when launching a game:

Code: Select all

default mc = "Mark"
Alright, now when saving a game, Renpy of course will save this name and reload it when the player loads that game. But we do not have access to this variable while the game is not loaded, because it is packed (I guess as part of some zip file or whatnot) that Renpy is creating. So a way to access this name without loading the game (for example in the main menu) is to save it as part of the JSON information that Renpy saves with each game. Usually this JSON information contains stuff like the game version or the renpy version. So if we want other information to be saved inside this, we just have to create the function I posted. The JSON information is just like a Python dictionary. You set a key and save a value.

Code: Select all

init python:
    def jsoncallback(d):
        # whenever a game is saved, also save this name with it
        d["mc_name"] = store.mc

    config.save_json_callbacks.append(jsoncallback)
So in this example the function "jsoncallback" is called by Renpy whenever you save a game. It then adds everything to the JSON dictionary "d" that you define. In our case we add the value of "mc" (which I wrote as store.mc to make sure we're referring to that global variable that contains "Eileen", but you could also just write "mc" as long as you have no local variable with that name inside the function). As the key for the dictionary we just use "mc_name", but we could also name it whatever we want, like "the_key_for_the_dictionary". But this gives us less information on the thing we're loading later.

Alright, so we just saved the MC's name as part of the JSON data that is part of the saved game. We now can access it inside the file_slots screen inside <screens.rpy>

Code: Select all

screen file_slots(title):
    ...
    for i in range(gui.file_slot_cols * gui.file_slot_rows):
        $ slot = i + 1

        $ our_saved_name = FileJson(slot, "mc_name")
        if our_saved_name:
            text "Character name: [our_saved_name]"
So in this example for each slot we try to load a JSON dictionary key of "mc_name". If it exists, we display it for this slot. Otherwise Renpy will return None by default, either because there is no saved game in that slot or the key does not exist. We just use some variable name like "our_saved_name" for that. Renpy will not save it and is not interested in it. Just don't choose a name that is already existing like "mc" to not get confused. It's just some temporary variable we chose.

User avatar
Adabelitoo
Regular
Posts: 86
Joined: Sat Apr 13, 2019 2:32 pm
Contact:

Re: How to show the MC's name and the slot page-number on file slots?

#7 Post by Adabelitoo »

Thanks! It all works now. Is it possible to make it not show "None" (or replace it with " ") when there is no saved game in that slot or the key does not exist? Because this way I have "None" in all empty files.

Lastly, I have managed to remove everything from my empty file except for the game's name (which btw no it won't change, so I am showing it using [config.name!t]). Is it possible to remove/hide that on empty files?

User avatar
m_from_space
Miko-Class Veteran
Posts: 975
Joined: Sun Feb 21, 2021 3:36 am
Contact:

Re: How to show the MC's name and the slot page-number on file slots?

#8 Post by m_from_space »

Adabelitoo wrote: Tue Feb 06, 2024 5:21 pm Thanks! It all works now. Is it possible to make it not show "None" (or replace it with " ") when there is no saved game in that slot or the key does not exist? Because this way I have "None" in all empty files.
It shouldn't show None, when you check that it's not None, like in my example. But another option is just to call FileJson with these parameters:

Code: Select all

$ saved_name = FileJson(slot, "mc_name", empty="", missing="")
This way the function will return an empty string both when there is no saved game and when the key is missing.
Lastly, I have managed to remove everything from my empty file except for the game's name (which btw no it won't change, so I am showing it using [config.name!t]). Is it possible to remove/hide that on empty files?
Yes of course. You just have to determine whether the slot is empty or not. There are different methods, but since by default a file slot will determine the save time and date via FileTime(), this function will return "empty slot" when the slot is empty (or whatever you define as a return value in that case).

Code: Select all

$ filetime = FileTime(slot, format=... , empty=_("empty slot"))

if filetime != "empty slot":
    ...

User avatar
Adabelitoo
Regular
Posts: 86
Joined: Sat Apr 13, 2019 2:32 pm
Contact:

Re: How to show the MC's name and the slot page-number on file slots?

#9 Post by Adabelitoo »

Thanks! It all works now.

Post Reply

Who is online

Users browsing this forum: Google [Bot]