Professional Documents
Culture Documents
Graphical Object Global Reference
Graphical Object Global Reference
Graphical Object Global Reference
# v 1.21 VXACE
# A debugger script.
# Created by Mithran
# hosted at forums.rpgmakerweb.com
%q(
AUTHOR'S NOTE: The following description primarily describes the VX (RGSS2)
version of the crash. The VX ACE crash shares some circumstances with the VX
crash. This script and instructions were written to address the VX issue then
updated to work in VX ACE. This script itself may or may not stop crashes in ACE
as it did with VX, but it can be used to log undisposed sprites and stop the
error from happening in the first place.
The cause of a given Game.exe crash could be any number of things - anything that
doesn't create throw an error in Ruby, but causes an unhandled exception in one
of the 'hidden' classes.
After extensive testing, I was finally able to recreate the circumstances leading
up to one such exception that, if left unhandled, could lead to Game.exe crash.
Due to the way GC is implemented, you are unlikely to see an immediate effect
when the situation comes up. It could be several scene changes down the line
before the crash finally happens. To make matters worse, following the exact
same course of action will yield completely different results, making it seem
as though the crashes are random. In addition, there is yet another circumstance
which I have still been unable to pinpoint, but I suspect has something to do
with the order in which assets associated with the Graphical Object are claimed
by the GC, or the amount of screen rewdraws that have taken place,
that allows the GO to be cliamed without causing an exception and
thus making it even harder to find.
In essence: you could be suffering from an unstable game and not even know it.
So that is where this little script comes in. This does the following:
* v 1.1 'Lazy' fix has been superceeded to prevent crashes caused by disposal of
these errant sprites. Lazy fix only works if debug criticial disposal has
been disabled.
Version History:
v 1.2 VX ACE
Discovered possibility of crash in RGSS3. Thanks to Galv for bringing the
problem to my attention and supplying a script to use as a test case.
Updated logging features to specificially work with VX ACE. RGSS Console must
be enabled to recieve live updates.
Added GOBJ_ABRIDGED_LOG option.
Altered some terms in the log. Specifically changed the term 'non-critical
object'
to 'Memory Leak' so the term 'Critical Object' can be searched in the log.
Time in log now refers to creation time of the object.
v 1.1
Discovered a new condition for a Game.exe crash. Updated script to trap and log
this error also.
v 1.01-1.05
Minor bugfixes, improved logging, added consideration for Plane objects viewport
method error
v 1.0
Initial Release
)
# Creates a global refrence list to all graphical objects, preventing them from
# ever being garbage collected. Objects from this list are removed when the object
# runs its dispose method, thereby allowing them to be GC'd.
# Has a built in layer to notify the player if the scene changes with live
# graphical objects in play. As a rule, this should almost never happen. Certain
# scripts have sprites that are used across every scene and never disposed,
# thus intentionally having an additional global reference (such as mouse script)
# As such, they should never generate a critical error. However, they can be
manually
# exempted from being detected by this script by using the instance method
# 'gobj_exempt' on the sprite. In the case of Woratana's Simple Mouse/Jets Mouse
# simply place my script as low as possible on the scripts list, but above Main,
# to avoid conflicts.
GOBJ_LOG_NON_CRITICAL = true
# if set to true creates log entries for non-critical objects that are not disposed
# between scenes. Only works if GOBJ_DEBUG_FILE is also set to true.
# if you have a game.exe crash that seems to pop up randomly after a while
# try using this and see if there are any unfreed objects at all
GOBJ_LAZY = false
# turn this to true and graphical objects without disposed viewports will be
disposed
# when the scene changes. It is recommended this setting not be used and instead
# the code be cleaned up directly.
# v 1.21 This function now only affects sprites without disposed viewports.
# Sprites must be kept in memory to prevent a crash if their viewport has already
# been disposed.
GOBJ_DEBUG_CRITICAL_DISPOSAL = false
# disables disposal of GO that have had their viewports already disposed
# this is only considered unsafe if screen redraws have taken place between the
# time that the viewport and sprite are disposed.
# Some of the base scripts dispose viewport immediately before the sprites, which
# has never been known to cause errors, therefore, this option has been added to
# circumvent dealing with these type of objects. Turn this on if you continue
# to get Game.exe crashes that are not logged.
GOBJ_ABRIDGED_LOG = false
# logs only the basic info about the created object and not the whole stack
GOBJ_NOTIFY_REPEAT_DISPOSE = true
# notifies (to console) when a repeat dispose is attempted on the same object
# while normally ignored, repeat disposes are indicative of poor sprite control
GOBJ_LOG_REPEAT_DISPOSE = true
# logs repeat disposes
end
cl.class_eval {
def gobj_exempt
$gobj.delete_if { |a| a[0] == self }
end
} # class eval
} # each class
class Scene_Base
alias main_gobj main unless $@
def main
if $TEST && $gobj.size > 0
p 'Live Graphical Object List:', $gobj.collect { |o| o[0..1] } if
GOBJ_NOTIFY_LEAK
$gobj.clone.each { |o|
next o[0].gobj_exempt if o[0].disposed?
critical = o[0].viewport && o[0].viewport.disposed?
print "#{o[0]} created in #{o[1]} is a potential for Game.exe crash!\n" if
GOBJ_NOTIFY_CRITICAL && critical
if GOBJ_DEBUG_FILE && !o[3] && (critical or GOBJ_LOG_NON_CRITICAL)
gobj_log_to_file(o, critical)
o[3] = true # do not log again this instance
end
if GOBJ_LAZY && !critical
o[0].dispose
end
} # close $gobj.each
end # debug branch
main_gobj #original method
end
end
module Kernel
end
class Viewport
alias dispose_gobj dispose unless $@
def dispose
@disposed = true
dispose_gobj
end
def disposed?
@disposed
end
end
ScriptNames = {}