• To improve security, we will soon start forcing password resets for any account that uses a weak password on the next login. If you have a weak password or a defunct email, please update it now to prevent future disruption.

Ren'Py Unzip Renpy Backup

Passion3D

Well-Known Member
Modder
Nov 10, 2017
1,258
6,871
How to decompress a Renpy backup. I'm talking about the "log" file in the .save
I tried with "import zlib", but the call to zlib.decompress sent me this error:
zlib.error: Error -3 while decompressing data: incorrect header check
 

the66

beware, the germans are cumming
Modder
Respected User
Donor
Jan 27, 2017
7,618
23,601
How to decompress a Renpy backup. I'm talking about the "log" file in the .save
I tried with "import zlib", but the call to zlib.decompress sent me this error:
zlib.error: Error -3 while decompressing data: incorrect header check
correct me if i'm wrong but doesn't renpy uses the zipfile module?
 

the66

beware, the germans are cumming
Modder
Respected User
Donor
Jan 27, 2017
7,618
23,601
It's not the '.rpa' that interests me.
I'm trying to decompress the 'log' file contained in the '.save' file
then go with zipfile
from loadsave.py
Code:
    def write_file(self, filename):
.
.
.
        zf = zipfile.ZipFile(filename_new, "w", zipfile.ZIP_DEFLATED)
 

Passion3D

Well-Known Member
Modder
Nov 10, 2017
1,258
6,871
then go with zipfile
from loadsave.py
Code:
    def write_file(self, filename):
.
.
.
        zf = zipfile.ZipFile(filename_new, "w", zipfile.ZIP_DEFLATED)
But this is to create the file ".save" which contains the "log" which contains the data of the game no?
 

Penfold Mole

Engaged Member
Respected User
May 22, 2017
2,905
6,611
The log itself doesn't look compressed to me at all.
I mean, the save file itsef is a simple zip file. When you extract log from there, it's not compressed. It has clear text strings in it and some sort of code, characters that aren't displayable. You can open it in Notepad++ and take a look. A compressed file shouldn't contain that much clear text.
@anne O'nymous or @Last Moment may know more about it, since Last Moment is the guy behind the save editor:
 
  • Like
Reactions: anne O'nymous

Passion3D

Well-Known Member
Modder
Nov 10, 2017
1,258
6,871
The log itself doesn't look compressed to me at all.
I mean, the save file itsef is a simple zip file. When you extract log from there, it's not compressed. It has clear text strings in it and some sort of code, characters that aren't displayable. You can open it in Notepad++ and take a look. A compressed file shouldn't contain that much clear text.
@anne O'nymous or @Last Moment may know more about it, since Last Moment is the guy behind the save editor:
"log" file is pickled and compressed
 
  • Like
Reactions: anne O'nymous

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,202
14,939
"log" file is pickled and compressed
Pickled yes, but like @Penfold Mole said, the file itself isn't compressed. What you need to access the data is to unpickle it, but doing this directly on Ren'py will lead to a global conflict. So either you use a standalone Python file, or the save editor linked by Penfold Mole.
 

Penfold Mole

Engaged Member
Respected User
May 22, 2017
2,905
6,611
Yep, that's how it looks after looking at the loadsave.py and savelocation.py code. The log is pickled, but zipped together with the other included files into the *.save container, not separately.
I have zero Python skills, but it looks quite obvious reading it.
Thanks, anne!
 
  • Like
Reactions: anne O'nymous

Passion3D

Well-Known Member
Modder
Nov 10, 2017
1,258
6,871
Pickled yes, but like @Penfold Mole said, the file itself isn't compressed. What you need to access the data is to unpickle it, but doing this directly on Ren'py will lead to a global conflict. So either you use a standalone Python file, or the save editor linked by Penfold Mole.
I tested with this:

import pickle
pkl_file = open('log', 'rb')
data1 = pickle.load(pkl_file)
print data1
pkl_file.close()

and I get that:
Traceback (most recent call last):

File "Pickle.py", line 31, in <module>

data1 = pickle.load(pkl_file)

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1378, in load

return Unpickler(file).load()

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load

dispatch[key](self)

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1090, in load_global

klass = self.find_class(module, name)

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1124, in find_class

__import__(module)

ImportError: No module named renpy.python

what's wrong with my code?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,202
14,939
ImportError: No module named renpy.python
My bad, I surely should have be more explicit when I answered. When I talked about a standalone Python script, I didn't meant that it will be something easy to do. Pickle works its own way, and unpickling doesn't meant "retrieving the raw data", but "recreating everything like it was". For each data to pickle, the module will store its name, its type and its value. Then when unpickling, he will create an attribute of this type, with this name, and assign it this value. And obviously, for this it need to have access to the type/class to create.
To complicate everything, because of its rollback system, Ren'py don't use regular List, Set, Dict and Object, but a "revertable" (supporting rollback) version defined by it. And on top of this some internal values can also be saved (like store._console.history by example), like obviously any class defined by the game itself.

So, for the said standalone version, Pickle need to have access to the class declaration of every single attribute that have been pickled. And for this you need to recreate Ren'py context, but without loosing the control. If you're sure that there isn't a single class defined by the game itself, importing Ren'py module should, more or less, be enough. But if there's at least one class defined by the game, you'll need first that Ren'py parse all the rpy files, then compile the said class declaration and put them in the right store. It possible, but not easy nor really useful.
And like I said, doing it directly over Ren'py will make a mess, since it will have exactly the same effect than loading the save file, unless you find a way to trick pickle and make it use another thing that the default store as target ; which is far to be easy and perhaps not even possible.

Now, personally I have a question : Why ?
The save editor can be useful to clean a save file and/or verify what's really save when you try advanced coding. But else, why editing/looking into, the save file, when you have the console and the variable viewer (whatever the default one or the extended version I made).
If you answer the question, they we can perhaps found a workaround.
 

Passion3D

Well-Known Member
Modder
Nov 10, 2017
1,258
6,871
@anne O'nymous
Thank you for all these details;)
The Backup Editor does not exist on Mac yet.
I need, for my project, to manipulate a backup outside the game.

I will try to get by with the info you gave me :)
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,202
14,939
I will try to get by with the info you gave me :)
If you don't need to have full access to the data but just make few changes, or look for few things, perhaps that just taking control on Pickle, and more precisely on the unpickling process, can do it for you. I don't know how it will works, but I assume that you'll have access to the pickled data after they are retrieved from the file, but before the attributes will be created ; something like [ ( typeData1, NameData1, ValueData1 ), ( typeData2, NameData2, ValueData2 ) ].
Perhaps it can help, so take a look at this :
On a side note, the pickle protocol is documented somewhere (don't remember where). If you find it, it can help you to directly look into the file.