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.

New AntiLag Script // Solution for Script Command Problem

yeah first of all I have a new AntiLag Script, which uses an improved version of Nears Event AntiLag Script (it aliases everything for example and its faster) and some new things.. all features are written down in the script..

Code:
#===============================================================================
# ** AntiLag Script
#-------------------------------------------------------------------------------
#
# f0tz!baerchen
# 0.71
# 06.01.2007
#
#-------------------------------------------------------------------------------
#
# Credits: 
# Chaosg1 (for testing ;) )
# NearFantastica (for the Event AntiLag I used and improved)
#
#-------------------------------------------------------------------------------
#
# Features:
# - Event AntiLag: Event (and their Sprites) which are not on the screen are 
#   not updated except they run on "Autostart" or "Parallel Process" or they
#   have an empty comment in the first line
# - High Priority: Game can be run on high priority
# - Smooth Antilag: the Event AntiLag does only work fine if the events are
#   distributed over the whole map, but when there are many events at the same
#   place it lags again. If the script notices that the CPU utilization
#   gets higher than $antilag.max_cpu_utilization it will slow down the game and
#   reduce the framerate as long as needed.
#
#-------------------------------------------------------------------------------
#
# Settings: 
# can be changed anytime during the game. They are found at the end of the 
# script.
#
#===============================================================================

#-------------------------------------------------------------------------------
# * SDK Log Script
#-------------------------------------------------------------------------------
SDK.log('AntiLag', 'f0tz!baerchen', 0.71, '06.01.07')

#-------------------------------------------------------------------------------
# Begin SDK Enabled Check
#-------------------------------------------------------------------------------
if SDK.state('AntiLag') == true
  
#===============================================================================
# Class for Antilag Settings
#===============================================================================
class Antilag_Settings
  
  attr_accessor :event
  attr_accessor :max_cpu_utilization
  attr_accessor :cpu_tolerance
  
  #-----------------------------------------------------------------------------
  # initializes default settings
  #-----------------------------------------------------------------------------
  def initialize
    @event = true
    @high_priority = true
    @max_cpu_utilization = 100
    @cpu_tolerance = 20
    @SetPriorityClass = Win32API.new('kernel32', 'SetPriorityClass', 
                                     ['p', 'i'], 'i')
    @GetProcessTimes = Win32API.new('kernel32', 'GetProcessTimes', 
                                    ['i','p','p','p','p'], 'i')
  end
   
  #-----------------------------------------------------------------------------
  # turns high priority on/off
  #-----------------------------------------------------------------------------
  def high_priority=(value)
    @high_priority = value
    
    if @high_priority
      @SetPriorityClass.call(-1, 0x00000080) # High Priority
    else
      @SetPriorityClass.call(-1, 0x00000020) # Normal Priority
    end
  end
  
  #-----------------------------------------------------------------------------
  # returns the current CPU Utilization
  #-----------------------------------------------------------------------------
  def get_cpu_utilization
    
    # uses API Call to get the Kernel and User Time
    creation_time = '0' * 10
    exit_time = '0' * 10
    kernel_time = '0' * 10
    user_time = '0' * 10
    @GetProcessTimes.call(-1, creation_time, exit_time, kernel_time, user_time)
        
    # converts times into integer (in 100ns)
    kernel_time = kernel_time.unpack('l2')
    user_time = user_time.unpack('l2')
    kernel_time = kernel_time[0] + kernel_time[1]
    user_time = user_time[0] + user_time[1]
    
    # takes differences to calculate cpu utilization
    if @old_time != nil
      timer_difference = Time.new - @old_timer
      time_difference = kernel_time + user_time - @old_time
      result = time_difference / timer_difference / 100000
    else
      result = $antilag.max_cpu_utilization
    end
    
    # saves values (to calculate the differences, s.a.)
    @old_timer = Time.new
    @old_time = kernel_time + user_time
    
    return result
    
  end
  
end

$antilag = Antilag_Settings.new

#===============================================================================
# Scene_Map class
#===============================================================================
class Scene_Map
  
  #-----------------------------------------------------------------------------
  # update method, smooth antilag has been added
  #-----------------------------------------------------------------------------
  alias f0tzis_anti_lag_scene_map_update update
  def update
    
    f0tzis_anti_lag_scene_map_update
    
    if Graphics.frame_count % 20 == 0 and $antilag.max_cpu_utilization <= 100
    
      # calculates difference between max utilization and current utilization
      abs = $antilag.max_cpu_utilization - $antilag.get_cpu_utilization
    
      # changes Frame Rate if difference is bigger than the tolerance
      if abs.abs >= $antilag.max_cpu_utilization * $antilag.cpu_tolerance/100.0
        Graphics.frame_rate = [[10, Graphics.frame_rate + abs / 2].max, 40].min
      end
      
    end
        
  end
  
end


#===============================================================================
# Game_Event Class
#===============================================================================
class Game_Event
  
  #-----------------------------------------------------------------------------
  # for AntiLag, decides, if an event is on the screen or not.
  #-----------------------------------------------------------------------------
  def in_range?
        
    # returns true if $event_antilag is false or the event is an 
    # Autostart/Parallel Process event or it has an empty 
    # comment in the first line
    if not $antilag.event or (@trigger == 3 or @trigger == 4 or 
    (@list != nil and @list[0].code == 108 and @list[0].parameters == ['']))
      return true
    end
          
    screne_x = $game_map.display_x
    screne_x -= 256
    screne_y = $game_map.display_y
    screne_y -= 256
    screne_width = $game_map.display_x
    screne_width += 2816
    screne_height = $game_map.display_y
    screne_height += 2176
    
    return false if @real_x <= screne_x
    return false if @real_x >= screne_width
    return false if @real_y <= screne_y
    return false if @real_y >= screne_height
    return true
            
  end
  
  #-----------------------------------------------------------------------------
  # update method
  #-----------------------------------------------------------------------------
  alias f0tzis_anti_lag_game_event_update update
  def update
    return if not self.in_range?      
    f0tzis_anti_lag_game_event_update
  end
  
end


#===============================================================================
# Sprite_Character Class
#===============================================================================
class Sprite_Character < RPG::Sprite
  
  #-----------------------------------------------------------------------------
  # update method, parameters added for Loop_Map, rebuild for 8dirs
  #-----------------------------------------------------------------------------
  alias f0tzis_anti_lag_sprite_char_update update
  def update
    return if @character.is_a?(Game_Event) and not @character.in_range?
    f0tzis_anti_lag_sprite_char_update
  end
  
end

end

#===============================================================================
# Settings
#===============================================================================

$antilag.max_cpu_utilization = 70 # the maximum CPU utilization, the script
                                  # try to stay under this value during changing
                                  # changing the frame rate. The lower this
                                  # value the higher will be the lag reduction
                                  # (and the smoothness, too), a value > 100
                                  # will disable this feature completely

$antilag.cpu_tolerance = 20       # this value tells the script how many % of
                                  # the CPU utilization change should be ignored
                                  # If you change it too a higher value you,
                                  # your Frame Rate will be more constant but
                                  # smaller lags will be ignored.

$antilag.high_priority = true     # set this to true if you want the game to run 
                                  # on high priority

$antilag.event = true             # set this to true to enable normal anti-lag
the effect of the smoother antilag can be seen on the second map..

----------------------------------------------------------------------

ok.. the second thing.. I think many people had the problem that the player hangs when a script command was used in an Event and the last line ended with an "false".. RGSS does something wrong there..

Code:
#===============================================================================
# Interpreter Class
#===============================================================================
class Interpreter
  
  #-----------------------------------------------------------------------------
  # * Script
  #-----------------------------------------------------------------------------
  def command_355
    # Set first line to script
    script = @list[@index].parameters[0] + "\n"
    # Loop
    loop do
      # If next event command is second line of script or after
      if @list[@index+1].code == 655
        # Add second line or after to script
        script += @list[@index+1].parameters[0] + "\n"
      # If event command is not second line or after
      else
        # Abort loop
        break
      end
      # Advance index
      @index += 1
    end
    # Evaluation
    result = eval(script)
    #---------------------------------------------------------------------------
    # If return value is false 
    # NEW: the last word of the code mustnt be false!
    #---------------------------------------------------------------------------
    if result == false and script[script.length-6..script.length-2] != 'false'
      # End
      return false
    end
    # Continue
    return true
  end
end
this small script prevents that error..

you can find the script here:
*klick* (just klick on "Scripts")

if you find bugs or other things to improve, please tell me.. normally the script should be fully compatible to everything..

EDIT: Chaosg1 just told me that the Smooth AntiLag in the demo does not work unless the script command fix is deleted.. I dont know why it works fine on my computer, but if you have the same problem like him, please tell me.. :)
 
Ok I have tested this and I must say that it DOES make a diference. Good Work F0tz. I love seing new Ideas being done.:P

Edit: Yay I am in Credits! lol
 
O_O;; Tested it and is awesome. Can't believe that with 127 events (yes, I checked how many were in that map) and no lag (well, a little, my PC has low RAM so that may be it), but anyways. Great anti-lag.
 
I'm not sure if this works, because I went to the second map and it was slow. I talked to the man and it didn't change.

Is this a problem? Or is it my computer?

I have a feeling it may be the problem you mentioned.

However, I noticed no lag what so ever on the first map, good job anyway.
 
This script will perform significantly worse under extreme test conditions.

The better compatibility can more than make up for it IMO, especially with the people that just toss Near's older rewrites of the update methods into all their games. :)

Also, the false thing isn't a bug. Scripts that return false aren't meant to progress the event yet, however not many people create complex systems that use it that way. Still extremely annoying to run into it changing a variable & wondering why RMXP is hanging. :)
 
well.. just tested around a bit.. the smooth antilag makes still some great problems I will fix..
(for example it only turns down the speed but not up again, etc.. ;) )
 

OS

Sponsor

This is pretty cool, though I think I got a seizure from Map Numero Dos. All of those Pink Haired Chicks fried my brain, man! Well, anyways, it looks good, and is quite handy. I give you 4 Glitchless Graphics out of 5

Score 4/5
~8r0k3n
 
thx thx.. I just updated the first post.. the new version should improve the mentioned things..

Edit: but its still not working perfectly.. smooth antilag is only needed when the game gets really laggy.. if there is only small lag, the script will slow down the game more than needed.. I'll try to fix that somehow.. -.-
 
ok.. one more update.. the script now uses the CPU Utilization (which gets very high if the game starts to lag) to check if the game lags.. if neccessary the frame rate is changed.. to optimize the script you can change the settings at the end.. to deactive it just change $antilag.max_cpu_utilization to a value > 100 ;)

Code:
#===============================================================================
# ** AntiLag Script
#-------------------------------------------------------------------------------
#
# f0tz!baerchen
# 0.7
# 04.01.2007
#
#-------------------------------------------------------------------------------
#
# Credits: 
# Chaosg1 (for testing ;) )
# NearFantastica (for the Event AntiLag I used and improved)
#
#-------------------------------------------------------------------------------
#
# Features:
# - Event AntiLag: Event (and their Sprites) which are not on the screen are 
#   not updated except they run on "Autostart" or "Parallel Process" or they
#   have an empty comment in the first line
# - High Priority: Game can be run on high priority
# - Smooth Antilag: the Event AntiLag does only work fine if the events are
#   distributed over the whole map, but when there are many events at the same
#   place it lags again. If the script notices that the CPU utilization
#   gets higher than $antilag.max_cpu_utilization it will slow down the game and
#   reduce the framerate as long as needed.
#
#-------------------------------------------------------------------------------
#
# Settings: 
# can be changed anytime during the game. They are found at the end of the 
# script.
#
#===============================================================================

#-------------------------------------------------------------------------------
# * SDK Log Script
#-------------------------------------------------------------------------------
SDK.log('AntiLag', 'f0tz!baerchen', 0.7, '04.01.07')

#-------------------------------------------------------------------------------
# Begin SDK Enabled Check
#-------------------------------------------------------------------------------
if SDK.state('AntiLag') == true
  
#===============================================================================
# Class for Antilag Settings
#===============================================================================
class Antilag_Settings
  
  attr_accessor :event
  attr_accessor :max_cpu_utilization
  attr_accessor :cpu_tolerance
  
  #-----------------------------------------------------------------------------
  # initializes default settings
  #-----------------------------------------------------------------------------
  def initialize
    @event = true
    @high_priority = true
    @max_cpu_utilization = 100
    @cpu_tolerance = 20
    @SetPriorityClass = Win32API.new('kernel32', 'SetPriorityClass', 
                                     ['p', 'i'], 'i')
    @GetProcessTimes = Win32API.new('kernel32', 'GetProcessTimes', 
                                    ['i','p','p','p','p'], 'i')
  end
   
  #-----------------------------------------------------------------------------
  # turns high priority on/off
  #-----------------------------------------------------------------------------
  def high_priority=(value)
    @high_priority = value
    
    if @high_priority
      @SetPriorityClass.call(-1, 0x00000080) # High Priority
    else
      @SetPriorityClass.call(-1, 0x00000020) # Normal Priority
    end
  end
  
  #-----------------------------------------------------------------------------
  # returns the current CPU Utilization
  #-----------------------------------------------------------------------------
  def get_cpu_utilization
    
    # uses API Call to get the Kernel and User Time
    creation_time = '0' * 10
    exit_time = '0' * 10
    kernel_time = '0' * 10
    user_time = '0' * 10
    @GetProcessTimes.call(-1, creation_time, exit_time, kernel_time, user_time)
        
    # converts times into integer (in 100ns)
    kernel_time = kernel_time.unpack('l2')
    user_time = user_time.unpack('l2')
    kernel_time = kernel_time[0] + kernel_time[1]
    user_time = user_time[0] + user_time[1]
    
    # takes differences to calculate cpu utilization
    if @old_time != nil
      timer_difference = Time.new - @old_timer
      time_difference = kernel_time + user_time - @old_time
      result = time_difference / timer_difference / 100000
    else
      result = $antilag.max_cpu_utilization
    end
    
    # saves values (to calculate the differences, s.a.)
    @old_timer = Time.new
    @old_time = kernel_time + user_time
    
    return result
    
  end
  
end

$antilag = Antilag_Settings.new

#===============================================================================
# Scene_Map class
#===============================================================================
class Scene_Map
  
  #-----------------------------------------------------------------------------
  # update method, smooth antilag has been added
  #-----------------------------------------------------------------------------
  alias f0tzis_anti_lag_scene_map_update update
  def update
    
    f0tzis_anti_lag_scene_map_update
    
    if Graphics.frame_count % 20 == 0
    
      # calculates difference between max utilization and current utilization
      abs = $antilag.max_cpu_utilization - $antilag.get_cpu_utilization
    
      # changes Frame Rate if difference is bigger than the tolerance
      if abs.abs >= $antilag.max_cpu_utilization * $antilag.cpu_tolerance/100.0
        Graphics.frame_rate = [[10, Graphics.frame_rate + abs / 2].max, 40].min
      end
      
    end
        
  end
  
end


#===============================================================================
# Game_Event Class
#===============================================================================
class Game_Event
  
  #-----------------------------------------------------------------------------
  # for AntiLag, decides, if an event is on the screen or not.
  #-----------------------------------------------------------------------------
  def in_range?
        
    # returns true if $event_antilag is false or the event is an 
    # Autostart/Parallel Process event or it has an empty 
    # comment in the first line
    if not $antilag.event or (@trigger == 3 or @trigger == 4 or 
    (@list != nil and @list[0].code == 108 and @list[0].parameters == ['']))
      return true
    end
          
    screne_x = $game_map.display_x
    screne_x -= 256
    screne_y = $game_map.display_y
    screne_y -= 256
    screne_width = $game_map.display_x
    screne_width += 2816
    screne_height = $game_map.display_y
    screne_height += 2176
    
    return false if @real_x <= screne_x
    return false if @real_x >= screne_width
    return false if @real_y <= screne_y
    return false if @real_y >= screne_height
    return true
            
  end
  
  #-----------------------------------------------------------------------------
  # update method
  #-----------------------------------------------------------------------------
  alias f0tzis_anti_lag_game_event_update update
  def update
    return if not self.in_range?      
    f0tzis_anti_lag_game_event_update
  end
  
end


#===============================================================================
# Sprite_Character Class
#===============================================================================
class Sprite_Character < RPG::Sprite
  
  #-----------------------------------------------------------------------------
  # update method, parameters added for Loop_Map, rebuild for 8dirs
  #-----------------------------------------------------------------------------
  alias f0tzis_anti_lag_sprite_char_update update
  def update
    return if @character.is_a?(Game_Event) and not @character.in_range?
    f0tzis_anti_lag_sprite_char_update
  end
  
end

end

#===============================================================================
# Settings
#===============================================================================

$antilag.max_cpu_utilization = 70 # the maximum CPU utilization, the script
                                  # try to stay under this value during changing
                                  # changing the frame rate. The lower this
                                  # value the higher will be the lag reduction
                                  # (and the smoothness, too)

$antilag.cpu_tolerance = 20       # this value tells the script how many % of
                                  # the CPU utilization change should be ignored
                                  # If you change it too a higher value you,
                                  # your Frame Rate will be more constant but
                                  # smaller lags will be ignored.

$antilag.high_priority = true     # set this to true if you want the game to run 
                                  # on high priority

$antilag.event = true             # set this to true to enable normal anti-lag

the link to the demo etc.

@all the guys who know more about API calls than me: is there a way to optimize the get_cpu_utilization method?
 
Your computer can freeze by changing a program's priority, that lags (=heavy). On the other hand, if the computer has not such a strong CPU it works fine, however, Game.exe will equal windows or even goign higher, and the Kayboard Input response will be REALLY weird (beleive me I tried). You pres Up, it takes one ore 2 seconds before your character starts two move (however NO lag!! graphical) and thne it moves 3 tiles instead of one even if you release it within a fraction of a second...

It could be me off course.
 
the priority isnt changed.. (only once when starting the game and if you want it)

the script only does exactly what I said.. it reduces the Graphics.frame_rate if it notices lag and increases it again when its not lagging anymore.
the cpu utilization is only checked (not changed or something else) to see if the game lags..
I didnt notice any delayed Input.. did you change any settings or something else inside the script?
 
This is nice, but it seems like it is lagging sometimes when you turn the high priority off, I guess I can release a warning label in the logo stuff to warn people to turn of certain things if they want to get the full experience of the game.
 
f0tz!baerchen;128353 said:
I didnt notice any delayed Input.. did you change any settings or something else inside the script?

I tried it in a new project. With ONLY setting the game to high priority with Photoshop open and Bryce 5 too...
 
@Me(tm): Set the Max values to 90 then the min to 20 and in high priority, it runs at 20-30 FPS fluxtuating only when I attack, it makes my game run so much smoother, but it really sucks CPUU when I try to play background music, let me say I have... Windows Live Messenger, Yahoo Instant Messenger, AIM with Messages open, 9 folders open, 5 RMXP projects for testing and my game included open, Photoshop, Windows Media Player, Win Word 2003, MS Paint, and FireFox with 3 tabs open... When I ran the game.
 

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