Chaos Project

RPG Maker => RPG Maker Scripts => Topic started by: G_G on August 17, 2011, 11:57:28 pm

Title: Reload Scripts at Runtime
Post by: G_G on August 17, 2011, 11:57:28 pm
When Blizzard said something about it being really difficult to reload scripts while playing. While looking through Blizzard's script extractor, why couldn't we just re-eval all the scripts? For the most part it worked. But then when it reloaded main it went back to the title screen. But then I just added a little check to see if the script name was in the Exclude.
Exclude = ["Main"]
for script in load_data("Data/Scripts.rxdata")
 if (!Exclude.include?(script[1]))
   eval(Zlib::Inflate.inflate(script[2]))
 end
end


Then just for safety precautions, just reload the scene you're on.
$scene = $scene.class.new


It seemed to work alright without any issues. Of course I'm expecting F0, Blizzard, or someone else to come in here and prove me wrong. xD Anyways its a quick workaround if you're tired of reloading your game constantly.

This isn't the full package, you'll have to put this in your own method or event or whatever. And for scripts you don't want to load, put the name that you entered in the Exclude array.
Title: Re: Reload Scripts at Runtime
Post by: Blizzard on August 18, 2011, 02:19:24 am
Reloading the scripts can cause unexpected errors. One of the first cases that would come to my mind would be the F12 reset bug fix. The $game variable is set the first time and when you run all scripts a second time, the variable would cause the script to abort right at the beginning. As you said, it's not impossible to do, but generally it's a bad idea. You would need a special script to "reset" the state of the Ruby VM before you eval all scripts again. This cannot be automated as it depends on the scripts you are using.

Also, when you re-eval all scripts, you have to keep in mind that all these classes already exist. Your old definitions would be overwritten and the aliasing applied afterwards can cause even more expected behavior, especially in classes/modules that are not yours. If you alias e.g. Input#update once, then a second run would alias it another time with the same name and actually just cause the whole thing to turn into an infinite recursive loop. Using safety precautions everywhere such as "if defined?()" is not much of a option either as you would have to yet again edit all the scripts.

It's not really possible to do it in an easy way. Deal with it. xD
Title: Re: Reload Scripts at Runtime
Post by: ForeverZer0 on August 18, 2011, 02:21:32 am
Does this actually change anything, or just refresh the scene?  Without every re-entering "main", I don't see how it would actually change any of the globals, since they never lose scope, and they are never re-initialized.  Just at a glance, the only line that I see even doing anything is "$scene = $scene.class.new".  I'm too lazy to test at the moment, though. :P
Title: Re: Reload Scripts at Runtime
Post by: Zeriab on August 18, 2011, 03:05:58 am
You can open a new instance of the game and close the current one.
Title: Re: Reload Scripts at Runtime
Post by: G_G on August 18, 2011, 05:03:01 am
Quote from: Blizzard on August 18, 2011, 02:19:24 am
Reloading the scripts can cause unexpected errors. One of the first cases that would come to my mind would be the F12 reset bug fix. The $game variable is set the first time and when you run all scripts a second time, the variable would cause the script to abort right at the beginning. As you said, it's not impossible to do, but generally it's a bad idea. You would need a special script to "reset" the state of the Ruby VM before you eval all scripts again. This cannot be automated as it depends on the scripts you are using.

Also, when you re-eval all scripts, you have to keep in mind that all these classes already exist. Your old definitions would be overwritten and the aliasing applied afterwards can cause even more expected behavior, especially in classes/modules that are not yours. If you alias e.g. Input#update once, then a second run would alias it another time with the same name and actually just cause the whole thing to turn into an infinite recursive loop. Using safety precautions everywhere such as "if defined?()" is not much of a option either as you would have to yet again edit all the scripts.

It's not really possible to do it in an easy way. Deal with it. xD


Yeah I know. :S I knew you'd bring your lingo to show me up again. xD

Quote from: ForeverZer0 on August 18, 2011, 02:21:32 am
Does this actually change anything, or just refresh the scene?  Without every re-entering "main", I don't see how it would actually change any of the globals, since they never lose scope, and they are never re-initialized.  Just at a glance, the only line that I see even doing anything is "$scene = $scene.class.new".  I'm too lazy to test at the moment, though. :P


You'd have to reinitialize the globals if you modified the global classes. This would more or so be helpful with on the fly menu positioning or something. This was more or so a discussion type thing and not a "here's a script, copypasta and use it." kind of thread.

Quote from: Zeriab on August 18, 2011, 03:05:58 am
You can open a new instance of the game and close the current one.


True and thats probably the best way to go at it. But for people who have issues loading MIDI files with RMXP this would be better if it was perfected that is.

Anyways I know this method isn't even near half-way to being perfect but it works for dirty jobs like positioning menu windows and whatnot.
Title: Re: Reload Scripts at Runtime
Post by: ForeverZer0 on August 18, 2011, 12:45:12 pm
Quote from: game_guy on August 18, 2011, 05:03:01 am
You'd have to reinitialize the globals if you modified the global classes. This would more or so be helpful with on the fly menu positioning or something. This was more or so a discussion type thing and not a "here's a script, copypasta and use it." kind of thread.


Yeah, I know what this is, I'm saying what is being accomplished by re-loading the scripts into Ruby's scope?  They are still the same as they were when the game loaded, your not actually changing anything except creating errors that Blizz mentioned above. The only actual thing that changes anything is the re-initializing the scene, but no other variables except what it changes are going to modified. 
Title: Re: Reload Scripts at Runtime
Post by: G_G on August 18, 2011, 01:36:56 pm
I'm aware. What I meant is that I expected people to already know that or to figure that out and finish the script themselves.
Title: Re: Reload Scripts at Runtime
Post by: nathmatt on August 18, 2011, 01:37:59 pm
y use
$scene = $scene.class.new


instead of just

$scene.initialize


Title: Re: Reload Scripts at Runtime
Post by: ForeverZer0 on August 18, 2011, 05:15:02 pm
Quote from: nathmatt on August 18, 2011, 01:37:59 pm
y use
$scene = $scene.class.new


instead of just

$scene.initialize



Because "initialize" is a private method and will result in a crash if you attempt to call it directly.