Wall of text, but worth a read if you want to try and understand what's going on a bit better then just trying to imitate other things and hoping it works somehow.
Okay, so I think there's a misunderstanding here about what saving actually is.
I'm going to explain this with relation to Essentials, but this the information can also be generalized to Ruby outside of Essentials, so I'm going to leave this in the General Coding category. Firstly, I'm going to explain a bit about saving in general, and then specifically about how/why you will use this in your load screen.
No part of your current code persists when you restart the game, any instance variables, etc, are all reset. The thing that allows them to persist is that the game will take specific instances of classes (the $Trainer variable, as an Essentials example, is an instance of PokeBattle_Trainer), and writes them all into a file (your saved game). The way they are loaded is simply the reverse, reading those data files, and setting whatever variables to the instances of classes that were saved there. There's no special symbols that indicated whether something should be saved or not, all saving and loading has to be defined manually.
What the '@' symbol means is that the variable is an instance variable, you are correct in that regard, but also remember that not all instances of classes are saved in Essentials (nor are they in almost anything, you should only save what you need). From your sample code, it's hard to tell exactly where you've put things, but I would guess you're not implementing it in something already designed to be saved.
So, let's see an example of how we could add a new variable to store some information. Since progress is related to your trainer, it would make the most sense to utilize the already saved PokeBattle_Trainer class.
If you go to the section of the same name, you'll see the initialization method (which is called when creating an instance of a class. We can add this red part
Code:
def initialize(name,trainertype)
@name=name
@language=pbGetLanguage()
@trainertype=trainertype
@id=rand(256)
@id|=rand(256)<<8
@id|=rand(256)<<16
@id|=rand(256)<<24
@metaID=0
@outfit=0
@pokegear=false
@pokedex=false
clearPokedex
@shadowcaught=[]
for i in 1..PBSpecies.maxValue
@shadowcaught[i]=false
end
@badges=[]
for i in 0...8
@badges[i]=false
end
@money=INITIALMONEY
@party=[]
[COLOR="Red"]@progress="Whatever default value"[/COLOR]
end
So, now if you start a new game, this variable will be initialized, and saved since it's in a class that's already (elsewhere) going to be saved.
But, this leaves us with a problem, even without saving. If you already have a game started before you added this variable, your instance of the class doesn't have this variable defined. So if you try to use it, it will cause problems.
Now, accessors are important here. I'm not going to explain them in depth, because they're actually a lot more complex than they seem. Going with the current example
Code:
class PokeBattle_Trainer
attr_accessor(:name)
attr_accessor(:id)
attr_accessor(:metaID)
You can see these accessors are used here, and their general purpose is to serve as methods that "access" instance variables of that class. There are 3 types of attr_ : attr_reader, attr_writer, and attr_accessor. Reader is for returning an instance variable (known as a getter in other languages), writer is for setting an instance variable (known as a setter in other languages), and accessor is both of them in one. A notable using is $Trainer.party, which is utilizing the attr_accessor :party to return the instance variable @party for your trainer.
But there's a problem with simply using these for variables we're adding, if you intend to provide support for previously saved files.
attr_writer is fine, since the code equivalent (these are not exactly the same, but we don't really need to understand how they work to use this) for attr_writer :progress is
Code:
def progress=(value)
@progress = value
end
Even if the current save file wasn't initialized with @progress, it can be written to here and is now initialized in the class.
Readers, on the other hand, are equivalent to
Code:
def progress
return @progress
end
In an older save file, @progress has never been set, meaning this will always return nil, no matter what you want the default value to be.
So, a workaround to this is to still use attr_writer, but make our own reader method
Code:
def progress
@progress = "A default value" if !@progress #or if @progress.nil? , if your variable is a boolean
return @progress
end
While we've now solved our problem for anything accessing the variable from outside the class, we should also consider the inside of the class as well. Consider the following method (inside the PokeBattle_Trainer class, and with all of our previously stated additions included)
Code:
def displayProgress
Kernel.pbMessage(_INTL("{1}",[COLOR="red"]@progress[/COLOR]))
end
This value will be nil, because it's not using our reader method, it's simply looking for that instance variable, which has not currently been set. Instead, we can say
Code:
def displayProgress
Kernel.pbMessage(_INTL("{1}",[COLOR="red"]self.progress[/COLOR]))
end
This will use the method we created, and thus will get a default value if it's not set.
So, now here's the additions we've made to our class
Code:
class PokeBattle_Trainer
def initialize(name,trainertype)
@name=name
@language=pbGetLanguage()
@trainertype=trainertype
@id=rand(256)
@id|=rand(256)<<8
@id|=rand(256)<<16
@id|=rand(256)<<24
@metaID=0
@outfit=0
@pokegear=false
@pokedex=false
clearPokedex
@shadowcaught=[]
for i in 1..PBSpecies.maxValue
@shadowcaught[i]=false
end
@badges=[]
for i in 0...8
@badges[i]=false
end
@money=INITIALMONEY
@party=[]
[COLOR="red"]@progress = "A default value"[/COLOR]
end
[COLOR="red"]attr_writer :progress
def progress
@progress = "A default value" if !@progress
return @progress
end
def displayProgress
Kernel.pbMessage(_INTL("{1}",self.progress))
end[/COLOR]
end
And now we've added a variable that will be saved and loaded, and will work properly even with old save files :)
Couple more notes. "Global variables" doesn't mean variables that will be saved. For instance, $DEBUG isn't saved. All these different terminologies for variables just refers to the scope, which isn't something I'll talk about here. You can see which variables get saved in def pbSave(safesave=false), in PScreen_Save.
One more thing to consider is that the variables you can add to classes aren't limited to strings, objects you might consider more complex can be used too. They can be any serializable object (you don't really need to know what that is, but 99% of the things you'll be using are). For instance, we can make @progress equal to PokeBattle_Pokemon.new(1,5,$Trainer) if we wanted.
Okay, so, onto talking about the actual load screen. This might sound a little complicated, but it's not so when you think about what we've learned. Saving and loading are not things automatically done, but the what/where/when are specified by the code. At the loading screen, we've actually not set all the global variables ($Trainer, and whatnot), and as such you cannot use them. But, it has loaded a few classes that it needs during the loading screen, notably the trainer class (so we've loaded it, but it hasn't been assigned to $Trainer yet). However, what was loaded was passed to the class that will make all the panels in the scene, which includes writing the player name and such in the "Continue" option.
Code:
class PokemonLoadPanel < SpriteWrapper
attr_reader :selected
def initialize(index,title,isContinue,[COLOR="red"]trainer[/COLOR],framecount,mapid,viewport=nil)
super(viewport)
@index=index
@title=title
@isContinue=isContinue
[COLOR="Red"]@trainer=trainer[/COLOR]
@totalsec=(framecount || 0)/Graphics.frame_rate
@mapid=mapid
@selected=(index==0)
@bgbitmap=AnimatedBitmap.new("Graphics/Pictures/loadPanels")
@refreshBitmap=true
@refreshing=false
refresh
end
We can see in the red here where it was passed, and is being used as an instance variable in the loading screen classes. This is why a few methods below
Code:
textpos.push([[COLOR="red"]@trainer.name[/COLOR],56*2,32*2,0,Color.new(56,160,248),Color.new(56,104,168)])
Will actually write your trainer's name. Since we've stored our "progress" variable in our trainer class, we can now use the reader we defined above.
Code:
textpos.push([@trainer.[COLOR="red"]progress[/COLOR],56*2,32*2,0,Color.new(56,160,248),Color.new(56,104,168)])
and it will actually do something.
The reason I'm explaining all this is so you don't simply try to use $Trainer.progress in this area and then wonder why it errors. Also note that most of the other saved data hasn't been loaded yet. So if you need to displayed saved data in the loading screen, put it in PokeBattle_Trainer unless you want to do slightly more complex coding.