python callbacks for saving and loading

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.
Message
Author
ChesStrategy
Regular
Posts: 96
Joined: Wed Jan 14, 2015 7:01 pm
Contact:

python callbacks for saving and loading

#1 Post by ChesStrategy »

Hi all,

Are there any python callback functions that we can override so that we can guarantee certain python commands are run before/after saving and loading?

Regards,
ChesStrategy

User avatar
deliciumartis
Regular
Posts: 30
Joined: Mon Feb 09, 2015 11:32 am
Location: shadowland
Contact:

Re: python callbacks for saving and loading

#2 Post by deliciumartis »

You could make the changes you want to the screen save(): and screen load(): sections of the screens.rpy file. Write in whatever python you need before the menu calls and it would run before your player gets to save or load a game if that's what you're after.
"What bothers me is, nothin' does."
--The dixie flatline

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: python callbacks for saving and loading

#3 Post by xela »

Screen is an option but not a very good one because screens are predicted and save/load screens are often within prediction range.

I don't know of a callback that happens before every save other than the one writing to json...
Like what we're doing? Support us at:
Image

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: python callbacks for saving and loading

#4 Post by trooper6 »

Maybe whatever function the OP wants to do could be added to the save and load buttons?
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: python callbacks for saving and loading

#5 Post by xela »

trooper6 wrote:Maybe whatever function the OP wants to do could be added to the save and load buttons?
Yeap but that may not work for auto-saves. What OP asked for is a callback before every save, I don't know of any without obvious stuff like overriding default saving process except for the json callback.
Like what we're doing? Support us at:
Image

User avatar
PyTom
Ren'Py Creator
Posts: 16096
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: python callbacks for saving and loading

#6 Post by PyTom »

There is label after_load, that is called after loading.

The only save callback is the json one. What's the use case? It seems weird to save something that isn't the current state of the game.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

ChesStrategy
Regular
Posts: 96
Joined: Wed Jan 14, 2015 7:01 pm
Contact:

Re: python callbacks for saving and loading

#7 Post by ChesStrategy »

Hi all,

Thanks for the responses/workarounds. I think this question is stemming from the fact that I don't fully understand the current save/rollback system and I want to structure my code in a way such that I only save certain things.

Based on the Ren'py Documentation:
In this example:

define a = 1
define o = object()

label start:
$ b = 1
$ o.value = 42

only b will be saved. A will not be saved because it does not change once the game begins. O is not saved because it does not change - the object it refers to changes, but the variable itself does not.
The excerpt above makes it sound like that if you have a class/object that has any internal state (in the form of class members/variables); the internal state will not be saved.

In such a case, it sounds like to get saving and loading to work with such objects:
1. The state (some combination of pickleable primitives) needs to be initialized outside the object (i.e. 'global' scope/'script.rpy' scope) upon the start of a new game (or a save file load)
2. The state is passed into the constructor of the new object or some method; so that the object can be reinitialized to the saved state.
3. *Before the player saves, the state needs to be reassigned/passed back to the global primitives (so that renpy's saving method sees a change to those variables)

So in most cases #3 can be accomplished as "atomically" as possible by:
1A. As soon as some internal state of the object changes, update the global-scope primitive as well.

My questions/concerns are:
1. Am I misunderstanding something about the save system?
2. If I am not (or not completely)... is 1A the only way to solve the issue? Could there be potential issues of performance if the variable that needs to be saved is large?
3. connected to point #2 above; if I want to defer updating the global primitive to some later time (bulk updates for performance); that is when a save() callback could help a lot.

User avatar
PyTom
Ren'Py Creator
Posts: 16096
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: python callbacks for saving and loading

#8 Post by PyTom »

If you do:

Code: Select all

label start:
    $ o1 = object()
    $ o1.value = 1234
Objects reachable from o1 will be saved. Basically, if a variable has been changed outside an init block, it and all objects reachable through it will be saved.

The one issue you have to be careful about is aliasing. If you do:

Code: Select all

define o = object()
label start:
     $ o1 = o
after a save and load cycle, o and o1 will not be the same object.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

ChesStrategy
Regular
Posts: 96
Joined: Wed Jan 14, 2015 7:01 pm
Contact:

Re: python callbacks for saving and loading

#9 Post by ChesStrategy »

Hi PyTom,

How would I go about saving only certain variables in a class; If I don't want to save the whole class?

Thanks,
ChesStrategy

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: python callbacks for saving and loading

#10 Post by Alex »

You could reset some variables in after_load label, like http://lemmasoft.renai.us/forums/viewto ... 25#p341566

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: python callbacks for saving and loading

#11 Post by trooper6 »

Could you explain what you exactly want to do in context? Why would you create an object and not want to save the entire object?

Say your Class is Character. The class has four variables: Name, Hit Points, Charm Points, and Fear Points.
Then your create two Character objects, one named Grognard and one named Fatima. And through the course of the game their variables change over time. So why would you want to save only Charm Points and not Hit Points?

Could you give a more detailed example of what it is you want to do in a context and why?
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

ChesStrategy
Regular
Posts: 96
Joined: Wed Jan 14, 2015 7:01 pm
Contact:

Re: python callbacks for saving and loading

#12 Post by ChesStrategy »

Let me try to think up an example; maybe I'm overlooking something simple since I haven't been getting good sleep lately.

I have an Achievement() class, that holds the player's score, times game is reloaded/saved, among other statistics. One of the achievements is to get increase score by a certain amount X, without a save/load in between. So I'm trying to accomplish this by having a temporary statistic in the Achievement class, that ideally holds the difference (increase/decrease) of the score since the game was loaded. If the difference is > X, then the player gets the achievement. Obviously I need to persist the player's total score and achievement acquisition status, but reset this temporary stat (i.e. not save it) between saves/loads.

If there is a location somewhere in the code where I can place the temp stat, allow it to change during the game, and reset to 0 before reload (or a way to explictly tell renpy not to save this stat); I guess I can do that; but I was really hoping to keep it in my Achievement() class since it makes sense from a code structure/design perspective.

Hope this example made some sense.

User avatar
PyTom
Ren'Py Creator
Posts: 16096
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: python callbacks for saving and loading

#13 Post by PyTom »

I'd suggest just resetting the stat in the after_load label.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

ChesStrategy
Regular
Posts: 96
Joined: Wed Jan 14, 2015 7:01 pm
Contact:

Re: python callbacks for saving and loading

#14 Post by ChesStrategy »

Hi all,

I've talked with several other teammates in our project; they are OK with disabling autosave. Some minor questions that remain:

1. How do we disable autosave? My guess it is somewhere in the config?
2. Upon doing disabling autosave, we just wanted to make sure the only method of saving/loading the game is (and only is) explicitly clicking the save/load buttons; thus we can modify screens.rpy to do the callback whenever the save/load buttons are pressed (per trooper6's earlier suggestion)

Thanks for all of the help and suggestions thus far!
ChesStrategy

synedraacus
Regular
Posts: 58
Joined: Tue Jun 09, 2015 8:10 am
Github: synedraacus
Contact:

Re: python callbacks for saving and loading

#15 Post by synedraacus »

Just adding another use case where explicit callback may be necessary. In our game the player ends up with a bunch of procedurally generated objects in his inventory. Of course, those are instances of a class that contains object data, displayable among them. Those objects are integral to the game, so they should be saved. But they contain displayables which contain Renders which can not be saved!
So we need a save callback that strips an object from its displayables and a load callback that creates them again. Of course, I can (and intend to) create my own save/load screen with my own save/load functions, but it means that autosaves are impossible.

Post Reply

Who is online

Users browsing this forum: Ocelot, piinkpuddiin