Save-Point
F12: The Key with the Misconception. - Printable Version

+- Save-Point (https://www.save-point.org)
+-- Forum: Games Development (https://www.save-point.org/forum-4.html)
+--- Forum: Development Discussion (https://www.save-point.org/forum-17.html)
+--- Thread: F12: The Key with the Misconception. (/thread-7498.html)



F12: The Key with the Misconception. - DerVVulfman - 06-13-2019

F12:
The Key with the Misconception

Internet Archive Backup Link from 2021

Hello friends, I wish to talk about the key that many in the RPGMaker community believe is a bugged and broken feature.  Nearly everyone has at one time talked about the dreaded F12 bug at some point in the course of their game development history.  But few ever stopped to consider, what is the actual issue with the F12 key itself.

The F12 key is not broken, nor is it bugged or contains an error.  The F12 key is merely the 'game reset' key built into your Game.Exe file.  If the player wishes to reset the game quickly, and doesn't wish to use the exit option in their game menu, they can hit the F12 key.  It's merely that simple a feature.

The problem that people have designated as the F12 Bug is really an issue with the way a script was written.  To be more specific, it has to do with something that the author had overlooked when he or she utilized the 'alias' command to add some new piece of code.

Now to be fair, many scripters were never given a course on writing scripts for RPGMaker.  So the cause of the so-called bug was never widely revealed, nor any manner to prevent its occurrence.

What has been widely and incorrectly referred to as the F12 bug is actually a Stack error, the typical error message displaying 'stack error too deep'.  So you may ask yourself the question "What is a stack error?"

This particular error is properly called a 'stack overflow' where a program is trying to use more memory than what's been set aside.  You could have made an infinite 'loop...end' block to add new monsters to your game and forgot to add a feature to exit the loop.  But when a stack error crops up because the player hits the F12 key, it is because of something slightly different.

When you start your game, all the scripts get loaded into memory whether they're the ones from your project's Script Database or if they are special hidden class scripts.  And hitting the F12 key forces the game engine to reload the scripts each and every time.

However, many scripters use the 'alias' command to attach new code to an already existing method. This practice is fine enough and looked favorably. It is considered to be preferable to use this tactic to add new code instead of rewriting the original code. But there are times where the use of an alias command creates something that coders call an 'infinite loop'.

An infinite loop in a game can cause the game to stall indefinitely and should be avoided at all costs.  But an infinite loop caused by the use of the alias command is more insidious.  Whether you run a fresh game or hit the F12 key, your game should load the original script, and then the custom script with the alias command to attach the new code. But some custom scripts, when the F12 key is pressed, forces the reloading of an already altered script with the alias command already embedded and this coerces the game engine to continue attaching code into this same script over and over, ad infinitum.  So as the script continues to load, it takes up more and more memory until the memory allocated is used up and the game crashes as a result of a stack overflow.

Now, this is not to say that the person writing the script did anything bad.  The scripter merely needed to make sure that the script only runs the 'attachment' to the original script once.  It's actually easy to do once you know what script is causing the crash.  You just need to encapsulate the line of code in the script that creates the relationship between the new/aliased code and the original as seen below:


Code:
if @f12_stack_fix_input_update.nil?
 alias fullkeyboard_update update
 @f12_stack_fix_input_update = true
end


Let's assume that someone is attaching some new code to the Input module itself, and this code adds full keyboard control. Fine enough, and would work normally until the F12 key is struck. But funny things happen with the hidden classes, and you would very likely get a stack overflow reloading.  But by adding a test for the existence of an instance variable that exists nowhere else in the project (the @f12_stack_fix_input_update value), we force the update method to be altered with this custom code only once.

But as you can see, it is not the fault of the F12 key and not the fault of the RPGMaker engines itself.  Those making the new scripts were never informed about the prevention of stack overflow in their code.  And the community of scripters merely pointed their finger at the F12 key as the simplest of explanations.



RE: F12: The Key with the Misconception. - kyonides - 06-13-2019

A So Called Right to Reply!
Laughing

The misconception is NOT to call it a bug. You see, when an engine developed to extend ye old RM2K and its cousin RM2K3, they let a committer or participant include C and C++ code slightly based on the RGSS and Ruby code. That was a mistake! Shocked It also featured the some stupid F12 reset errors! So it's been definitely the F12 feature inclusion the one that's causing the troubles here.

Since XP they just reset Graphics, Audio, probably even Input, but they never reset Ruby itself! Angry So far it seems Ruby has never included a reset feature ever. Happy with a sweat  Because of this lack of vision on behalf of the Ruby core team, "DropBrain" just let the C++ side reload the whole bunch of scripts! (Not from memory but by reading the Scripts file once again...) If we were working with pure Ruby or any other OOP scripting language, you'll never reload the scripts!

In this sad scenario they could have done something about that like:

1. Just calling the Main script. (It might even work the best if it has been a hidden script and then do what's mentioned below.) Sarcasm
2. Do what I'm trying to achieve, to implement a simple script call to set the default starting script (the first script after Main) and let the F12 button call a hidden method to set a new value to $scene global variable. Laughing
3. Implement any other creative method anybody could come up with! Laughing + Tongue sticking out
4. Implement the fake but working solution: just use unless $@ at the end of the alias method. Confused


RE: F12: The Key with the Misconception. - DerVVulfman - 06-13-2019

A response to above showing his 2019 post date
Post 2 by Kyonides

Apologies.  But nothing you said actually points blame at the F12 game reset feature, except that resetting the game and the scripts is bad.

I outlined how the issue is a stack error caused by infinite loops. And I explained how this is caused by the manner in which someone writes a script and doesn't account for infinite loops in their own personal coding.  Of course, RPGMaker 2000 or 2003 did not have this issue because there was no way for anyone to affect the underlying code of the system. There is no F12 reset errors with the native code.  Only when a scripter alters the actual ruby scripts in a manner that causes the stack error on script reset do we have this issue.

But I also described a method to prevent such stack errors from occuring.  The method taught to me a decade ago by SephirothSpawn.  So this issue, its root cause, and methods to prevent stack errors have been known for quite a long time. Unfortunately, this seems to be an ignored or overlooked subject.

Can I blame scripters?  Partially, yes.  And partially no.  But I fully blame those that are aware that this is caused by their own code and if they are told there are ways to prevent the error from occurring.  I know of a few that say 'Meh, I'm using an F12 blocker script'.... That's a 'few', as in more than two or three.

There are a couple of scripters out there where I found these specific stack errors in their code. Both of which, I not only told them how to prevent the stack error from cropping up but presented them with their code fixed by the inclusion of a mere three lines (the if....end block around their alias). That they openly said they would prefer to use an F12 blocking script than fix their own code made me feel embarrassed to be a programmer.

Ruby doesn't need a reset feature.  Ruby is a programming language like C++, Basic, Fortran, Cobal, Pascal.  None of which have a reset feature, and I have never heard of a language ever including such.  If you were to apply the same concept towards the script database being C++, you would have the same issue.  If a coder were to use a command similar to 'alias' to attach code, they too would likely be prone to a similar stacking loop error.  

A protest about needing the scripts to reload is falling on deaf ears.  I have seen entertaining applications made for RPGMaker XP that allows you to run a project and let you actively change data, graphics, and even ruby scripts whilst the project is running. Yes, this application allows contents described to reset while the game is running.  So reloading the scripts is a non-issue except to those that write scripts poorly.

Hiding the main method which is located at the bottom of the scripts library is a non issue.  In programming languages such as Ruby or C+, the entire operation of the program begins with the main method.  And from there it branches out.  Hiding the main method is not wise at all.  And there are those who may find need to alter the main method to include options such as the changing of default fonts, game speed, or the like.

And you speak of trying to achieve other methods than what I already described above.  Yes, there are scripts dedicated towards the F12 key, mainly by preventing the player to reset their game and making the F12 key worthless.  This doesn't fix the actual issue with a script causing a stack overflow, but covers it up with a bandage.  Your concept, if I read that correctly, is to prevent the scripts themselves from resetting, interesting as it sounds.  I would love to see that.   Whilst a bandage, it is certainly a more appealing variant.  I would wish you luck, lazy scripter you.

This is not an argument whether the F12 key is at fault.  It isn't if someone writes code and knows how to properly prevent their code from reloading infinitely.  The existence of a stack overflow error is a matter of fact, whether it is one formed within C+ programming, Ruby scripts, Basic programs, Assembly code, or the like.  But as always, the community of scripters merely pointed their finger at the F12 key as the simplest of explanations.


RE: F12: The Key with the Misconception. - kyonides - 06-13-2019

Sadly I have to discredit your claim of languages not needing to include any sort of reset feature. You ignore the fact that CRuby, the original implemention of Ruby in C, lets you embed Ruby to use it in C and C++ based applications. It needs an initializer, a setup and a main loop plus cleanup and termination steps. It doesn't include a reset like feature even if some programmers already pointed out that it would be a great addition. If you already know that as a programmer (not just as a scripter), you should be compelled to overcome that inconvenience (like undefining class methods via C API?)

You said one can't customize a Main script if it were hidden but you know well that's a lie. It's quite easy to create a basic main loop script that include calls to specific methods you leave in any available section of the editor. Modularity makes it possible and keeps it simple.


RE: F12: The Key with the Misconception. - DerVVulfman - 06-13-2019

A response to above showing his 2019 post date

Post 4 by Kyonides

In your description of CRuby, you fail to recognize that Ruby and RGSS also have initialize and dispose methods as defaults.  While you may visit the Scene_Battle code of the default scripts and do not see any initialize method, it is present and is set to the system defaults.  Likewise, so too is the dispose method in Scene_Battle.  This holds true to other classes within Ruby. I have used 'alias' methods to classes where an initialize method does not appear visible, yet they are there none-the-less.

However, you're not accepting that we are dealing with an interpreter version where the custom scripts (ie the Scripts Library) is being loaded from an encrypted file after the Game.Exe file loads.  Thus, we are not having the actual code embedded in a C+ engine.  Even so, a faulty scripter could still cause a stack overflow if their code was wrong. 

In regards of the main method, I clearly stated "Hiding the main method is not wise at all" and not that hiding the method couldn't be done.  You as well as I and anyone with programming language in C programming (among others) know that the main method is the starting / jumpoff point of a program.

In both of these cases, I feel your statements are argumentative and meant solely to hide the fact that a coder could use a simple technique to prevent stack overflows.