Ren'Py Adding an image after compiling

Nottravis

Sci-fi Smutress
Donor
Game Developer
Jun 3, 2017
5,132
27,280
So, fairly simply, I want to be able to add an image to my game post download for, let's say, bonus reasons.

Simple, right? Now if I didn't compile the chapters it would be, but I can't think of a way that I can get Renpy to access the compiled images plus this other one that's been added later. I know, the easy answer is "Notty, don't compile it" but I feel I have to for the players benefit. Partly due to the suspense angle of my game as it progresses but also due to some of the content as it goes on not being to everyone's tastes. By compiling it, I prevent anyone accidentally seeing either major plot points or seeing content they don't want to.

So, that aside, anyone any idea on how I can get Renpy to access both the compiled images plus this additional one?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
So, that aside, anyone any idea on how I can get Renpy to access both the compiled images plus this additional one?
It's very, very, very complicated because... Ren'py absolutely don't care if the images are in a rpa file or not.


Therefore, just create an "images" folder inside the "[my awesome game]/game" folder where are the "rpa" files, and put your added images inside this folder.
Then use something like in the code to ensure that the file is present.

Therefore, if you add "heavy five/game/images/bonus/becca upskirt.jpg" and "heavy five/game/images/bonus/becca showering.jpg" images for your most generous patrons, you can have this in the code :
Code:
screen game_menu(title, scroll=None):
    [...]

    # Assume that if you added one, then you added the other.
    showIf renpy.loadable( "images/bonus/becca upskirt.jpg" ):
        textbutton "Bonus" action Call( "bonus_section" )
    [...]

label bonus_section:
    [...]
    scene expression "image/bonus/becca upskirt.jpg"
    [...]

You can even use this (minus the renpy.loadable part) to add an image you've forgot when you asked Ren'py to create the distribution file. Or, like normally Ren'py look at the disk first, to change an image that exist in the rpa file.
You forgot to add "becca shower front.jpg" ? Put it in the "game/images/bonus/" folder after the creation of the rpa file, and it will be used by Ren'py.
Or, you messed a little, and "becca upskirt.jpg" is an image where she wear a panty ? Add the correct image in the "game/images/bonus/" folder, still named "becca upskirt.jpg", and it's the one that the player will see.




All this said, I have a sad news for you. A rpa file didn't really reduce the size and don't effectively compress again the image (like an archive would do). It just put them all in a single file, which imply a little reduction of the time needed to load the images ; therefore it's still a good idea to do it, but not for the reasons you thought.
 

Nottravis

Sci-fi Smutress
Donor
Game Developer
Jun 3, 2017
5,132
27,280
It's very, very, very complicated because... Ren'py absolutely don't care if the images are in a rpa file or not.


Therefore, just create an "images" folder inside the "[my awesome game]/game" folder where are the "rpa" files, and put your added images inside this folder.
Then use something like in the code to ensure that the file is present.

Therefore, if you add "heavy five/game/images/bonus/becca upskirt.jpg" and "heavy five/game/images/bonus/becca showering.jpg" images for your most generous patrons, you can have this in the code :
Code:
screen game_menu(title, scroll=None):
    [...]

    # Assume that if you added one, then you added the other.
    showIf renpy.loadable( "images/bonus/becca upskirt.jpg" ):
        textbutton "Bonus" action Call( "bonus_section" )
    [...]

label bonus_section:
    [...]
    scene expression "image/bonus/becca upskirt.jpg"
    [...]

You can even use this (minus the renpy.loadable part) to add an image you've forgot when you asked Ren'py to create the distribution file. Or, like normally Ren'py look at the disk first, to change an image that exist in the rpa file.
You forgot to add "becca shower front.jpg" ? Put it in the "game/images/bonus/" folder after the creation of the rpa file, and it will be used by Ren'py.
Or, you messed a little, and "becca upskirt.jpg" is an image where she wear a panty ? Add the correct image in the "game/images/bonus/" folder, still named "becca upskirt.jpg", and it's the one that the player will see.




All this said, I have a sad news for you. A rpa file didn't really reduce the size and don't effectively compress again the image (like an archive would do). It just put them all in a single file, which imply a little reduction of the time needed to load the images ; therefore it's still a good idea to do it, but not for the reasons you thought.
Holy fuck...

Thank you! Thank you -so- much!

EDIT: Also...a lot of Becca showering examples there I notice! Anything you wish to share? ;)
 
  • Like
Reactions: anne O'nymous

Rich

Old Fart
Modder
Donor
Respected User
Game Developer
Jun 25, 2017
2,566
7,384
It's worth mentioning that this doesn't just apply to images - applies to .rpy or .rpyc files as well - this is how post-distribution patches are typically applied. Essentially, Ren'py can see everything in the game folder, whether it's in an .rpa file or not.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
It's worth mentioning that this doesn't just apply to images - applies to .rpy or .rpyc files as well - this is how post-distribution patches are typically applied.
For the rpy/rpyc files, I recommend to test it at home first, because the order in which the files will be loaded change everything ; and between a file inside a rpa archive and one outside of it, the order isn't always what it can seem.
You also need to distribute the rpyc files, not just the rpy ones, else there's risk to see Ren'py complaining a lot the first time your players will try to launch the game ; but not the second because Ren'py will create the rpyc files while complaining.


But yes :
Essentially, Ren'py can see everything in the game folder, whether it's in an .rpa file or not.
And it's the most important part, because it goes further that what is explicitly say by this sentence.
Indeed, it also imply that you can have an image "images/my game menu.jpg" in the "images.rpa" file, and an image "images/my game menu.jpg" in the "bonus pack.rpa" file ; if my memory don't betray me, for the images it need to be the revert alphabetical order, but try at home first I can be wrong.
Same for a script.rpy file in the "scripts.rpa" file and in the "zzpatch.rpa" file ; here I'm sure, the second archive need to have a name that come later in the alphabetical order.
 
  • Like
Reactions: Nottravis

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,611
2,258
A couple of random thoughts, not based on direct experience... so take all this with a pinch of salt...

As I understand it, files outside an .rpa archive override files within an .rpa archive. So if your "standard" version of the game was all processed within an .rpa archive. Then you had some other files (.rpyc and/or .png/.jpg/etc) unpacked from a zip file into your main game/images folder after the fact... those "extra" files would take precedence. There might be some RenPy voodoo about datetime stamps, etc. But I'm not 100% about that last bit. But...

Where you run into problems distributing all those extra files in something like a bonuscontent.zip download is Android ports of your game. As I understand it, Android renames files to stuff like x-script.rpyc and in so doing causes problems if you are doing renpy.loadable() calls. However, renpy.loadable will also search inside .rpa archives... so...

You could code your options.rpy to create a separate .rpa archive (e.g. bonus.rpa) in addition to your other .rpa archives. So if you're already splitting things up into a scripts.rpa, images.rpa, sounds.rpa, etc. as some games do... just add some extra filters to send all your bonus content into a bonus.rpa archive. Then when you build your game using the RenPy launcher, just remove the bonus.rpa archive from the "standard" version of the game. Obviously you would need to name your files in a way the options.rpy filtering could recognize (Maybe ./bonus/ subfolders ?)

I'm sure there's some clever voodoo which would allow you to build both a standard-PC and bonus-PC distribution at the same time, in the same way you can build PC, MAC, etc. One would include the bonus.rpa, one wouldn't. It would avoid manually removing the bonus.rpa after building - but other than suspecting it's possible... I've no clue how to do it.

You might want to do a single renpy.loadable() as the game is loading and then setting a variable to True or False depending. Better than having lots of renpy.loadble references all over the place. You might want to do an additional check as part of the label after_load: too, if the variable is saved as part of your save files. Just because someone had Patreon access for chapter 1 doesn't mean they will still have Patreon access for chapter 8. Alternatively, have a define bonus_content = False constant as part of a init {n} python: block, then have an almost identical define bonus_content = True within something like a bonus.rpy file that uses a higher priority python init block to override the other definition. That way, if your game is distributed with the bonus.rpy file, the value will be True otherwise false... with no renpy.loadable() checks required.
 
Last edited:
  • Like
Reactions: Nottravis

Nottravis

Sci-fi Smutress
Donor
Game Developer
Jun 3, 2017
5,132
27,280
It's worth mentioning that this doesn't just apply to images - applies to .rpy or .rpyc files as well - this is how post-distribution patches are typically applied. Essentially, Ren'py can see everything in the game folder, whether it's in an .rpa file or not.
For the rpy/rpyc files, I recommend to test it at home first, because the order in which the files will be loaded change everything ; and between a file inside a rpa archive and one outside of it, the order isn't always what it can seem.
You also need to distribute the rpyc files, not just the rpy ones, else there's risk to see Ren'py complaining a lot the first time your players will try to launch the game ; but not the second because Ren'py will create the rpyc files while complaining.


But yes :


And it's the most important part, because it goes further that what is explicitly say by this sentence.
Indeed, it also imply that you can have an image "images/my game menu.jpg" in the "images.rpa" file, and an image "images/my game menu.jpg" in the "bonus pack.rpa" file ; if my memory don't betray me, for the images it need to be the revert alphabetical order, but try at home first I can be wrong.
Same for a script.rpy file in the "scripts.rpa" file and in the "zzpatch.rpa" file ; here I'm sure, the second archive need to have a name that come later in the alphabetical order.
A couple of random thoughts, not based on direct experience... so take all this with a pinch of salt...

As I understand it, files outside an .rpa archive override files within an .rpa archive. So if your "standard" version of the game was all processed within an .rpa archive. Then you had some other files (.rpyc and/or .png/.jpg/etc) unpacked from a zip file into your main game/images folder after the fact... those "extra" files would take precedence. There might be some RenPy voodoo about datetime stamps, etc. But I'm not 100% about that last bit. But...

Where you run into problems distributing all those extra files in something like a bonuscontent.zip download is Android ports of your game. As I understand it, Android renames files to stuff like x-script.rpyc and in so doing causes problems if you are doing renpy.loadable()[/code] calls. However, renpy.loadable will also search inside .rpa archives... so...

You could code your
options.rpy[/icode] to create a separate .rpa archive (e.g. bonus.rpa) in addition to your other .rpa archives. So if you're already splitting things up into a scripts.rpa, images.rpa, sounds.rpa, etc. as some games do... just add some extra filters to send all your bonus content into a bonus.rpa archive. Then when you build your game using the RenPy launcher, just remove the bonus.rpa archive from the "standard" version of the game. Obviously you would need to name your files in a way the options.rpy filtering could recognize (Maybe ./bonus/ subfolders ?)

I'm sure there's some clever voodoo which would allow you to build both a standard-PC and bonus-PC distribution at the same time, in the same way you can build PC, MAC, etc. One would include the bonus.rpa, one wouldn't. It would avoid manually removing the bonus.rpa after building - but other than suspecting it's possible... I've no clue how to do it.

You might want to do a single renpy.loadable()[/code] as the game is loading and then setting a variable to True or False depending. Better than having lots of renpy.loadble references all over the place. You might want to do an additional check as part of the [icode]label after_load: too, if the variable is saved as part of your save files. Just because someone had Patreon access for chapter 1 doesn't mean they will still have Patreon access for chapter 8. Alternatively, have a define bonus_content = False constant as part of a init {n} python: block, then have an almost identical define bonus_content = True within something like a bonus.rpy file that uses a higher priority python init block to override the other definition. That way, if your game is distributed with the bonus.rpy file, the value will be True otherwise false... with no renpy.loadable() checks required.
Guys, thank you all so much for the supplemental here. I really do appreciate it.

What I'm actually trying to achieve is something that, to my mind, is hugely straightforward - but also as far as I'm aware hasn't been done before in a Renpy VN game so you'll forgive me if I'm slightly opaque as to what I'm trying to do - mainly as I want it to be a bit of surprise :)

I'll take some time to digest and, as you all suggest, test what I come up with. Coding is not my area of expertise so I am -very- grateful for the assist.

Thanks :)
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
Coding is not my area of expertise so I am -very- grateful for the assist.
You know, when you take a deeper look at all the abandoned games, half of them end like this because their author didn't achieved to do what they wanted... and they were far to have something like your VR mini-game. I mean, as simple as it can be for people of experience, even this was too much for them, and you, you did it ! You even found a way to fix the little error you made ; an error due only of a lack of knowledge at this time.
Alright, coding isn't your area of expertise, but your far to be as bad as you think, and you've the community to help you if needed. You're also stubborn, which here is a quality because you try until you find a way, and you aren't afraid to ask, which is something missing to too many devs.
But what is more important, you have a creative mind. And it's something that really make a difference when you write code, especially with Ren'py where there's many way to do things. You don't write it "like it should" ? Who cares ? Not me, not your players, because at the end it works, and that the only thing that mater.

So continue (and don't forget that Chris asked to appear in the next edition of Bored Pilot ; I assure you, I heard her :p).
 
  • Like
Reactions: lancelotdulak

lancelotdulak

Active Member
Nov 7, 2018
556
557
Im glad you came and asked.. and actually got good advice. And i know you spend the VAST majority of your time on graphics. (the sheer time cgi takes and the volume of what you have to learn is still blowing me away).

To do this every programmer who saw this thought "just dump them all in a folder and have a routine to autoread the filenames in that folder and sort them by whatever"... the reason im saying this.. you should consider spending a little time learning basic programming better. The simple stuff. You can do it in python .. id suggest something like visualbasic, perl or python. Just decide to do something basic like this. Im pretty sure if you had come at this from the mindset of "i want to write a tiny routine to do this" instead of "im trying to get my game done i just need to find something to do this" (which i TOTALLY understand man!) youd have done this quicly and learned a lot. Again.. this is just friendly advice to a dev who seems to actually care and i want the few good devs to succeed and thrive
 

Nottravis

Sci-fi Smutress
Donor
Game Developer
Jun 3, 2017
5,132
27,280
I mean, as simple as it can be for people of experience, even this was too much for them, and you, you did it !
Ah but I have an advantage!

Because I find all coding hard, I've no idea what's meant to be difficult or not! :D So I never have a difficulty curve and somehow blindly get things done which, I suppose, as a first timer with no experience I shouldn't even be attempting *uses her lack of knowledge to good effect* ;)

And i know you spend the VAST majority of your time on graphics. (the sheer time cgi takes and the volume of what you have to learn is still blowing me away).
Oh God, don't remind me! XD It's been so long since I actually wrote anything I might have forgotten how! Although, partly that is my fault for trying to make a game as big as H5 on a 1060 card. I don't recommend it!

"im trying to get my game done i just need to find something to do this"
You know me suspiciously well! :)

Again.. this is just friendly advice to a dev who seems to actually care and i want the few good devs to succeed and thrive
And taken. I'm in the process of doing a huge remaster at the moment as I suddenly seem to be able "to daz" properly. But post that....yeah. A more methodical approach other than "Let's write some code!" is probably in order :)

So continue (and don't forget that Chris asked to appear in the next edition of Bored Pilot ; I assure you, I heard her :p).
*slips into his DM...*
 
  • Like
Reactions: anne O'nymous

lancelotdulak

Active Member
Nov 7, 2018
556
557
Oh God, don't remind me! XD It's been so long since I actually wrote anything I might have forgotten how! Although, partly that is my fault for trying to make a game as big as H5 on a 1060 card. I don't recommend it!
You should check out my post on octane. It is currently literally blowing my mind....
And.. check out unity sometime..
 
  • Like
Reactions: Nottravis