I can think of a number of solutions. Problem is they each have their advantages and disadvantages.
Solution 1: Unlink the existing saves to your next release...
Within your
options.rpy
file, change the line that says
define config.save_directory = "..."
. It's usually your project name and a random number. Just change the random number.
On PC at least, whenever you do a save - the save file is put both in the
\game\saves\
folder AND a common folder within the Windows APPDATA folders. This means that when a player installs a new version, that new version can synchronize it's save files with the ones stored in the APPDATA folders and everything can continue normally.
But if you change the name of APPDATA folder (the
config.save_directory
), you break that connection. A new version of the game's save folder will be empty and so will the (new) APPDATA version.
The player won't see their previous saves. But in the process, they'll lose all those Character() definitions that are incorrectly stored in the save file.
Players who manually copy their save files across will lose the portraits when they load those saves. But that's on them.
I'm unsure what Steam does though. If it keeps the game in the same folder when there is an updated release, that will keep the existing
\game\saves\
folder and you're back to square 1. Changing
config.save_directory
won't break the connection to the old saves.
Solution 2: Change the variable names used for your Character() definitions...
This one is a LOT of work. But guarantees the fewest problems (for the player).
You already have code like:
Python:
define arisa = Character("{size=-10}Arisa \"No jokes\"{/size}", image="arisa", color ="#8b0a1c")
define cyntx = Character("Cynthyatrix", image="cynthyatrix", color="#cbb439")
define jack = Character("{size=-10}Awesome Jack{/size}", image="awesome_jack", color ="#bb8be2")
default n = Character(None, color="#F13E18", what_color="#c9b7ae", what_italic=True)
default p = Character("[mc]", image="mc", color="#113cb1")
Change ALL of these to something new (and unique).
Python:
define a = Character("{size=-10}Arisa \"No jokes\"{/size}", image="arisa", color ="#8b0a1c")
define c = Character("Cynthyatrix", image="cynthyatrix", color="#cbb439")
define j = Character("{size=-10}Awesome Jack{/size}", image="awesome_jack", color ="#bb8be2")
define narrator = Character(None, color="#F13E18", what_color="#c9b7ae", what_italic=True)
define pc = Character("[mc]", image="mc", color="#113cb1")
The new names must be unique (within your game).
btw,
narrator
is a special character name within RenPy. It is used any time you have a line of dialogue, but no specific character speaking it.
Now the "hard work" bit... Every single line of dialogue needs changing to match the new id.
I've chosen to change the majority of names to single characters. That won't always be possible. But it's a good start.
I've chosen to change
p
to
pc
for example. I'd normally have picked
mc
, but you've already use that for the player's name. So I went with "pc" (for "
player
character").
There will still be a variable called
arisa
within certain player's save files. But your game will no longer use it. It's new name of
a
is created using
define
and so the link to the bad data is broken.
Player's may have issues with save files not being able to match up the correct line when loading. In my experience RenPy is good at working around this one - but I may be wrong and players will instead see the dreaded "Exception: Couldn't find a place to stop rolling back. Perhaps the script has changed in an incompatible way?"
At which point your only real option is a disclaimer to the effect of "Saves up to version x.xx may be incompatible with the current game."
You can't even do a "change all" within your editor because you frequently use names like "arisa" in multiple ways within your code. That is... doing
change all "arisa" to "a"
might fix all your dialogue lines, but break something else.
I've done it before. But you have to be ridiculously careful. Or you have to do them all manually.
As I say... "A LOT of work".
Option 3: Remove the variables from the save files.
Okay. I sort of know how to do this one. But not fully.
I know something that should get you 80% the way to a solution, but I'm going to rely on someone like
anne O'nymous to step in and fix the code I'm mostly guessing at.
The basic idea that there is a
You must be registered to see the links
called
label after_load():
. Anytime you load a save file, if you have an after_load label, that code will be called. It's designed to allow the developer to fix errors in save files before they impact the player.
Firstly,
default
variables are kept with another variable called
store
. RenPy does this for you automatically, so you don't generally need to think about it... except on occasions like now...
So I'm imaging some code like this:
Python:
label after_load():
if hasattr("store", "arisa") == True:
$ delattr("store", "arisa")
$ arisa = Character("Arisa \"No jokes\"", image="arisa", color ="#8b0a1c", who_size=10)
return
DON'T USE THAT CODE BTW.
I'm imagining a number of problems (I can't currently test this code).
Firstly, I'm not sure if a variable created with
define
is already kept in the
store
. I'm hoping that only variables from the save file are held with in the store, but I'm not able to test that right now.
Secondly, the game still needs an
arisa
Character() object to work. So deleting the value isn't enough. Which is why the next line creates a new definition using the updated/correct details. Except, I'm 99% sure that new definition will be included in the next save file. Which kinda defeats the object of what I was trying to do.
Maybe that's good enough. Maybe just replacing one broken Character() definition with the correct Character() definition on the save files is enough (in which case the
delattr()
line probably isn't needed).
What I can't think of is a solution that creates a new variable that is practically the same as if it had been created using
define
(that is, NOT saved the next time the player saves a game).
There's a solution in here somewhere. Probably some variation on #3 (and maybe #1 too). It's just quite there yet.