06-08-2023, 09:24 PM
Classes & Instance Variables & Aliases
This is not the first I ever discuss the topic, but there is a good reason why I have to come back to that same place once again. There are people that every so often encounter the very same issue and for some reason they are oblivious to the actual cause of their scripting nightmares.
As we learned here, classes need to be defined at the beginning or reopened at any other moment. This second stage is critical to what I am going to criticize here.
I myself have made that mistake and I am not alone here. Even Hime has made it and few others as well.
Well, it has two very specific parts. The first one is we forget to tell people that our code has aliased a method present in an already existing class, either a default script or a famous custom one.
Why is this a problem?
For some strange reason, we think the average joe will understand simple concepts like how to use a script or how to properly implement it in their own projects. What a classical mistake!
The truth is that most of the forumers don't. They might not fully appreciate what we scripters have been doing for them, yet, they don't even suspect that their lack of knowledge is what is actually biting them back.
Aliasing Can Be Dangerous... Sometimes
When we alias a method, we are telling Ruby, or RGSS if you prefer, to call the previously defined method with the same old name we had BUT by using a brand new nickname. This can be done as many times as needed as long as we don't repeat those so called nicknames. (They are aliases, anyway.)
This is exactly the part where the blame shifts completely to the scripter.
We normally create brand new @instance variables there.
Here is an example.
Code:
class MyClass
alias :my_alias_init :initialize
def initialize
my_alias_init
@my_new_variable = 1
@my_new_boolean = false
end
attr_accessor :my_new_variable, :my_new_boolean
end
Normally, this would be OK for we the scripters are totally used to this. Our customers aren't.
They don't know that once you want to test that new addition, you GOTTA GET RID OF OLD SAVED GAMES.
Yes, this time I am yelling at everybody.
Why should we get rid of old saved games?
When you first created your heroes or monsters on the map BEFORE you added the new script or script modification, those @instance variables didn't exist at all. Not even for a second!
Once you try to load the game, you can get 1 out of 2 outcomes.
- The file could not be loaded and breaks your game.
- You are indeed playing from the last saved point, YET, it crashes later on. Sometimes in less than 5 minutes or at the moment they are facing a tough enemy or even a poor slime!
Why does it fail to load all data?
That is because it never was there. When you add a new modification, those new variables won't be created UNLESS you start a new game session. Only then it will work!
Why does it work in new game sessions?
And the reason is simple. This time the game did find our new procedures included in our new script, the one with the @instance variables being declared so they get created just in time. Yes, declaring variables is the same as creating them for immediate or future use.
Isn't there any exception to this rule?
Yeah, there is some sort of except here. The thing is that you can't always count on it.
Under some circumstances you can create a brand new method inside that class and declare those @variables there. Then you can call that method via a script call. This means you need an event to process it for you.
Take a look at this example.
Code:
class MyClass
alias :my_alias_init :initialize
def initialize
my_alias_init
my_new_method
end
def my_new_method
@my_new_variable = 1
@my_new_boolean = false
end
attr_accessor :my_new_variable, :my_new_boolean
end
In this case, the script call would be the following:
Code:
my_class = MyClass.new
my_class.my_new_method
If you save your game right after that call, you should be safe for the rest of your game. Nonetheless, there is a caveat or two as well.
What if one saved game took place while visiting the Royal Palace?
And wasn't there another where you were searching for a custom item or weapon inside the whole Dark Wolf Dungeon?
How many times would you need to make the same call from many different events?
Is there any other solution to this convoluted problem?
Yes, there is just another one. Still, it can't always be applied to your very specific issue. Sorry about that!
If we are handling stuff that was already saved from the very beginning or the addition isn't new at all and can be easily found at some specific method, you can simply delete the new @variables that you created there and go call that original method as many times as needed.
Let us suppose that our original intention with this script was to keep track of the First Actor's Class in the Database.
Code:
class MyClass
def my_new_variable
$game_actors[1].class_id
end
end
Now any other scripts, both new or old ones, can call my_class.my_new_variable and it will return a given Class ID.
This implies that it will quickly load that specific data you are requesting and that's it!
And nope, it will not make your game crash ever again... if you know what you are doing!
An Exceptional Case: Booleans
When dealing with booleans, meaning true or false or even nil in Ruby, you MIGHT not go through this predicament at all.
As long as a method with the same name DOES exist.
XP & VX Example:
Code:
if my_class.my_new_boolean
print "My new boolean exists!"
else
print "It doesn't exist, yet. Even so, it is equal to nil."
end
VX ACE Example:
Code:
if my_class.my_new_boolean
msgbox "My new boolean exists!"
else
msgbox "It doesn't exist, yet. Even so, it is equal to nil."
end
But I need my new @variable to be set to true!
Then you've got a problem, my friend!
Yeap, now you DO need to erase your saved game sessions.
Or you can see if you go through ALL of your sessions and look for a perfect place to make the script call to assign it a true value... if that is the value it is supposed to be holding at that particular point.
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9
Maranatha!
The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.
My Original Stories (available in English and Spanish)
List of Compiled Binary Executables I have published...
HiddenChest & Roole
Give me a free copy of your completed game if you include at least 3 of my scripts!
Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Maranatha!
The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.
My Original Stories (available in English and Spanish)
List of Compiled Binary Executables I have published...
HiddenChest & Roole
Give me a free copy of your completed game if you include at least 3 of my scripts!
Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE