Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Remove 'Script is Hanging'

Sorry, I thought I was being clear enough. ^^;

I remember a very old fix/script for removing the 'Script is Hanging' error message from RPG Maker. I'm looking for a way to remove this error message.

The reason is 'cause some properly functioning scripts give this error message if the computer is lagging a bit at that moment, which is quite annoying. If the message came a little bit later (or not at all) the game wouldn't be crashing -- it just needs to load a bit more. :)
 
Graphics.update
Refreshes the game screen and advances time by 1 frame. This method must be called at set intervals.

  • loop do
    Graphics.update
    Input.update
    do_something
    end

If this method is not called in 10 seconds or more, the program will view the script as having run out of control and will force a quit.
 
So, hold on... (Sorry, I'm a bit of a failure at RGSS. ^^; )
- If Graphics.update isn't called for 10 seconds, the game crashes.
- Thus it needs to be called within a time consuming process, so it doesn't crash.
- Thus, I need to know exactly where these time consuming processes are.

Am I correct? If so, suppose that the game freezes when loading the Items menu. The most laggy I can imagine from that is the list of items itself. Where would I put Graphics.update? I would appreciate it a lot if you could show it in an example with the RTP Scene_Items. ^^;

I reckon that if I put Graphics.update simply after one of the other updates like this...

Code:
  def update

    # Update windows

    @help_window.update

 

Graphics.update

 

    @item_window.update

 

Graphics.update

 

    @target_window.update

    # If item window is active: call update_item

    if @item_window.active

      update_item

      return

    end

    # If target window is active: call update_target

    if @target_window.active

      update_target

      return

    end

  end

It's not really helping and just making things more laggy?
 
Which custom scripts are you using? Or this is happening with only the default scripts?

What is causing the computer to lag more than 10 seconds?
If you have a bunch of other apps running, try closing them.
If your computer doesn't meet the minimum requirements for RMXP, you may just be S.O.L.

If it's your game that's causing the lag, upload an unencrypted copy & I'll take a look.
 
Ok. Here's a quick something that could help. Basically rather than calling Graphics.update and forcing the Graphics module to update, it'll check the last update and only update if the last update was more than x seconds ago.

Code:
class << Graphics

  Force_Update_Seconds = 8

  unless self.method_defined?(:seph_hanging_update, :update)

    alias_method :seph_hanging_update, :update

  end

  def update

    seph_hanging_update

    @last_update = Time.now

  end

  def hanging_update(seconds = Force_Update_Seconds)

    update if Time.now > @last_update + seconds

  end

end

Now in rather process consuming functions (such as reading and setting pixels, generating paths (pathfinding), etc.) at the end of certain block, just add

Graphics.hanging_update

or

Graphics.hanging_update(seconds)


Such as below:
Code:
class Bitmap

  def get_pixel_pallette

    colors = []

    for x in 0...width

      for y in 0...height

        c = get_pixel(x, y)

        colors << c unless color.include?(c)

      end

      Graphics.hanging_update

    end

    return colors

  end

end

Now when such a method is called, it'll pass from left to right and up to down a bitmap collecting colors (which is a consuming process). Once it finishes every column of pixels, it'll call that Graphics.hanging_update method to try to prevent the hanging error to occur forcing to update the graphics module.

Here's a list of consuming methods for the default RGGS library:
Bitmap
- get_pixel
- set_pixel
- hue_change
Sprite
- angle


So do a search in your scripts. If you see any line of code with those keywords and they are indented 6-8 spaces, throw Graphics.update_hanging on the line beneath them.




Your other error might not be a process that is consuming too much time, as a loop that just is never executing. As simple as
Code:
 

loop do

 

end

It keeps going through that block (although nothing is happening) but because nothing is happening and it is never exited, you'll eventually get an error. There could just be a bad range or block that just never terminates.
 

Zeriab

Sponsor

The snippet you remember was probably the one I cooked up two years ago.
Here is the topic I made back then:
As many of you probably know you get a 'Script Hanging' error if a script takes too long to process.
More accurately, if the Graphics.update is not called in about 10 seconds the engine will assume an endless loop or something similar has happen. It will therefore give the 'Script Hanging' error.
This code snippet works by calling Graphics.update if this has not happened in a long time. A separate thread is running which checks up on the time. It should not affect the speed of the main thread in any significant way. It will not work if you have DLL calls which takes too long though.
THIS IS A SCRIPT YOU DON'T JUST ADD
Adding this script comes at the of your code becoming non-deterministic. This is bad, very bad. Also I do not have a monitor on critical parts, which gives the possibility of race conditions. I think that Graphics.update does have mutual exclusion, but I am not sure.
And even if it has, what do you think happens if Graphics.update is called while you are in the process of creating a sprite?
I expect this mainly to be for scripters to help their debugging and testing of stuff.
Since the script will not call Graphics.update unless 4 seconds has passed since the last call to Graphics.update I do not expect it will have too much of an effect.
[rgss]if @zer_no_hang_stack.nil?
  ##
  # Change the Graphics module so it contains the time of the last update
  # Add a getter for the time property
  #
  module Graphics
    # Alias the update method (you have to do it this way since Graphics is a module)
    class << self
      alias no_hang_update update
    end
    ##
    # Change the update method
    #
    def self.update
      @@time = Time.now
      self.no_hang_update
    end
    ##
    # Retrieve the Time at the last update
    #
    def self.time
      # Protection if this method is called before the first update
      @@time = Time.now if @@time.nil?
      return @@time
    end
  end
 
  ##
  # A separate thread that will run and keep track of the time since the last
  # update
  #
  Thread.new {
    loop do
      # Lets the thread sleep for a while to minimize CPU usage
      sleep 1
      # If more than 4 seconds has passed since the last update
      if Time.now - Graphics.time > 4
        # Update the graphics
        Graphics.update
      end
    end
  }
 
  @zer_no_hang_stack = true
end
[/rgss]

Use it wisely and only if there is an actual need.

*hugs*
- Zeriab

I don't believe its possible to remove the error in the general case without hacking or re-engineering the engine. :sad:
Note that Graphics.update will try to enforce the given fps. Putting two Graphics.update calls in an update loop will thus feel like the speed have been halved.

@Seph:
I believe that the Sprite.angle method is safe to use in respect to the error since the actual projection is made in the engine. (I.e. it happens during a Graphics.update call while the Ruby interpreter is not running)
I haven't tested this theory though.

*hugs*
 
Ah. I was thinking about doing this with a thread, but really have never worked with them and when i do, they just never worked out for me.

As far as the angle method goes, I just read through the help file and methods:
angle
The sprite's angle of rotation. Specifies up to 360 degrees of counterclockwise rotation. However, drawing a rotated sprite is time-consuming, so avoid overuse.

Only reason I included it in the list. I am sure you are right though. It would probably only drop the fps and assigning an angle value 4000 times before the sprite was updated would have no effect.
 
Thank you for all your replies. :) From what you've said, Zeriab, I think it would be better to use Seph's. It seems less likely to mess anything up.

I get this error on your script, though, Seph:

Script 'Graphics Update Fix' line 3: ArgumentError occurred.
wrong number of arguments(2 for 1)

for

unless self.method_defined?:)seph_hanging_update, :update)
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top