Ren'Py How do I not fuck up my Renpy saves?

HappyEnd231

New Member
Feb 11, 2022
7
10
I'm currently in the process of creating VN with multiple endings that I plan to determine using a stats based system (ie, if stats A>10, B<10, C<10 then achieve true end). Problem is I'm brand new to Renpy and coding in general so I'm scared of fucking up and be forced to create an update in the future that ruins player saves. This is pet peeves of mine and I would like to avoid it in my own projects. Are my fear even justified since my game is a simple VN that doesn't contain any gameplay or sandbox elements like these other games ?

Also bonus question are going to be performance problem if I add long animations to my games (ie. a 20 seconds looping background scene) ?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,143
14,827
Problem is I'm brand new to Renpy and coding in general so I'm scared of fucking up and be forced to create an update in the future that ruins player saves.
Then starts by reading an .


Also bonus question are going to be performance problem if I add long animations to my games (ie. a 20 seconds looping background scene) ?
No, maybe, yes.

This totally depend of the computer/tablet/smartphone used to play the game. There's people who play on a potato and would suffer even with a 0.01 second none looping background, and people who would still have a perfect game with four full size combined movies.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,559
2,176
I'll throw in two nice easy ones...

NEVER, EVER delete any of the .rpyc files unless you are deliberately deleting a matching .rpy file.

.rpyc files are what RenPy actually runs. They contain a complex cross reference of every line of code in your game. It's the reason why you can edit your game, insert or delete a few lines here and there and save games still load at the correct line (even though that line may have moved up/down within your code).

If you remove an .rpyc file, RenPy will recreate it next time you run the game... and every line of your code is "renumbered" (well, sort of - it's a lot more complex than that). So now when you load a save file, the cross reference doesn't match the data stored in the save and RenPy has no clue where to restart at.

99%* of developers would never do this anyway. But the 1% that do will regret never reading a post like this one.
*88.2% of all statistics on the internet are made up.

The 2nd piece of advice is to create all your "normal" variables (like "mom_score", "vodkas_drunk" and "met_her_mom") at the top of your code using the default statement. Anne lists this as his option "2". default happens as your game starts and they are all processed regardless of where in the code they can be found - so it makes sense to keep them all "mainly" together at the top of the code. Because any variable created this way is automatically marked as needing to be included in the save file - it avoids the rare pitfall of loading a save file where the variable is somehow missing.

In my opinion... the absolute best solution is use both options "2" and "3" from Anne's guide. Though using "2" alone (default) will be perfectly fine 99%* of the time.

Finally. Don't overthink it. Things rarely break anyway. But when things break -- it feels worse than it really is. Keep in mind that no matter how bad things get, there's always the option of "Sorry folks, saves from before v0.xx no longer work - you may need to restart from the beginning". It's a pain for the players, but sometimes it's just the way it is.
 

Jman9

Engaged Member
Jul 17, 2019
2,294
955
NEVER, EVER delete any of the .rpyc files unless you are deliberately deleting a matching .rpy file.

... and RenPy has no clue where to restart at.
Er, what? Getting rid of both will cause issues if the rest of the game actually references that particular file's content, implicitly or explicitly. Getting rid of just one might lead to problems, but is likely to just break something minor, e.g. which labels have been seen already. Depends on the game, of course.

If what you said was true, no one would be able to use forced recompile and a test save together. Obviously, people manage to develop and test their games.

I have done exactly that for three+ years now, and never regretted not reading this snippet once. To be fair, it's probably because I don't rename labels.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,143
14,827
Er, what? Getting rid of both will cause issues if the rest of the game actually references that particular file's content, implicitly or explicitly.
I'll reformulate 79flavors sentence: Do not delete the rpyc file unless you intent to also delete the associated rpy one.


Getting rid of just one might lead to problems, but is likely to just break something minor, e.g. which labels have been seen already. Depends on the game, of course.
Deleting the rpyc file can break way more than that. Among the problems, there's those ones that immediately cross my mind:
  • If Ren'Py is configured to add the from clause for the call statement when compiling from the SDK, it will generate totally new ones, what will defeat all the interest to use the said clause ;
  • When loading a save file, Ren'Py will not be able to find where you saved, and then restart the whole label ;
  • There's also case where it mess with the rollback, breaking it for the early part of the game after you loaded your save ;
  • All the dialog lines will be brand new ones and the skip feature will not works anymore ;
  • It also mess with the translation.
There's also few, by chance exceptional, cases where it totally break the save compatibility.

With some time and experience, you can tell when the author have deleted the rpyc files just by seeing Ren'Py behavior when you start a new update.


If what you said was true, no one would be able to use forced recompile and a test save together.
This have absolutely no relation with what he said.

Forced recompilation just mean that all the rpyc files will be recompiled, even if the rpy file haven't been changed. This is to use when you change the version of Ren'Py, or when you use user defined statements and made a change in one ; it will ensure you that the information as stored in the rpyc files are correct accordingly to the new way to parse the code and store what they got at this moment.
But forced recompilation do not act differently to a normal recompilation. Both rely on the rpyc file, when it exist, to enforce the compatibility. It's way to technical to explain what happen, but globally speaking keeping the rpyc files permit you to pass from this:
Code:
label start:
    "blabla"
    "line before"
    "--- save right here ---"
    "line after"
    "END"
to that:
Code:
label start:
    "blabla"
    jump somewhereElse

label neverCalledNorJumped:
    "line before"
    "--- save right here ---"
    "line after"
    "END"

label somewhereElse:
    "Something totally new"
    "END"
You can test it at home if you want. Ren'Py will load at the "--- save right here ---" line. If you advance, you'll see the content of the "neverCalledNorJumped" label. If you rollback, you'll return in the "start" label and totally skip it if you advance again.

Of course, I absolutely not advice to do something like this ; this it totally bad practice. But it's one of the best way to show how important the presence of the rpyc files is when you edit your code.


I have done exactly that for three+ years now, and never regretted not reading this snippet once.
Well, it's been more than three years that you messed with everyone's life. As for "this snippet", you would have seen it if you had read the :
"When making multiple releases, like when a game is distributed through early access or platforms like Patreon, it's necessary to keep the old .rpyc files around. The .rpyc files contain information that is necessary to ensure that saves can be loaded, and omitting these files can cause problems. "
 
  • Like
Reactions: Jman9

Jman9

Engaged Member
Jul 17, 2019
2,294
955
You don't have permission to view the spoiler content. Log in or register now.

Edit: In brief, IMO the advice should have read: don't delete an .rpyc file unless it and the corresponding .rpy file are now redundant, or you're prepared to face [list of issues from AON's post] and a rare chance of breaking the saves completely. I would have had no issues with that, and it would have been more informative and less proscriptive to boot.
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,143
14,827
If you delete an .rpy file, all the code within is gone and a chunk of the game is now missing, isn't it?
Absolutely not. The source code is gone (relatively speaking since it can be retrieved), but the source code isn't what Ren'Py use when playing the game. Many games only distributes the rpyc files and they have no problem to be played.


If not, then you're giving advice for a far more specific situation than the one in the above post appears to be.
1) It's not me who gave this advice.
2) It's an advice totally relevant to the question, since randomly deleting a rpyc file can break the save compatibility.
3) It's just repeating what is in the documentation, something that PyTom said thousands of times, to the point that he even (almost ? Don't remember precisely) dedicated one of his monthly article to this sole subject.


While that's all true, none of this is something one wouldn't expect from an update and can't work around.
There's no world where it's something one would expect ; and especially not the users. It's not because more and more software act like that (and I don't just talk about indie adult games), that it's something that should be expected.
As one of my teacher said, from memory, "if you've to change the order of your data when you update your code, then you did it wrong from the start". And the same apply here. If your update isn't fully transparent and have any kind of annoyance, like sending you back to the start of the label, by example but not only, then you did it wrong from the start.


E.g. a game with a translation also needs to have the translation updated when a patch hits.
Not when it's just a bug fix. At least not if you don't delete the rpyc files, because if you do there's risk that you've to redo all the translation.


Yes, sometimes saves can break completely and for a lot of VN's it's no good if massive labels get restarted each update. That's not a reason to issue a universal ban on deleting .rpyc files. It's a reason to say "Be cautious! Learn what can go wrong.".
No, it's a reason to say "learn to do things right", and it's precisely what we did.

Ren'Py best point is that it's a really lax and tolerant game engine. But it's also it's worse point, because more or less half of the games available here are broke in a way or another due to this tolerance.
Most of the time it's not visible, because we don't know what should have happened, because we have the same behavior than the dev, or because we make the choice expected by the author. But if we look at the code, we see that there's parts that are unreachable, or that are silently skipped. If we don't have the same behavior than the dev, we discover bugs, strange behaviors, or just miss animations. And if we make a choice that the author haven't expected, we end nowhere.
Learning to do things right, from the start and even for what looks the more insignificant, is the first step to a stable and not broke game.


It absolutely does. He recommends against any and all .rpyc deletion whatsoever. Since that's very close to recompiling, that would also mean you were wrong here:
There's nothing comparable between a compilation and the creation of a rpyc file.

A compilation transform your something highly dependent, you source code, into something that can be directly proceeded by under a wild range of cases. As long at the CPU (or what replace it) understand the set of instruction, and the OS have the right API, the compiled code will works. That's why you can still use +20 years old software on Windows 11, run Windows software on ReactOS, or emulate a C64 on your modern PC, among other things.
Plus, as long as you know assembly language, you can understand the result of the compilation and what the code is doing.

But the creation of a rpyc is a totally different process. In a way it's near to the pre-processing performed by some interpreted languages. But "in a way" only, because the process only care about the data and totally ignore the way they'll be proceeded. rpyc files are just a way to store objects and their values ; but objects deprived to any code, there's their name and there values, nothing more.
This mean that a rpyc file is even more dependent than a rpy file is. Only Ren'Py, and technically speaking only the right version (practically the backward compatibility is relatively good), can understand what is stored in a rpyc file.
If you achieved to get a humanly readable version of the rpyc file, you still wouldn't be able to understand what it's doing. You would know that there's an object named "whatever", that it's "myVar" attribute have such value, its "otherVar" have that value, but that's all you would get from the rpyc file. What this object do, what those value mean, is something totally independent of the file.

Therefore, the creation of a rpyc file is at the opposite of a compilation, in this way that the compilation create something still understandable and less dependent, while the creation of a rpyc file create something more dependent and mostly obscure.

And effectively I wasn't wrong, but in the context where I gave this answer. It's not the deletion of the rpyc file that will, by itself, break the save compatibility. As I said in the same discussion (perhaps not directly in the post you quoted), it's how you'll deal with your code after this deletion that can possibly break it. What mean that:

I don't think you were wrong then, and thus I think this absolute recommendation is wrong, or at least quite misleading.
It's not misleading, it's a warranty.
OP said that he have near to no codding knowledge and his totally new to Ren'Py. This mean that he can possibly do all the errors that can lead to a broke save compatibility, when not a broke save, in case of deletion of the rpyc files.
Above you said that your issue was with the absolute. Well, in the absolute, he'll do this thing that make Ren'Py crash silently when you load a save file. A problem than only happen when the rpyc files have been deleted, and that have hit few games available here ; but haven't happened since a long time, so perhaps that PyTom finally achieved to understand it or, more surely, it was silently solved by the fix of something else.


Can, not will.
What is an even better reason to not do it. In computer science, there's nothing to fear more than a "can" where you expected a "will".

A "will" mean that we know what can happen and why it happen. There's no work around, no way to easily fix this, but at least we know what we have to avoid. It also mean that we will immediately know if our code is broke or not, by testing it under the condition that trigger the problem.
But a "can" mean that everything is possible, from the best scenario (everything works fine) to the worse one (nothing works and we have no clue why). And like there's no fixed conditions that trigger the problem, we have no way to know if our code is broke or not.
It can perfectly works fine for years, until one user do something a little differently and boom. I think it was in the late 90's that I had to fix a software because of this kind of problem. It was a management software that worked fine since decades, for probably dozens of thousands users since at this time it was the product number one on the market. At least it worked fine until the day someone had two consecutive accented characters in his name, and I had to figure out why it broke everything.

So, when you read something like, "doing this can lead to trouble", do not do the said thing, even if it mean that you'll have to pass one week finding a work around. Else you'll be walking on a minefield. Perhaps that you'll make 99,99% of your way out without problem, but the 0.01% left can be the moment when you'll put your foot on a mine.
 
  • Like
Reactions: Jman9

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,559
2,176
Er, what? Getting rid of both will cause issues if the rest of the game actually references that particular file's content [...]

Which was why I said "deliberately deleting". Perhaps I could have used an alternate word, but I didn't. The original version of my advice was "Never delete an .rpyc file". Keep in mind my intended audience... people who don't know any better... who do something perfectly normal in other environments... and in the process accidently screw themselves over. I recognized that "Never delete an .rpyc file" was too broad and so I've starting qualifying it in case someone DOES choose to delete the matching .rpy file.

If what you said was true, no one would be able to use forced recompile and a test save together. Obviously, people manage to develop and test their games.

.rpyc files use what they call an AST tree. PyTom's original blog post is here :
It explains (at least implicitly) why deleting an .rpyc would break things, whilst forced recompiles wouldn't.
The basics are that when the game is incrementally built, each new iteration of the .rpyc file is based on the previous version. It grows and varies over time. As soon as you delete an .rpyc file, that previous "history" is lost and RenPy has to start from scratch with a new AST tree.


I have done exactly that for three+ years now, and never regretted not reading this snippet once. To be fair, it's probably because I don't rename labels.

And in the three or so years I've been helping people out, I've probably spoken to maybe half a dozen people in the background explaining how to repair their games after they've done some things similar.
What generally matters is whether the game has been released or not. Once there are saved games on lots of player's machines... things get more complicated.

I glad you haven't had problems. But not everyone is as experienced as you. As the consequences can be so severe and the solution so easy (don't do it)... my advice is a word of caution for those who don't know the detail of "why" yet.

Edit: since it's come up in a recent discussion - I will summarize a part of consequences to say that if you are writing a mod, even if that mod include files shared with the base game - never include .rpyc files with your mod when distributing it.

By only including
.rpy files, RenPy is forced to rebuild any necessary .rpyc files based on the existing .rpyc files and the merged contents of the mod. This is by far safer... because the resulted updated .rpyc files will share ALL the "history" I've talked about with the current version of the game. Makes it easier each time a new version of the game is released.
 
Last edited:

Jman9

Engaged Member
Jul 17, 2019
2,294
955
Keep in mind my intended audience...
Fair. All I'd have wanted is another disclaimer that this is not a guarantee of broken saves, not even close, instead of '*99%'.

What generally matters is whether the game has been released or not. Once there are saved games on lots of player's machines... things get more complicated.
True, but they get complicated for other reasons as well. I've found that just making it okay for major milestones to break saves works for me, especially as converting saves is a lot of work. YMMV.

But not everyone is as experienced as you.
I'm not. I'm a self-taught idiot who doesn't care to spend too much time on learning proper software development because I do this alone, for fun and not profit. Game dev is for young slaves idealists, and commercial software work is a lifelong career that isn't mine.

E.g. I was not quite aware of the exact magnitude of what can happen when you delete .rpyc files. I just have done it, and not suffered from much more than broken 'seen labels' history. I didn't think I was quite '1%'.
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,559
2,176
All I'd have wanted is another disclaimer that this is not a guarantee of broken saves, not even close, instead of '*99%'.

To my mind, it is almost a guarantee of broken saves. Though I free admit I spend my time thinking about what is the worst that could happen.

My 99% figure was the number of developers who would just develop their game and never even consider deleting an .rpyc file for a game that is already in progress. As long as each new iteration of the .rpyc has a direct link to the one before it - it's never an issue.

I just have done it, and not suffered from much more than broken 'seen labels' history.

It might be we're talking about slightly different scenarios, or scaling the consequences differently...

Here's what I was thinking of...
  • Take an existing semi-large game.
  • Play it for a while (or skip through) until you're about 50% through a script file.
  • Save and quit.
  • Delete the .rpyc file for the script file you're currently in the middle of. (ideally keep a copy of the .rpyc file to put back later).
  • Run the game again.
  • RenPy recreates the .rpyc file from scratch.
  • Try to load the save file you made before deleting the .rpyc file.
In my experience, RenPy will struggle to load that save. Often to the point of refusing outright due to being unable to match the history buffer (stored in the save file) to the current version of the AST tree (stored in the .rpyc file).

As with all the fine detail of these things, there are caveats. RenPy will manage better if there are lots of label statements within the script (as I understand it, the AST trees are anchored to labels). It will also manage better if the section of code where the saved occurred has not been heavily edited during the overall development process (the more you edit+run, the more updates of the AST tree elements you create within the .rpyc file).

I hope it goes without saying that active developers of real games should NOT try this with their own projects. It's possible to recover from this, but not without consequences (though generally pretty minor ones).

I'm not a RenPy expert. I too have just been trying to learn things as I go along, primarily for my own amusement. My very first message (nearly 4 years ago) here on the F95 forums was about save compatibility. If reality works better than my worst case scenario... great! Which is not to say that the advice to leave .rpyc files well alone where ever possible is not something worth planting at the back of someone's mind.
 
  • Like
Reactions: Jman9

Jman9

Engaged Member
Jul 17, 2019
2,294
955
My 99% figure was the number of developers who would just develop their game and never even consider deleting an .rpyc file for a game that is already in progress.
Usually, I don't, either. But there is a niche reverse situation where if someone either changes a script themselves or just has screwed up dates, they might end up with an .rpyc file that's newer than your spiffy new update. And if you're a miser like me and only release .rpy files as minor fixes, that's going to mean the little fix won't activate without further prodding.

It's pretty damn rare, though.

It might be we're talking about slightly different scenarios, or scaling the consequences differently...

Here's what I was thinking of...
  • Take an existing semi-large game.
  • Play it for a while (or skip through) until you're about 50% through a script file.
Quite likely. I've only ever been involved with Ren'Py games where saving in the middle of some random label tends to lead to broken return labels (or worse) anyway, intact AST trees or no, and all labels are relatively short themselves so there's no great incentive to save mid-label.

Which is not to say that the advice to leave .rpyc files well alone where ever possible is not something worth planting at the back of someone's mind.
I have no issues with and endorse this.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,143
14,827
The advice was:

A Ren'Py newcomer will easily read from it "Don't delete .rpyc files, or saves cannot be loaded again, ever." This is not the case.
But what is the best outcome ?
A frightened newcomer who take real care to never delete the rpyc files, or a newcomer who deleted one by error, and now face players complaining about the behavior of Ren'Py, without a single clue regarding why it happened and how to solve it ?
[Not sure this example is the best since in English it's also named "hotplate"]
We tell our children to never touch a cooking plate, and it's only later, when they are older with "more knowledge", that we had "when it's hot". In a way it's a jerk move, we scare a poor little thing that don't deserve it, but better safe than having to rush to Emergency.

Of course, it's different here, 90% of the time the risks for the game are minimal when you delete a rpyc file. But there's also the risk for the author that have to be take in count. When you're totally new to this, it's so easy to lost your passion and believe that in fact making a game is not for you. It can just need that you face a problem that you don't understand and/or can't solve.
We can't prevent the syntax errors, the logical errors, and so many things that he'll do and that will perhaps lead to a problem. But at least there's some issues that can be prevented with few words: "Never delete a rpyc file".


Because you're using an idiosyncratic definition of 'compilation'.
It's not an idiosyncratic definition, it's the definition of the word, period.


Are you saying that a Java compiler that outputs Java bytecode suddenly isn't a compiler because you think compilers must be high-level-to-low-level?
No, I'm saying that rpyc are not the result of a compilation.
Java compilers transform the source code into bytecodes that only the Java interpreter can understand. But bytecodes are instructions, exactly like the opcodes of the good old Basic. The interpreter proceed those bytecodes in the same way that a CPU do with the opcodes of a binary compiled software.
But this isn't at all what happen with rpyc files. There isn't a single instruction in a rpyc file, they contain the serialization of the data stores in Ren'Py AST, nothing else. A rpyc file just tell that there's an object named X which class is Y, and that have for attribute an integer named Z that have 10 for value. It's all what is stored in a rpyc file.
Even inline Python (the $ x = "some string") are stored more or less as literal strings. What is stored in the rpyc file is: class PyCode / source 'x = "some string"' plus some information telling where this line is located in the source code. And that's all. I wonder how this can be seen as a form of compilation.


Which is exactly my issue with it all. You say it will break saves, and provide evidence that it might.
No, I said that it risk to break the save compatibility, what is different to breaking the save. When your save files are incompatible, they can still be loaded, but they will not permit to continue the game as if you haven't saved.