Ren'Py Extracting folder names from paths [solved]

Lou111

Active Member
Jun 2, 2018
543
686
I know its possible with some kind of formatting function but I can't find it!

I have a character folder in my image directory. I want to use this directory as a suedo "character list". Meaning if I add a folder here, I then add a character to the game.

images/characters/female/blonde/Name/etc/etc/etc

I want to isolate the folder: Name
and append the character name to a character list.

I know I will probably have to use .startswith("images/characters/female/blonde/") but there are a lot of different parameters leading up to the character name and am hoping also for a more simple/cleaner function. If anyone has an alternative way to apply common attributes like hair color using folder names that would be fantastic.

Thanks in advance!
 

Lou111

Active Member
Jun 2, 2018
543
686
Thanks to xcrash and the code from Brothel King
Here's what I came up with:

Python:
python:
    def list_characters():

        temp_list = []

        for f in renpy.list_files():
            if f.endswith("rest.png"):
                folders = f.split("/")
                temp_list.append(folders[5])

        return temp_list
I wasn't sure how to just say "From this folder"
So I found a file name that was common to all characters (a required side-image named: "Name rest.png")


This function feels a bit crude to me and would like to get a second opinion on this.
I would like to avoid having to rely on using the .png here.
 

Lou111

Active Member
Jun 2, 2018
543
686
I don't know that these folks can or will help you but I am going to tag 79flavors and anne O'nymous. They are the people I feel like are go-to Ren'py experts here.
Hah!
I try to make my posts sound like I'm talking talking to them :ROFLMAO:


This function suits my purposes for now.
I can even use this self-same function to assign their attributes using the sub folder categories.
Something feels off about it to me though, my tiger senses are telling me I'm overlooking something that will hurt my code later. Also, relying on that .png file just feels outright barbaric.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
Something feels off about it to me though, my tiger senses are telling me I'm overlooking something that will hurt my code later.

Good tiger senses, keep your tiger senses ;)
It will not really hurt your code, but it's effectively way too much works for something really simple. In fact, all come from your premise, "extracting folder names".

Let's say that you want to talk to all the people working for the accounting. You'll not ask all the employees of the society to assemble, then take them one by one, keeping them only if the answer "yes" to your "do you works for the accounting ?"
It would be way better to directly go where the accounting service is, and ask people there to listen, if they effectively work here.

It's exactly the same here.
Why searching to extract the name from a path, when you can simply go to the base path and look at the directories located there ?


Also, relying on that .png file just feels outright barbaric.
It's also dangerous. One day you'll forgot that you filter with the extension, and wonder why your marvelous .jpg files aren't used.

In the end, what you want is something like that :
Python:
init python:

    def initGirlsList():
        tmpList = []
        # Base directory is "[...]game/images/characters/female/".
        workingDir = renpy.os.path.join( config.gamedir, "images", "characters", "female"  )

        # Browse all files.
        for file in renpy.os.listdir( workingDir ):
            # Keep only the directories.
            if not renpy.os.path.isdir( renpy.os.path.join( workingDir, file ) ):
                continue
            # Store them.
            tmpList.append( file )

        return tmpList

# Mandatory use of /define/ here, the list MUST NOT be saved.
define girlList = initGirlsList()
I need to insist on the use of define, because if the list is saved, your game will be broken.
In this case, Ren'py will generate the list of girls, then load the save file and overwrite this list by the list of girls that existed when the save was made. At best, there will be girls missing, the player will just have less content. At worst, there will be girls that don't exist anymore, and the game will crash trying to address them.

This can be fixed with after_load, but why fix the consequence, when you can avoid the cause ?
define the list, don't change it during the play, and everything will works smoothly.
 

Lou111

Active Member
Jun 2, 2018
543
686
Good tiger senses, keep your tiger senses ;)
It will not really hurt your code, but it's effectively way too much works for something really simple. In fact, all come from your premise, "extracting folder names".

Let's say that you want to talk to all the people working for the accounting. You'll not ask all the employees of the society to assemble, then take them one by one, keeping them only if the answer "yes" to your "do you works for the accounting ?"
It would be way better to directly go where the accounting service is, and ask people there to listen, if they effectively work here.

It's exactly the same here.
Why searching to extract the name from a path, when you can simply go to the base path and look at the directories located there ?




It's also dangerous. One day you'll forgot that you filter with the extension, and wonder why your marvelous .jpg files aren't used.

In the end, what you want is something like that :
Python:
init python:

    def initGirlsList():
        tmpList = []
        # Base directory is "[...]game/images/characters/female/".
        workingDir = renpy.os.path.join( config.gamedir, "images", "characters", "female"  )

        # Browse all files.
        for file in renpy.os.listdir( workingDir ):
            # Keep only the directories.
            if not renpy.os.path.isdir( renpy.os.path.join( workingDir, file ) ):
                continue
            # Store them.
            tmpList.append( file )

        return tmpList

# Mandatory use of /define/ here, the list MUST NOT be saved.
define girlList = initGirlsList()
I need to insist on the use of define, because if the list is saved, your game will be broken.
In this case, Ren'py will generate the list of girls, then load the save file and overwrite this list by the list of girls that existed when the save was made. At best, there will be girls missing, the player will just have less content. At worst, there will be girls that don't exist anymore, and the game will crash trying to address them.

This can be fixed with after_load, but why fix the consequence, when you can avoid the cause ?
define the list, don't change it during the play, and everything will works smoothly.
May the Gods bless you my friend. Thank you!

I would like to add that you also explained something I desperately needed to know about defining variables!
 
Last edited: