Ren'Py Some way to run a function every time a save is loaded?

Sakrilas

Just Another Member
Game Developer
Oct 26, 2017
363
2,654
Hey there, everyone.
Is there anyway I have a piece of code be guaranteed to run every time a save is loaded in Renpy?

I tried looking for life cycle hooks, but had no luck with it.

Any kind of assistance would be appreciated.
 

LightmanP

Well-Known Member
Modder
Game Developer
Oct 5, 2020
1,750
16,558
I think you can use the after_load label for that -
 
  • Heart
Reactions: Sakrilas

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,611
2,258
Just keep in mind that label will be called EVERY time a save file is loaded.

It's very easy to forget that whatever you do there will continue to be executed long, long into the future.

People tend to use label after_load: to "fix" stuff (like the values of variables) they screwed up in a previous release of the game.

Maybe ep2_saw_mom_in_shower wasn't set correctly during episode 2, so you're correcting it in ep3... But HOW you correct it matters, since that "fix" is still going to be run for not only those broken save files, but perfectly fine save files for ep8, 11 and onward. Not only that, it's also going to be run for players just (re-)starting the game during ep1.

Maybe you're doing something else, so it's not an issue.
All I'm saying is think through all the various combinations - or it'll come back to bite you in the ass.
 
  • Like
Reactions: Sakrilas

Sakrilas

Just Another Member
Game Developer
Oct 26, 2017
363
2,654
Just keep in mind that label will be called EVERY time a save file is loaded.

It's very easy to forget that whatever you do there will continue to be executed long, long into the future.

People tend to use label after_load: to "fix" stuff (like the values of variables) they screwed up in a previous release of the game.

Maybe ep2_saw_mom_in_shower wasn't set correctly during episode 2, so you're correcting it in ep3... But HOW you correct it matters, since that "fix" is still going to be run for not only those broken save files, but perfectly fine save files for ep8, 11 and onward. Not only that, it's also going to be run for players just (re-)starting the game during ep1.

Maybe you're doing something else, so it's not an issue.
All I'm saying is think through all the various combinations - or it'll come back to bite you in the ass.
I'm using it to make some sort of "computed property".

Here's what I'm doing with it.
I have a file called "state.rpy" where I keep track of flags for the game.

1624133592402.png

I don't think this will cause problems to me in the future. Will it?

I'm doing this just for the sake of increasing readability of my code base.


Seeing in the script:
Python:
if professor_saw_caseys_porn_site:
    professor "Casey, blablsbla porn site, blabla"
Reads better than:

Python:
if casey_refused_to_run_naked_at_first:
    professor "Casey, blablsbla porn site, blabla"
But both scripts would behave the same, because those 2 booleans go hand and hand.
You know what I mean?

Is this a bad practice?
 
Last edited:

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,611
2,258
I don't think this will cause problems to me in the future. Will it?

No clue. It looks safe enough. But then, how could I tell.

I'm doing this just for the sake of increasing readability of my code base.

Yeah. I can see you're aiming to simplify your variables.

My question would be why you would need to refresh them using after_load:?

I presume (always a bad idea) you regularly call calculate_derivative_variables. Either at some key point in the code (a sort of central hub or hubs) or after you've updated any variable which could contribute toward your derived variables.

Therefore the derived variables will always be up to date.

But if they're already up to date, then there's no need to update them during after_load.

Therefore, if after_load is necessary, it's because the values of the derived variables are not in line with their contributing variables - presumably because you're not calling calculate_derivative_variables often enough. Either that, or the variables are all fine and you're doing the whole label after_load: for no reason.

Or put another way... Would your game still work if a player never loaded a save file... Just played from beginning to end in one session, without ever quitting the game? Because if the answer is yes, I'm not sure why the after_load is needed.

At best, we could say it's doing no harm. Just setting values that were already set correctly anyway.
At worst, it could be masking a more fundamental underlying problem.

Pardon my skepticism, I'm just being cautious.

Is this a bad practice?

If it works... it's fine.
Seriously, RenPy is as simple or complex as you want it to be.
There will always be people who say something can be done better or refined or whatever... but if it works... it's fine.

What matters more is that YOU understand your own code.
If you were part of a team, it might matter... since you'd all need to be on the same page. But a one-man project... whatever works for you.
 

Sakrilas

Just Another Member
Game Developer
Oct 26, 2017
363
2,654
No clue. It looks safe enough. But then, how could I tell.




Yeah. I can see you're aiming to simplify your variables.

My question would be why you would need to refresh them using after_load:?

I presume (always a bad idea) you regularly call calculate_derivative_variables. Either at some key point in the code (a sort of central hub or hubs) or after you've updated any variable which could contribute toward your derived variables.

Therefore the derived variables will always be up to date.

But if they're already up to date, then there's no need to update them during after_load.

Therefore, if after_load is necessary, it's because the values of the derived variables are not in line with their contributing variables - presumably because you're not calling calculate_derivative_variables often enough. Either that, or the variables are all fine and you're doing the whole label after_load: for no reason.

Or put another way... Would your game still work if a player never loaded a save file... Just played from beginning to end in one session, without ever quitting the game? Because if the answer is yes, I'm not sure why the after_load is needed.

At best, we could say it's doing no harm. Just setting values that were already set correctly anyway.
At worst, it could be masking a more fundamental underlying problem.

Pardon my skepticism, I'm just being cautious.




If it works... it's fine.
Seriously, RenPy is as simple or complex as you want it to be.
There will always be people who say something can be done better or refined or whatever... but if it works... it's fine.

What matters more is that YOU understand your own code.
If you were part of a team, it might matter... since you'd all need to be on the same page. But a one-man project... whatever works for you.
I only call it on loads. I don't need to refresh them any other time.

My idea behind this is that I can freely go back and add "derivative variables" anywhere in the previous days that already exist in the game knowing that nothing is going to break for players that are continuing their saves.

The game can still be played from beginning to end without loads because I still set the derivative variables as needed in the regular execution.

1624163129812.png

But you see, if I do decide that "student_list_received_caseys_trail_nudes_with_no_face" is a bad variable, I can now just remove or edit it from the code, knowing that the state is not going to break for people that have saves in the future.

This means that on each day I no longer need to guess which derivative consequences are important to keep track in variables.

Now the only "dangerous to change" variables are the base ones. But these are a very selective few.
1624163635913.png

I'm hoping this will make my life easier, or at the very least, I'm hoping I'm not shooting myself in the foot. Hahah
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
I don't think this will cause problems to me in the future. Will it?
So far it's just bool assignation, so yes, it's safe.
You don't effectively change a value, but compute it according for formulas that are frozen in time. What mean that the result of the said computation will also be frozen.


I'm doing this just for the sake of increasing readability of my code base.
Readability isn't the only thing you should take in count, you code should also be easy to write, and I have some doubts due to the really big size of your flags' name.
It doesn't meant that I'm right to have doubts, it can be perfect for you since here it depend solely of your own abilities. But I know from experience that the longer and more explicit are the variable name, the more people tend to in fact forget them and/or make typo when writing them. Especially when there's in the end so many that are just aliases of a base flag.


That something like student_list_received_caseys_trail_nudes_with_no_face is easier to understand don't make doubt.
But if, in few months, you'll need to use it again, will your remember that it's the "student_list" and not the "students_list" ? Will you remember that it's the "trail_nudes" and not just the "nudes" ? Will you remember that you specified that they were "with_no_face" and not that it was implied ?
Because if your efforts to increase the readability lead you to write

if students_list_received_caseys_nudes:
[...]

then it will have in fact just broke your game.
And if it imply that, each time you need to write a flag name, you've first to pass through the list of flags' name in order to validate that you write it correctly, then it will make you lost times and make the writing of your code feel a little more like a burden.

But, as I said above, this are just my doubts. I'm not you, therefore perhaps that for you all this is effectively really explicit, and also really easy to remember and to use. And if it's the case, they I've nothing to say, go with it.
 
  • Like
Reactions: Sakrilas

Sakrilas

Just Another Member
Game Developer
Oct 26, 2017
363
2,654
So far it's just bool assignation, so yes, it's safe.
You don't effectively change a value, but compute it according for formulas that are frozen in time. What mean that the result of the said computation will also be frozen.




Readability isn't the only thing you should take in count, you code should also be easy to write, and I have some doubts due to the really big size of your flags' name.
It doesn't meant that I'm right to have doubts, it can be perfect for you since here it depend solely of your own abilities. But I know from experience that the longer and more explicit are the variable name, the more people tend to in fact forget them and/or make typo when writing them. Especially when there's in the end so many that are just aliases of a base flag.


That something like student_list_received_caseys_trail_nudes_with_no_face is easier to understand don't make doubt.
But if, in few months, you'll need to use it again, will your remember that it's the "student_list" and not the "students_list" ? Will you remember that it's the "trail_nudes" and not just the "nudes" ? Will you remember that you specified that they were "with_no_face" and not that it was implied ?
Because if your efforts to increase the readability lead you to write

if students_list_received_caseys_nudes:
[...]

then it will have in fact just broke your game.
And if it imply that, each time you need to write a flag name, you've first to pass through the list of flags' name in order to validate that you write it correctly, then it will make you lost times and make the writing of your code feel a little more like a burden.

But, as I said above, this are just my doubts. I'm not you, therefore perhaps that for you all this is effectively really explicit, and also really easy to remember and to use. And if it's the case, they I've nothing to say, go with it.
That's a fair point, but I usually rely on the IDE's intellisense to autocomplete my typing.

So in the "student_list_received_caseys_trail_nudes_with_no_face" example, I just need to remember that the variable had "student" in it.

1624206656549.png

Or "nude":

1624207230131.png

I see what you're saying though, if I didn't have intellisense on my text editor, it would be a pain to keep track of those names.
 
Last edited: