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.

[RESOLVED] 'Map.AutoSaveResume' system

*Sigh* BUMP!

The system at least loads the map now, but now it has an error with @scroll_start or something being nil and I don't know how to get around it without having to overwrite that portion of Scene_Map. Since this uses Scene_Save "write_save_data" and Scene_Load "on_decision", I imagined it'd be easy to implement a system like this but I don't know why its not saving/loading correctly.

I've updated code, the system works just a little different from the last one but the general idea still stays the same, as well as the problem.

Code:
#===============================================================================
# ~** Auto-Save System **~
#-------------------------------------------------------------------------------
# Written by  : Kain Nobel
# Version     : 0.2c
# Last Update : 09.11.2008
# Created On  : 09.10.2008
#-------------------------------------------------------------------------------
# * Description   :
#-------------------------------------------------------------------------------
#   This is an AutoSave system for the map scene. Whenever you visit a new map,
#   a file is saved within the game's Data directory. If you ever can't find a
#   save point, and want to quit a game (as long as the script is enabled), you
#   can simply close the game without saving and resume it at a later time.
#-------------------------------------------------------------------------------
# * Features      :
#-------------------------------------------------------------------------------
#   - Create an AutoSave file in the games internal directory each time visiting
#     a new map scene.
#   - Close your game and open it at a later time from the entrance of the last
#     map scene visited.
#   - Author can toggle script activity with 'AutoSave::Enabled = true/false'
#-------------------------------------------------------------------------------
# * To-Do List    :
#-------------------------------------------------------------------------------
#   - Get the map resume loading to work, first of all...
#   - Create a quick 'n convenient sprite message to let player know if autosave
#     is enabled.
#-------------------------------------------------------------------------------
# * Requirements  :
#-------------------------------------------------------------------------------
#   - SDK version 2.2 or higher, at least parts 1 and 3
#===============================================================================
module AutoSave
  Enabled  = true
  Filename = 'AutoSave.rxdata'
end
#-------------------------------------------------------------------------------
# * SDK Log
#-------------------------------------------------------------------------------
SDK.log('Map.AutoSaveResume', 'Kain Nobel', 0.2, '09.11.2008')
SDK.log_alias(Game_Temp,  :autosave_game_temp_intialize,  :initialize)
SDK.log_alias(Game_Map,   :autosave_game_map_setup,       :setup)
SDK.log_alias(Scene_Title,:autosave_scene_title_main,     :main)
#-------------------------------------------------------------------------------
# * Use AutoSave::Enabled, not SDK.enable() to toggle script
#-------------------------------------------------------------------------------
if SDK.enabled?('Map.AutoSaveResume') && !AutoSave::Enabled
  SDK.disable('Map.AutoSaveResume')
end
if !SDK.enabled?('Map.AutoSaveResume') && AutoSave::Enabled
  SDK.enable('Map.AutoSaveResume')
end
#-------------------------------------------------------------------------------
# * SDK Enabled Test - BEGIN
#-------------------------------------------------------------------------------
if SDK.enabled?('Map.AutoSaveResume')
#===============================================================================
# ** Game_Temp
#-------------------------------------------------------------------------------
#   This class has an extra attribute added to it, so the Title scene knows to
# load the autosave or not.
#===============================================================================
class Game_Temp
  #-----------------------------------------------------------------------------
  # * Public Instance Variables
  #-----------------------------------------------------------------------------
  attr_accessor :autosave_invalid
  attr_accessor :autosave_load
  #-----------------------------------------------------------------------------
  # * Alias Listings
  #-----------------------------------------------------------------------------
  alias_method :autosave_game_temp_initialize, :initialize
  #-----------------------------------------------------------------------------
  # * Object Initialization
  #-----------------------------------------------------------------------------
  def initialize
    autosave_game_temp_initialize
    @autosave_invalid = false
    @autosave_load    = FileTest.exist?('Data/'+AutoSave::Filename)
  end
end
#===============================================================================
# ** Game_Map
#-------------------------------------------------------------------------------
#   Each time the map is set up, the game does an autosave.
#===============================================================================
class Game_Map
  #-----------------------------------------------------------------------------
  # * Alias Listings
  #-----------------------------------------------------------------------------
  alias_method :autosave_game_map_setup, :setup
  #-----------------------------------------------------------------------------
  # * Setup
  #-----------------------------------------------------------------------------
  def setup(map_id)
    $game_temp.autosave_load = true
    file = File.open('Data/'+AutoSave::Filename, 'wb')
    save = Scene_Save.new
    save.write_save_data(file)
    file.close
    $game_temp.autosave_load = false
    unless exists?(map_id)
      print("Failed to setup $game_map.map_id:#{map_id}\n\nI am now deleting",
      " your AutoSave file and \n taking you back to the Title Screen.")
      $game_temp.autosave_invalid = true
      $scene = Scene_Title.new
      autosave_game_map_setup(1)
    else ; autosave_game_map_setup(map_id)
    end
  end
  #-----------------------------------------------------------------------------
  # * Name      : Exists? (Submitted as a MACL 'RGSS.Map' method)
  #   Info      : Tests to see if Map exists
  #   Author    : Kain Nobel
  #   Call Info : id = Map ID in question
  #-----------------------------------------------------------------------------
  def exists?(id)
    if    id.between?(100, 999) ; filename = "Data/Map"   + id.to_s + ".rxdata"
    elsif id.between?( 10,  99) ; filename = "Data/Map0"  + id.to_s + ".rxdata"
    elsif id.between?(  1,   9) ; filename = "Data/Map00" + id.to_s + ".rxdata"
    else                        ; return false
    end
    return FileTest.exist?(filename)
  end
end
#===============================================================================
# ** Scene_Title
#-------------------------------------------------------------------------------
#   This scene prettymuch has its own sub-scene that is called if a AutoSave
# file exists.
#===============================================================================
class Scene_Title < SDK::Scene_Base
  #-----------------------------------------------------------------------------
  # * Alias Listing
  #-----------------------------------------------------------------------------
  alias_method :autosave_scene_title_main,          :main
  #-----------------------------------------------------------------------------
  # * Main
  #-----------------------------------------------------------------------------
  def main
    main_autosave_load if main_autosave_exist?
    if $game_temp.autosave_invalid
      if FileTest.exist?('Data/'+AutoSave::Filename)
        File.delete('Data/'+AutoSave::Filename)
      end
      $game_temp.autosave_invalid = false
    end
    autosave_scene_title_main
  end
  #-----------------------------------------------------------------------------
  # * Main Autosave Exist?
  #-----------------------------------------------------------------------------
  def main_autosave_exist?
    if FileTest.exist?('Data/'+AutoSave::Filename) && $game_temp.autosave_load
      return true
    end
    return false
  end
  #-----------------------------------------------------------------------------
  # * Main Autosave
  #-----------------------------------------------------------------------------
  def main_autosave_load
    file = File.open('Data/'+AutoSave::Filename, 'rb')
    load = Scene_Load.new
    load.on_decision('Data/'+AutoSave::Filename)
    file.close
    $game_temp.autosave_load = false
    if FileTest.exist?('Data/'+AutoSave::Filename)
      File.delete('Data/'+AutoSave::Filename)
    end
  end
end
#-------------------------------------------------------------------------------
# * SDK Enabled Test - END
#-------------------------------------------------------------------------------
end

To test, be sure you have SDK parts 1 and 3, open the game, go to New Game, imediately quit it when the New Game is initialized, then start it back up again, then you'll get the error I'm getting most likely. I don't know how to make it work correctly, it should work the same as just loading a saved game.... why things have to be so difficult sometimes...

Please tell me somebody's smarter than me and can tell me whats wrong, because I'd really love for this system to work like I wanted it to.
 
Code:
[code]First, a couple things:
[code]
SDK.log_alias(Game_Temp,  :autosave_game_temp_intialize,  :initialize)
SDK.log_alias(Game_Map,   :autosave_game_map_setup,       :setup)
SDK.log_alias(Scene_Title,:autosave_scene_title_main,     :main)

If you use alias_method and not alias, you don't have to do this. I have aliased the alias_method method, so it auto-logs these (I just couldn't alias the alias method).

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

if SDK.enabled?('Map.AutoSaveResume') && !AutoSave::Enabled
  SDK.disable('Map.AutoSaveResume')
end
if !SDK.enabled?('Map.AutoSaveResume') && AutoSave::Enabled
  SDK.enable('Map.AutoSaveResume')
end

That's kinda overkill. Instead, move the AutoSave module below the logging of your script. Then in the module, instead of a constant to enable it, just have something like this below:
Code:
#-------------------------------------------------------------------------------
# * SDK Log
#-------------------------------------------------------------------------------
SDK.log('Map.AutoSaveResume', 'Kain Nobel', 0.2, '09.11.2008')

module AutoSave
  SDK.disable('Map.AutoSaveResume') if true
  Filename = 'AutoSave.rxdata'
end

Then to enable and disable, just alter that true. Must cleaner code in the end. The other way just had far too many conditional statements.

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

Code:
  def exists?(id)
    if    id.between?(100, 999) ; filename = "Data/Map"   + id.to_s + ".rxdata"
    elsif id.between?( 10,  99) ; filename = "Data/Map0"  + id.to_s + ".rxdata"
    elsif id.between?(  1,   9) ; filename = "Data/Map00" + id.to_s + ".rxdata"
    else                        ; return false
    end
    return FileTest.exist?(filename)
  end

Use the sprintf and cut that code down.
Code:
    def exists?(id)
    return FileTest.exist?(sprintf("Data/Map%03d.rxdata", map_id))
  end

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

Ok. Now let's actually think about the script you will be making. When a map is loaded, save. Let's create a module method for this. Then when the title is loaded, if a file is found, load it. Might as well make a module method to do that as well. Let's do our methods first:

Code:
module AutoSave
  def self.autosave
    file = File.open(Filename, "wb")
    (Scene_Save.new).write_save_data(file)
    file.close
  end
  def self.autoload
    (Scene_Load.new).on_decision(Filename)
  end
  def self.exist?
    return FileTest.exist?(Filename)
  end
end

I also created a method that test if a file exist.

Ok. First, lets do the saving. Simple enough. Alias the setup method and just call our save method.
Code:
class Game_Map
  alias_method :kn_autosave_gmmap_setup, :setup
  def setup(map_id)
    Autosave.autosave
    kn_autosave_gmmap_setup(map_id)
  end
end

Little bit shorter now.

Finally, lets load the data. We need to make sure to do this after our databases have been added. So let's just do this after the main_database method.

Code:
class Scene_Title
  alias_method :kn_autosave_scnttl_mdb, :main_database
  def main_database
    kn_autosave_scnttl_mdb
    if AutoSave.exists?
      AutoSave.autoload
      $scene = Scene_Map.new
    end
  end
end


I think that should work. Let me know.[/code][/code]
 
Cleaned up the code beautifully, thank you for your help, however I'm still encountering the same error.

Code:
Script '[SDK-2]::Game/Sprite Objects' line 366: NoMethodError occured

undefined method '>' for nil:NilClass

This classic error occurs when I'm loading the AutoSave file, and if it matters I haven't updated my SDK I'm still using version 2.2, here's a copy of the Game_Map method, I commented the line.

Code:
def update_scrolling
    # If scrolling
    if @scroll_rest > 0 #<---This line.
      # Change from scroll speed to distance in map coordinates
      distance = 2 ** @scroll_speed
      # Execute scrolling
      case @scroll_direction
      when 2  # Down
        scroll_down(distance)
      when 4  # Left
        scroll_left(distance)
      when 6  # Right
        scroll_right(distance)
      when 8  # Up
        scroll_up(distance)
      end
      # Subtract distance scrolled
      @scroll_rest -= distance
    end
  end

Yes, I have updated the code with your suggestions and removed alot of the extra crap from it, if you would like to see it here's version 0.2d. I haven't changed much from what you submitted me besides just renaming the AutoSave module methods and the alias_method names, but it generally remains to be the same code you sent me, I copied and pasted it in.

The $game_temp.autosave_load initially is true/false based on file existance, then it is set to false during the game so that you can go back to the title later without kicking in the AutoSave.load_data segment.

Code:
#===============================================================================
# ~** Map.AutoSaveResume **~
#-------------------------------------------------------------------------------
# Written by  : Kain Nobel
# Version     : 0.3
# Last Update : 09.15.2008
# Created On  : 09.10.2008
#-------------------------------------------------------------------------------
# * Description   :
#-------------------------------------------------------------------------------
#   This is an AutoSave system for the map scene. Whenever you visit a new map,
#   a file is saved within the game's Data directory. If you ever can't find a
#   save point, and want to quit a game (as long as the script is enabled), you
#   can simply close the game without saving and resume it at a later time.
#-------------------------------------------------------------------------------
# * Features      :
#-------------------------------------------------------------------------------
#   - Create an AutoSave file in the games internal directory each time visiting
#     a new map scene.
#   - Close your game and open it at a later time from the entrance of the last
#     map scene visited.
#   - Author can toggle script activity with 'AutoSave::Enabled = true/false'
#-------------------------------------------------------------------------------
# * To-Do List    :
#-------------------------------------------------------------------------------
#   - Get the map resume loading to work, first of all...
#   - Create a quick 'n convenient sprite message to let player know if autosave
#     is enabled.
#-------------------------------------------------------------------------------
# * Requirements  :
#-------------------------------------------------------------------------------
#   - SDK version 2.2 or higher, at least parts 1 and 3
#===============================================================================
#-------------------------------------------------------------------------------
# * SDK Log
#-------------------------------------------------------------------------------
SDK.log('Map.AutoSaveResume', 'Kain Nobel', 0.3, '09.15.2008')
#-------------------------------------------------------------------------------
# * SDK Enabled Test - BEGIN
#-------------------------------------------------------------------------------
if SDK.enabled?('Map.AutoSaveResume')
#===============================================================================
# ~** AutoSave **~
#-------------------------------------------------------------------------------
#   This module handles all the AutoSave methods.
#===============================================================================
module AutoSave
  #-----------------------------------------------------------------------------
  # * Customizable Constant
  #-----------------------------------------------------------------------------
  Filename = "Data/AutoSave.rxdata"
  #-----------------------------------------------------------------------------
  # * AutoSave.save_file
  #-----------------------------------------------------------------------------
  def self.save_file
    $game_temp.autosave_load = false
    file = File.open(Filename, "wb")
    (Scene_Save.new).write_save_data(file)
    file.close
  end
  #-----------------------------------------------------------------------------
  # * AutoSave.load_file
  #-----------------------------------------------------------------------------
  def self.load_file
    (Scene_Load.new).on_decision(Filename)
  end
  #-----------------------------------------------------------------------------
  # * AutoSave.exists?
  #-----------------------------------------------------------------------------
  def self.exists?
    return FileTest.exist?(Filename)
  end
end
#===============================================================================
# ** Game_Temp
#-------------------------------------------------------------------------------
#   This class has an extra attribute added to it, so the Title scene knows to
# load the autosave or not.
#===============================================================================
class Game_Temp
  #-----------------------------------------------------------------------------
  # * Public Instance Variables
  #-----------------------------------------------------------------------------
  attr_accessor :autosave_load
  #-----------------------------------------------------------------------------
  # * Alias Listings
  #-----------------------------------------------------------------------------
  alias_method :autosave_game_temp_initialize, :initialize
  #-----------------------------------------------------------------------------
  # * Object Initialization
  #-----------------------------------------------------------------------------
  def initialize
    autosave_game_temp_initialize
    @autosave_load = AutoSave.exists?
  end
end
#===============================================================================
# ** Scene_Title
#-------------------------------------------------------------------------------
#   This class has been enhanced to load an AutoSave file (if it exists) apon
# opening the Game.exe later on after previously closing a game in progress.
#===============================================================================
class Scene_Title < SDK::Scene_Base
  #-----------------------------------------------------------------------------
  # * Alias Listing
  #-----------------------------------------------------------------------------
  alias_method :autosave_scene_title_main_database, :main_database
  #-----------------------------------------------------------------------------
  # * Main Database
  #-----------------------------------------------------------------------------
  def main_database
    autosave_scene_title_main_database
    if $game_temp.autosave_load
      AutoSave.load_file
      $scene = Scene_Map.new
    end
  end
end
#===============================================================================
# ** Game_Map
#-------------------------------------------------------------------------------
#   Each time you visit a new map scene, the AutoSave file is written to so you
# can just close the game and open it later and start where you left off at.
#===============================================================================
class Game_Map
  #-----------------------------------------------------------------------------
  # * Alias Listing
  #-----------------------------------------------------------------------------
  alias_method :autosave_game_map_setup, :setup
  #-----------------------------------------------------------------------------
  # * Setup
  #-----------------------------------------------------------------------------
  def setup(map_id)
    AutoSave.save_file
    autosave_game_map_setup(map_id)
  end
end
#-------------------------------------------------------------------------------
# * SDK Enabled Test - END
#-------------------------------------------------------------------------------
end
 
What is the point of: $game_temp.autosave_load?

You do know Game_Temp gets re-initialized in a few area? I guess I just don't understand what it is there for.

I removed the Game_Temp mod and tried the script with a blank project (SDK 2.4 and MACL 2.3) and it works fine for me.

Code:
#===============================================================================
# ~** Map.AutoSaveResume **~
#-------------------------------------------------------------------------------
# Written by  : Kain Nobel
# Version     : 0.3
# Last Update : 09.15.2008
# Created On  : 09.10.2008
#-------------------------------------------------------------------------------
# * Description   :
#-------------------------------------------------------------------------------
#   This is an AutoSave system for the map scene. Whenever you visit a new map,
#   a file is saved within the game's Data directory. If you ever can't find a
#   save point, and want to quit a game (as long as the script is enabled), you
#   can simply close the game without saving and resume it at a later time.
#-------------------------------------------------------------------------------
# * Features      :
#-------------------------------------------------------------------------------
#   - Create an AutoSave file in the games internal directory each time visiting
#     a new map scene.
#   - Close your game and open it at a later time from the entrance of the last
#     map scene visited.
#   - Author can toggle script activity with 'AutoSave::Enabled = true/false'
#-------------------------------------------------------------------------------
# * To-Do List    :
#-------------------------------------------------------------------------------
#   - Get the map resume loading to work, first of all...
#   - Create a quick 'n convenient sprite message to let player know if autosave
#     is enabled.
#-------------------------------------------------------------------------------
# * Requirements  :
#-------------------------------------------------------------------------------
#   - SDK version 2.2 or higher, at least parts 1 and 3
#===============================================================================
#-------------------------------------------------------------------------------
# * SDK Log
#-------------------------------------------------------------------------------
SDK.log('Map.AutoSaveResume', 'Kain Nobel', 0.3, '09.15.2008')

#-------------------------------------------------------------------------------
# * SDK Enabled Test - BEGIN
#-------------------------------------------------------------------------------
if SDK.enabled?('Map.AutoSaveResume')
  
#===============================================================================
# ~** AutoSave **~
#-------------------------------------------------------------------------------
#   This module handles all the AutoSave methods.
#===============================================================================

module AutoSave
  #-----------------------------------------------------------------------------
  # * Customizable Constant
  #-----------------------------------------------------------------------------
  Filename = "Data/AutoSave.rxdata"
  #-----------------------------------------------------------------------------
  # * AutoSave.save_file
  #-----------------------------------------------------------------------------
  def self.save_file
    file = File.open(Filename, "wb")
    (Scene_Save.new).write_save_data(file)
    file.close
  end
  #-----------------------------------------------------------------------------
  # * AutoSave.load_file
  #-----------------------------------------------------------------------------
  def self.load_file
    (Scene_Load.new).on_decision(Filename)
  end
  #-----------------------------------------------------------------------------
  # * AutoSave.exists?
  #-----------------------------------------------------------------------------
  def self.exists?
    return FileTest.exist?(Filename)
  end
end

#===============================================================================
# ** Scene_Title
#-------------------------------------------------------------------------------
#   This class has been enhanced to load an AutoSave file (if it exists) apon
# opening the Game.exe later on after previously closing a game in progress.
#===============================================================================

class Scene_Title < SDK::Scene_Base
  #-----------------------------------------------------------------------------
  # * Alias Listing
  #-----------------------------------------------------------------------------
  alias_method :autosave_scene_title_main_database, :main_database
  #-----------------------------------------------------------------------------
  # * Main Database
  #-----------------------------------------------------------------------------
  def main_database
    autosave_scene_title_main_database
    if AutoSave.exists?
      AutoSave.load_file
      $scene = Scene_Map.new
    end
  end
end

#===============================================================================
# ** Game_Map
#-------------------------------------------------------------------------------
#   Each time you visit a new map scene, the AutoSave file is written to so you
# can just close the game and open it later and start where you left off at.
#===============================================================================

class Game_Map
  #-----------------------------------------------------------------------------
  # * Alias Listing
  #-----------------------------------------------------------------------------
  alias_method :autosave_game_map_setup, :setup
  #-----------------------------------------------------------------------------
  # * Setup
  #-----------------------------------------------------------------------------
  def setup(map_id)
    autosave_game_map_setup(map_id)
    AutoSave.save_file
  end
end

#-------------------------------------------------------------------------------
# * SDK Enabled Test - END
#-------------------------------------------------------------------------------
end
 
Thank you Seph, for your patience and your help, you're truely a saint! With my new baby girl and my hours changing at work, I've been on an RGSS stumble, I'll probably be back to normal in a couple days. Couple little bugs to track down left, but those are easy, I will gladly add your name into the credit for your help and support.

$game_temp.autosave_load means that the Title doesn't load the AutoSave twice in the same game session (only when you open the game, not when you visit the title later from the same game session.) I forget that only my CMS allows me to carry over the Game_Temp, because in my CMS I used '$game_temp.load_calling = true' to prevent Scene_Load taking you back to the Title when you're really calling it from the menu. I'm going to change that though because its improper for publicly used scripts.

One last note, I did encounter another error when comparing @encounter_count > 0, so I added this to Game_Player#encounter_count method.

Code:
#===============================================================================
# ** Game_Player
#-------------------------------------------------------------------------------
#   You encounter a bug with this script if you don't do this.
#===============================================================================
class Game_Player < Game_Character
  #-----------------------------------------------------------------------------
  # * Alias Listing
  #-----------------------------------------------------------------------------
  alias_method :autosave_game_character_encounter_count, :encounter_count
  #-----------------------------------------------------------------------------
  # * Encounter Count
  #-----------------------------------------------------------------------------
  def encounter_count
    if @encounter_count.nil?
      make_encounter_count
    end
    autosave_game_character_encounter_count
  end
end

I shall now slap a RESOLVED on this topic, and I'm outta here! :rock:
 

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