Renpy meta-tools

FlipTopBin

Member
Game Developer
Dec 5, 2017
176
222
I have been looking at other peoples code and I continue to see VNs with code which looks like this:

Code:
                        hide r2_236
                        show r2_233
                        with dissolve
                        s "\" Don't you like it?\""
                        p "\" I didn't say that.\""
                        scene sandrablow2 animated with fade:
                                "2/237.webp" with dissolve
                                pause 0.8
                                "2/238.webp" with dissolve
                                pause 0.8
                                repeat
What I am interested in here is coding of names for the images (r2_233, 237.webp, etc) Are other Devs just a lot more organised than me or are they using some content management tool to generate all the names and keep track of the images?
 

Palanto

Active Member
Game Developer
Oct 4, 2017
964
1,841
Weeellll first of all renpy has . So basically the "renpy defined name" usually is from the images folder -> subdirectory name -> name of image without .extension usually ren'py already takes those apart without / for folders or anything so lets say I have a folder called v1 in the images folder and inside this v1 folder there's an image called scene01_image01.png renpy would split all this instead of /v1/scene01_image01.png it would just be scene v1 scene01 image01
with dissolve

i.e.

But I personally like to define my images in a seperate file so that I can use auto completion in atom for those scenes without always checking if the image existed or not, it will just list all the images that are there and so on.

For this I create a really little .bat file which takes all new images I get from the creator, and puts them defined in a textfile..... Well here's an example of how my image definitions look in my game (so I can use their names instead of the folder structure and so on) :
Code:
################## SHARED IMAGES ################################

image openback = "/shared/backgrounds/openbackground.png"
image gameover = "/shared/backgrounds/badending1.png"
image meanwhile = "/shared/backgrounds/meanwhile.png"
image elsewhere = "/shared/backgrounds/elsewhere.png"
image hoursb4 = "/shared/backgrounds/hoursb4.png"
image tobecontinued = "/shared/backgrounds/2bcontinued.png"
image support = "/shared/backgrounds/support.png"
image thoughts = "/shared/backgrounds/thoughtpower.png"
image warning = "shared/backgrounds/_warning.png"
image sometimelater = "shared/backgrounds/sometimelater.png"
image shorttimeafter = "shared/backgrounds/shorttimeafter.png"
image saveStatsBG = "shared/backgrounds/saveStats.png"

################## Credits & Ads #################################

image cpt06p1_credits01 = "/credits/cpt06p1_credits01.png"
image cpt06p1_credits02 = "/credits/cpt06p1_credits02.png"

################## Side Images for the whole Game #########################

        ########## Lynara ###########

                ### Lace Bodice ###
                    # Afraid #
image side lynara blace afraid01 = im.Scale("/sides/lynara/lynara_blace/afraid/afraid_01.png", 345, 460)
image side lynara blace afraid02 = im.Scale("/sides/lynara/lynara_blace/afraid/afraid_02.png", 345, 460)
image side lynara blace afraid03 = im.Scale("/sides/lynara/lynara_blace/afraid/afraid_03.png", 345, 460)

*snip*

# Define main images for chapter five part 02 #
image cpt05p2_000 = "/chapter_five_part02/cpt05p2_000.png"
image cpt05p2_000a = "/chapter_five_part02/cpt05p2_000b.png"

image cpt05p2_000b:
    "/chapter_five_part02/cpt05p2_000b.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000c.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000d.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000e.png" with dissolve
    3.0
    "/chapter_five_part02/cpt05p2_000f.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000g.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000h.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000i.png" with dissolve
    0.5

image cpt05p2_001a = "/chapter_five_part02/cpt05p2_001a.png"
image cpt05p2_001b = "/chapter_five_part02/cpt05p2_001b.png"
image cpt05p2_002a = "/chapter_five_part02/cpt05p2_002a.png"
image cpt05p2_002b = "/chapter_five_part02/cpt05p2_002b.png"
So as you can see, the last image would be auto defined (can be setup as much as you want so that it actually auto defines them like I named them... but then they wouldn't show up in the Lint logfile ;) ) as:
"chapter five part02 cpt05p2 002b"
So instead I just named it cpt05p2_002b

And since all "scene" images got called just like that (file name without extension) I made a little batch script that would search through the folder and all subfolders it is in an would just write for every .png it finds:
image imageNameWithoutExtension = "/folderName/fileNameWithExtension"

then it prints it into a .txt file which I can just copy paste into my .rpy file and tadaaa done.
 

Elementario

Member
Game Developer
Nov 11, 2017
252
312
Weeellll first of all renpy has . So basically the "renpy defined name" usually is from the images folder -> subdirectory name -> name of image without .extension usually ren'py already takes those apart without / for folders or anything so lets say I have a folder called v1 in the images folder and inside this v1 folder there's an image called scene01_image01.png renpy would split all this instead of /v1/scene01_image01.png it would just be scene v1 scene01 image01
with dissolve

i.e.

But I personally like to define my images in a seperate file so that I can use auto completion in atom for those scenes without always checking if the image existed or not, it will just list all the images that are there and so on.

For this I create a really little .bat file which takes all new images I get from the creator, and puts them defined in a textfile..... Well here's an example of how my image definitions look in my game (so I can use their names instead of the folder structure and so on) :
Code:
################## SHARED IMAGES ################################

image openback = "/shared/backgrounds/openbackground.png"
image gameover = "/shared/backgrounds/badending1.png"
image meanwhile = "/shared/backgrounds/meanwhile.png"
image elsewhere = "/shared/backgrounds/elsewhere.png"
image hoursb4 = "/shared/backgrounds/hoursb4.png"
image tobecontinued = "/shared/backgrounds/2bcontinued.png"
image support = "/shared/backgrounds/support.png"
image thoughts = "/shared/backgrounds/thoughtpower.png"
image warning = "shared/backgrounds/_warning.png"
image sometimelater = "shared/backgrounds/sometimelater.png"
image shorttimeafter = "shared/backgrounds/shorttimeafter.png"
image saveStatsBG = "shared/backgrounds/saveStats.png"

################## Credits & Ads #################################

image cpt06p1_credits01 = "/credits/cpt06p1_credits01.png"
image cpt06p1_credits02 = "/credits/cpt06p1_credits02.png"

################## Side Images for the whole Game #########################

        ########## Lynara ###########

                ### Lace Bodice ###
                    # Afraid #
image side lynara blace afraid01 = im.Scale("/sides/lynara/lynara_blace/afraid/afraid_01.png", 345, 460)
image side lynara blace afraid02 = im.Scale("/sides/lynara/lynara_blace/afraid/afraid_02.png", 345, 460)
image side lynara blace afraid03 = im.Scale("/sides/lynara/lynara_blace/afraid/afraid_03.png", 345, 460)

*snip*

# Define main images for chapter five part 02 #
image cpt05p2_000 = "/chapter_five_part02/cpt05p2_000.png"
image cpt05p2_000a = "/chapter_five_part02/cpt05p2_000b.png"

image cpt05p2_000b:
    "/chapter_five_part02/cpt05p2_000b.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000c.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000d.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000e.png" with dissolve
    3.0
    "/chapter_five_part02/cpt05p2_000f.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000g.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000h.png" with dissolve
    0.5
    "/chapter_five_part02/cpt05p2_000i.png" with dissolve
    0.5

image cpt05p2_001a = "/chapter_five_part02/cpt05p2_001a.png"
image cpt05p2_001b = "/chapter_five_part02/cpt05p2_001b.png"
image cpt05p2_002a = "/chapter_five_part02/cpt05p2_002a.png"
image cpt05p2_002b = "/chapter_five_part02/cpt05p2_002b.png"
So as you can see, the last image would be auto defined (can be setup as much as you want so that it actually auto defines them like I named them... but then they wouldn't show up in the Lint logfile ;) ) as:
"chapter five part02 cpt05p2 002b"
So instead I just named it cpt05p2_002b

And since all "scene" images got called just like that (file name without extension) I made a little batch script that would search through the folder and all subfolders it is in an would just write for every .png it finds:
image imageNameWithoutExtension = "/folderName/fileNameWithExtension"

then it prints it into a .txt file which I can just copy paste into my .rpy file and tadaaa done.
Thanks for the detailed explanation.
I am still new to all this stuff and trying to understand how things work
I should go to Ren'Py Documentation and try to get a better understanding of this
Anyway, thanks again
 

FlipTopBin

Member
Game Developer
Dec 5, 2017
176
222
Thanks for replying @Palanto but you may have missed my original point.

I am areasonably competant Renpy developer and I know how to deal with images. I used to pre-define all my images like you but sick of the admin overhead in the end.

What I am trying to work out is how other developers keep their image names so uniform. For instance, in the example code I pasted the Dev uses the format: r2_236 and r2_233 which I would imagine means Release 2 image number 236 and 233.

Now, with the best will in the world, nobody is going to remember what image 236 is when writing their code. They will either have to look at all the images they rendered to pick the right one or have some kind of index which relates image 236 to a more human friendly description. I am assuming the latter.

So, my question is: How do people keep track of all their images and their encoded names? Do they just write them down on a pad of paper? Do they in fact just look at all the renders they made and try and pick the correct one? Or are people using some kind image library software to keep track of all this stuff?

I my code, I write the story first and use code like:

Code:
    scene restaurant_chris_laughs_at_sophie
    c "That reminds me of a drinking game I used to play. You have to make a statement and end it with 'if you know what I mean.' to make it sound rude."
    c "When somebody can't think of one or what they say isn't rude enough then they have to down a drink."
    s "I don't get it."
    c "Well, you would have said something like: You can't beat a nice battered sausage, if you know what I mean! *wink*"
    scene restaurant_sophie_shocked
Then I go and render all the images I need for the scene using the name as a prompt for what I need to include in the image and lint to remind me which ones I have missed. If you write your story using image names like r2_236 then you have to read all the text again to work out what needs to be included in the image. Do people really do this? Perhaps they story board everything first so they know the images needed before the code and text gets written?

This is what I am trying to understand: how people cope with the complexity of games with thousands of images all with very very dull names.
 

Palanto

Active Member
Game Developer
Oct 4, 2017
964
1,841
Ahhh alright, well there are a lot of possible ways to do it, one of the ways a lot of developers do it is exactly like you do it. Others like @ASLPro3D i.e. work a little more general, keeping in mind that another person has to code all of it so they prepare the whole chapters/versions/whatevers dialogue and scenes in i.e. a twine file, adding the image names to the scene.

It all depends on how you think. Some people can keep all the scenes in mind and might even know what r2_233 is without having to look at it. I wouldn't be able to though ;) So either I'd do it like you (or a little different, I'd just call the images by numbers and add a comment above the scene call so I know in a short way what has to be inside the scene) or I'd write it in a twine file even if nobody else would have to read it, the second option is far more organized but also means you're going to write all your dialogues and so on in a seperate file and copy paste it back to your real .rpy files (if you write it in code inside the twine file you don't even have to change anything then ;) )

I'd probably go from scene to scene then, meaning I'd write a whole scene from begining to the end, then I'd set up the scene in DAZ and make sure that everything I thought of is even possible in a render, if not I'd check how far I could go and then rewrite the scene a little to make it fit again. When I'm done with the scene setup I'd usually have the number of images that scene needs. So I can write the imagenumber into the twine file. Then I'd continue with writing the next scene, in the meantime the images from the last scene can be rendered.

But it's all kind of what you prefer, so it's a matter of taste in a way.
Most important is that YOU know what is where, not that somebody else can read it (at least if you're working alone)
If writing the whole update and then rendering is easier for you then the chosen approach is probably the best way to do it. At least I can't come up with an idea of how to do it differently or more ordered ;) Except, maybe calling the scenes like you do, then when you've rendered the image, replace the scene call with another one that just holds the image number, i.e. change:

Code:
   scene restaurant_chris_laughs_at_sophie
   c "That reminds me of a drinking game I used to play. You have to make a statement and end it with 'if you know what I mean.' to make it sound rude."
   c "When somebody can't think of one or what they say isn't rude enough then they have to down a drink."
   s "I don't get it."
   c "Well, you would have said something like: You can't beat a nice battered sausage, if you know what I mean! *wink*"
   scene restaurant_sophie_shocked
when the images are done to:

Code:
   scene r01 001
   c "That reminds me of a drinking game I used to play. You have to make a statement and end it with 'if you know what I mean.' to make it sound rude."
   c "When somebody can't think of one or what they say isn't rude enough then they have to down a drink."
   s "I don't get it."
   c "Well, you would have said something like: You can't beat a nice battered sausage, if you know what I mean! *wink*"
   scene r01 002
something like that. This way you'd end up with a cleaner file list later (to find the right scene file if you want to check something or swap it with something else or whatever) and would have it like any other game creator.

But like I said, most important is that you know what is what and where it has to be in the end ;)
 

Palanto

Active Member
Game Developer
Oct 4, 2017
964
1,841
Another way is to sort it by folders...
You can create milions of folders in your game/images/ directory
i.e. game/images/day01/restaurant/scene01/image01.ext
Of course you'd always need to have the scene itself in your head (or on a small sheet) to make sure you have all the stuff inside the image that you described in the dialogue/narration ;) But I for one would go with a mix of several things ;)

  • Twine file (really easy to use and really powerful for branching stories)
  • images sorted by folders (makes it generally easier to find all the images to the depending scenes and so on)
  • comments above the scene calls (if the image isn't finished I'd usually get the line of code in the Lint file which I can search for with ctrl+G in atom ;) )
  • maybe do it like you until the image is done and then renaming the image call so that it gets the real image instead of a description of what should be inside the render
 

FlipTopBin

Member
Game Developer
Dec 5, 2017
176
222
Thanks for that @Palanto, really I was was just worried I was missing out on some fabulous content management system for Renpy but obviously not :) So, I'll stick with what works for me for now. I may have to investigate Twine though as many people speak highly of it.
 
  • Like
Reactions: Palanto

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,620
15,601
What I am trying to work out is how other developers keep their image names so uniform.
To the wonderful answers gave by @Palanto, I would have one thing that you've apparently missed: laziness.

Whatever if it's "r2_236" like in your example, "1245", "c117" or other things like this, the name generally come from the desire to not deal with names. You found more or less the same thing in Palanto's "cpt05p2_002b". But in a more advanced way, since he use a real structure, even if he prefer to use numbers in place of words.
It's just easier for these devs to deal with the 236th picture of what is (I assume) the second release, so "r2_236", than having to find a name for (pure hypothesis) "the scene in the kitchen when the youngest roommate/sister is pleased because you just said a compliment to her and it's the first time in years that you are gentle with her".
 
  • Like
Reactions: Palanto and bas

FlipTopBin

Member
Game Developer
Dec 5, 2017
176
222
Hmmm, you may be right. Programmers do tend towards logic and numbers and Zzzzzzzzzz

I like words:
Code:
    scene kitchen_sister_suck_cock
is so much more fun than
Code:
    scene r2_236
 

ASLPro3D

Engaged Member
Donor
Game Developer
Sep 16, 2017
3,439
11,334
You should design the game the way that you feel best comfortable doing @FlipTopBin or the way that you enjoy.

I will say, after doing "Wicked Choices: Book One" with @Palanto that it was just easier for me to name our images like: "cpt4p5_214" because when you get to doing nearly 4,000 images like we did in our game, you run out of clever little image descriptions like: "trog_with_big_dick_fucks_angelion_girl_one".

I am not a programmer, but I still like consecutive order and neat file structure... makes it easier for a supporter to say: "Hey, I noticed in my game, that image 'cpt05p2_044.png' isn't linked properly in this release, you might want to check it out..." instead of "Hey, I noticed in my game, that image 'uncle_taking_it_up_the_ass_by_mother-in-law' isn't linked properly in this release, you might want to check it out..." which is a bitch more for a supporter to type and report.

Also, last thing you want is to have a Patron on your Patreon Page, publicly tell you: "Image 'little_sister_sucking_brothers_cock_kitchen.png' isn't showing up..." which would draw a flag to your page on Patreon which uses 'spiders' to search for specific keywords that would get your page shut down. ;)

Sometimes just using numbers is better... also works easier in Twine when you start working with someone else.
 

Palanto

Active Member
Game Developer
Oct 4, 2017
964
1,841
Thanks to everybody who contributed here. Looks like I need to download Twine ...
It's also great to outline your story and branches with it, you can see on one glance what has to be done where (programming wise like if else statements or menus and so on) It can even be used to create games if you'd wanted to ;) But we're just using it as a workflow and outlining tool including all scenes in seperate blocks so I can go into them and copy the dialogue, the image names and paste it into the code ;)
 
  • Like
Reactions: ASLPro3D