RMRK is retiring.
Server is paid up for the rest of 2026, but the forum may go after that. See here for more information. Please archive or save anything you would like to keep before 2027.
Main Menu
  • Welcome to The RPG Maker Resource Kit.

Checkpoints and Continues (VX)

Started by Zylos, March 17, 2011, 07:29:00 AM

0 Members and 1 Guest are viewing this topic.

Zylos

Checkpoints and Continues (VX)
Version: 1.0
Author: Zylos
Date: March 16, 2011


Description



This script allows the game creator to easily set up checkpoint spots for the player to respawn to after the party has been defeated. The creator simply calls this script in an event on the map (such as during a map transfer or after an important cutscene), then when the player reaches what would normally be a game over, they will be allowed to continue the game from the exact spot marked by the creator. Additionally, the creator may allow the player a set number of continues or lives before it is game over for good.

Features


  • Lets you easily set up game checkpoints with events.
  • Allows the player to continue from the last checkpoint after being defeated.
  • Capable of using either unlimited continues or a set quantity before game over.
  • Very customizable and easy to follow.

Screenshots



Instructions


  • Place this script in the materials section, above Main.
  • Check the script settings in the editable region of the script (below the instructions) to make sure they are to your needs. Continues_Enabled determines whether the player is allowed to continue from a checkpoint after being defeated. Number_Of_Continues is the number of times the player is allowed to try again from a checkpoint (set a negative number for unlimited continues). Continue_Graphic is any image you wish to use for when you are allowed to continue instead of getting a final game over. Return_To_Title determines whether the player returns to the title or whether the game should shut down if the player chooses not to continue after being defeated.
  • Use the script command in an event and type in "checkpoint" without the quotes. This will create a checkpoint at that exact point. Checkpoints are also automatically created upon the start of a new game, saving the game, and loading a save file.
  • For a better visual, you might also want a specific graphic to use instead of the regular game over screen. Add your screen to your games system folder and change the Continue_Graphic to the file's name for it to replace the game over screen when the player is allowed to continue. I've made the following screen for anyone to use if they want to:

[spoiler]http://i254.photobucket.com/albums/hh99/Zylos_2007/Continue-1.png[/spoiler]

Script



#==============================================================================
#  Checkpoints and Continues (VX)
#  Version: 1.0
#  Author: Zylos (rmrk.net)
#  Date: March 16, 2011
#------------------------------------------------------------------------------
#  Description:
#
#   This script allows the game creator to easily set up checkpoint spots for
#   the player to respawn to after the party has been defeated. The creator
#   simply calls this script in an event on the map (such as during a map
#   transfer or after an important cutscene), then when the player reaches what
#   would normally be a gameover, they will be allowed to continue the game
#   from the exact spot marked by the creator. Additionally, the creator may
#   allow the player a set number of continues or lives before it is gameover
#   for good.
#
#------------------------------------------------------------------------------
#  Instructions:
#   
#     - Place this script in the materials section, above Main.
#     - Check the settings of this script in the editable region below these
#       instructions to make sure they are to your needs.
#     - Use the script command in an event and type in "checkpoint" without
#       the quotes. This will create a checkpoint at that exact point.
#       Checkpoints are also automatically created upon the start of a new
#       game, saving the game, and loading a save file.
#
#==============================================================================

module Continue_Checkpoint
  #============================================================================
  # EDITABLE REGION:
  #============================================================================
 
  #============================================================================
  #   Continues_Enabled determines whether the player is allowed to continue or
  #   not when they have reached a gameover screen. In essence, it determines
  #   whether this script is turned on or off. This may be turned off in the
  #   game by calling "$game_system.continues_enabled = false".
  #============================================================================
  Continues_Enabled = true
  #============================================================================
  #   Number_Of_Continues sets the number of times the player is allowed to
  #   continue from a checkpoint before finally getting a gameover. Setting
  #   this to a negative number lets the player continue without a limited
  #   number of continues. You may add to this number ingame by calling
  #   "$game_system.lives += 1" and subtract similarly.
  #============================================================================
  Number_Of_Continues = -1
  #============================================================================
  #   Continue_Graphic is the image used to replace the gameover screen if the
  #   player is allowed to continue from a checkpoint. If the picture does not
  #   exist in the games system folder, then the default gameover screen will
  #   be used. Editable with "$game_system.continue_graphic = 'imagename'".
  #============================================================================
  Continue_Graphic = "Continue.png"
  #============================================================================
  #   Return_To_Title determines whether the player should return to the title
  #   screen if they choose not to continue from a checkpoint, or whether the
  #   game simply shuts down. This is useful for instances where the player
  #   can do battle before the title screen comes up. Editable with
  #   "$game_system.return_to_title = true/false".
  #============================================================================
  Return_To_Title = true
 
  #============================================================================
  # END EDITABLE REGION
  #============================================================================
end

#==============================================================================
# ** Game_System
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Initializing the checkpoint system here, in the event of the player having
#  maps before the title screen.
#==============================================================================

class Game_System
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :continues_enabled
  attr_accessor :lives
  attr_accessor :continue_graphic
  attr_accessor :return_to_title
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  alias_method :quicksave_data, :initialize
  def initialize
    quicksave_data
    @continues_enabled = Continue_Checkpoint::Continues_Enabled
    @lives = Continue_Checkpoint::Number_Of_Continues
    @continue_graphic = Continue_Checkpoint::Continue_Graphic
    @return_to_title = Continue_Checkpoint::Return_To_Title
    create_checkpoint
  end
  #--------------------------------------------------------------------------
  # * Creating Checkpoint Class
  #--------------------------------------------------------------------------
  def create_checkpoint
    $game_checkpoint = Game_Checkpoint.new
    $game_checkpoint.do_erase
  end
end

#==============================================================================
# ** Game_Checkpoint
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Creates and loads the data from checkpoints.
#==============================================================================

class Game_Checkpoint
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :quicksave 
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    @quicksave = []
    @quicksave[15] = ""
  end
  #--------------------------------------------------------------------------
  # * Execute Erasure
  #--------------------------------------------------------------------------
  def do_erase
    for i in @quicksave
      i = ""
    end
  end 
  #--------------------------------------------------------------------------
  # * Execute Save
  #--------------------------------------------------------------------------
  def do_quicksave
    do_erase
    write_quicksave_data
  end
  #--------------------------------------------------------------------------
  # * Execute Load
  #--------------------------------------------------------------------------
  def do_quickload
    if @quicksave[15] == "true"
      read_quicksave_data
      $scene = Scene_Map.new
      RPG::BGM.fade(1500)
      Graphics.fadeout(60)
      Graphics.wait(40)
      @last_bgm.play
      @last_bgs.play
    else
      $game_temp          = Game_Temp.new
      $game_message       = Game_Message.new
      num_of_lives        = $game_system.lives
      $game_system        = Game_System.new
      $game_system.lives  = num_of_lives
      $game_switches      = Game_Switches.new
      $game_variables     = Game_Variables.new
      $game_self_switches = Game_SelfSwitches.new
      $game_actors        = Game_Actors.new
      $game_party         = Game_Party.new
      $game_troop         = Game_Troop.new
      $game_map           = Game_Map.new
      $game_player        = Game_Player.new
      $game_party.setup_starting_members            # Initial party
      $game_map.setup($data_system.start_map_id)    # Initial map position
      $game_player.moveto($data_system.start_x, $data_system.start_y)
      $game_player.refresh
      $scene = Scene_Map.new
      RPG::BGM.fade(1500)
      Graphics.fadeout(60)
      Graphics.wait(40)
      Graphics.frame_count = 0
      RPG::BGM.stop
      $game_map.autoplay
    end
  end 
  #--------------------------------------------------------------------------
  # * Write Quicksave Data
  #     file : write file object (opened)
  #-------------------------------------------------------------------------- 
  def write_quicksave_data
    characters = []
    for actor in $game_party.members
      characters.push([actor.character_name, actor.character_index])
    end
    $game_system.version_id = $data_system.version_id
    @last_bgm = RPG::BGM::last
    @last_bgs = RPG::BGS::last
    @quicksave[1] = Marshal.dump(characters)
    @quicksave[2] = Marshal.dump(Graphics.frame_count)
    @quicksave[3] = Marshal.dump(@last_bgm)
    @quicksave[4] = Marshal.dump(@last_bgs)
    @quicksave[5] = Marshal.dump($game_system)
    @quicksave[6] = Marshal.dump($game_message)
    @quicksave[7] = Marshal.dump($game_switches)
    @quicksave[8] = Marshal.dump($game_variables)
    @quicksave[9] = Marshal.dump($game_self_switches)
    @quicksave[10] = Marshal.dump($game_actors)
    @quicksave[11] = Marshal.dump($game_party)
    @quicksave[12] = Marshal.dump($game_troop)
    @quicksave[13] = Marshal.dump($game_map)
    @quicksave[14] = Marshal.dump($game_player)
    @quicksave[15] = "true"
  end
  #--------------------------------------------------------------------------
  # * Read Quicksave Data
  #     file : file object for reading (opened)
  #--------------------------------------------------------------------------
  def read_quicksave_data
    characters           = Marshal.load(@quicksave[1])
    Graphics.frame_count = Marshal.load(@quicksave[2])
    @last_bgm            = Marshal.load(@quicksave[3])
    @last_bgs            = Marshal.load(@quicksave[4])
    $game_system         = Marshal.load(@quicksave[5])
    $game_message        = Marshal.load(@quicksave[6])
    $game_switches       = Marshal.load(@quicksave[7])
    $game_variables      = Marshal.load(@quicksave[8])
    $game_self_switches  = Marshal.load(@quicksave[9])
    $game_actors         = Marshal.load(@quicksave[10])
    $game_party          = Marshal.load(@quicksave[11])
    $game_troop          = Marshal.load(@quicksave[12])
    $game_map            = Marshal.load(@quicksave[13])
    $game_player         = Marshal.load(@quicksave[14])
    if $game_system.version_id != $data_system.version_id
      $game_map.setup($game_map.map_id)
      $game_player.center($game_player.x, $game_player.y)
    end
  end
end

#==============================================================================
# ** Scene_File
#------------------------------------------------------------------------------
#  Modifying the save screen to create new checkpoints.
#==============================================================================

class Scene_File
  #--------------------------------------------------------------------------
  # * Execute Save
  #--------------------------------------------------------------------------
  alias_method :quicksave_1, :do_save
  def do_save
    quicksave_1
    $game_checkpoint.do_quicksave
  end
  #--------------------------------------------------------------------------
  # * Execute Load
  #--------------------------------------------------------------------------
  alias_method :quicksave_2, :do_load
  def do_load
    quicksave_2
    $game_checkpoint.do_quicksave
  end
end

#==============================================================================
# ** Game_Interpreter
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Adding the checkpoint call script.
#==============================================================================

class Game_Interpreter
  #--------------------------------------------------------------------------
  # * Checkpoint
  #--------------------------------------------------------------------------
  def checkpoint
    $game_checkpoint.do_quicksave
  end
  #--------------------------------------------------------------------------
  # * Checkpoint Load
  #--------------------------------------------------------------------------
  def checkpoint_load
    $game_checkpoint.do_quickload
  end 
end

#==============================================================================
# ** Scene_Gameover
#------------------------------------------------------------------------------
#  Modifying the gameover screen to include continuing from checkpoints.
#==============================================================================

class Scene_Gameover
  #--------------------------------------------------------------------------
  # * Start processing
  #--------------------------------------------------------------------------
  alias_method :continuing1, :start
  def start
    continuing1
    if $BTEST
      $game_system.continues_enabled = false
    end
    if $game_system.lives != 0 and $game_system.continues_enabled
      create_command_window
    end
  end
  #--------------------------------------------------------------------------
  # * Post-Start Processing
  #--------------------------------------------------------------------------
  def post_start
    super
    if $game_system.lives != 0 and $game_system.continues_enabled
      open_command_window
    end
  end
  #--------------------------------------------------------------------------
  # * Pre-termination Processing
  #--------------------------------------------------------------------------
  def pre_terminate
    super
    if $game_system.lives != 0 and $game_system.continues_enabled
      close_command_window
    end
  end
  #--------------------------------------------------------------------------
  # * Termination Processing
  #-------------------------------------------------------------------------- 
  alias_method :continuing2, :terminate
  def terminate
    continuing2
    if $game_system.lives != 0 and $game_system.continues_enabled
      dispose_command_window
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    if $game_system.lives != 0 and $game_system.continues_enabled
      if @command_window.openness == 255
        @command_window.update
        if Input.trigger?(Input::C)
          case @command_window.index
          when 0    #Continue
            Sound.play_load
            RPG::ME.stop
            close_command_window
            num_of_lives = $game_system.lives
            $game_checkpoint.do_quickload
            $game_system.lives = num_of_lives
            if $game_system.lives > 0
              $game_system.lives -= 1
            end
          when 1    #Return to Title
            if $game_system.return_to_title == true
              Sound.play_decision
              RPG::BGM.fade(800)
              RPG::BGS.fade(800)
              RPG::ME.fade(800)
              $scene = Scene_Title.new
              close_command_window
              Graphics.fadeout(60)
            else    #Shutdown
              Sound.play_decision
              close_command_window
              RPG::BGM.fade(800)
              RPG::BGS.fade(800)
              RPG::ME.fade(800)
              $scene = nil
            end
          end
        end
      end
    else
      if Input.trigger?(Input::C)
        $scene = Scene_Title.new
        Graphics.fadeout(120)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Create Game Over Graphic
  #--------------------------------------------------------------------------
  def create_gameover_graphic
    @sprite = Sprite.new
    file = $game_system.continue_graphic
    file_exist = FileTest.exist?("Graphics/System/" + file)
    continue_on = $game_system.continues_enabled
    if $BTEST
      continue_on = false
    end
    if file_exist==true and $game_system.lives !=0 and continue_on == true
      @sprite.bitmap = Cache.system("Continue")
    else
      @sprite.bitmap = Cache.system("GameOver")
    end
  end
  #--------------------------------------------------------------------------
  # * Create Command Window
  #--------------------------------------------------------------------------
  def create_command_window
    s1=$game_system.lives>0 ? "Continue: "+"#{$game_system.lives}":"Continue"
    s2=$game_system.return_to_title ? Vocab::to_title : Vocab::shutdown
    @command_window = Window_Command.new(173, [s1, s2])
    @command_window.x = (544 - @command_window.width) / 2
    @command_window.y = 264
    @command_window.openness = 0
  end
  #--------------------------------------------------------------------------
  # * Dispose of Command Window
  #--------------------------------------------------------------------------
  def dispose_command_window
    @command_window.dispose
  end
  #--------------------------------------------------------------------------
  # * Open Command Window
  #--------------------------------------------------------------------------
  def open_command_window
    @command_window.open
    begin
      @command_window.update
      Graphics.update
    end until @command_window.openness == 255
  end
  #--------------------------------------------------------------------------
  # * Close Command Window
  #--------------------------------------------------------------------------
  def close_command_window
    @command_window.close
    begin
      @command_window.update
      Graphics.update
    end until @command_window.openness == 0
  end
end


Credit



  • Zylos
Thanks

  • Modern Algebra and IAMFORTE for taking a look at the script.
Demo


See attached.




Infinate X


tSwitch



FCF3a A+ C- D H- M P+ R T W- Z- Sf RLCT a cmn+++ d++ e++ f h+++ iw+++ j+ p sf+
Follow my project: MBlok | Find me on: Bandcamp | Twitter | Patreon

pacdiggity

Zylos wrote several scripts.
They are all nice.
This one, imo, offers the best feature. It's a great idea and will help with most platformers (you're making a platformer in VX?) or slow-paced kinda-action games (like mine :P).
The mastermind one is hella cool too. ;)
it's like a metaphor or something i don't know

qJusticeOne5


Acolyte

I'm using an evented game over screen. Would it be possible to call the continue option from an event and forgo the continue screen entirely?

Zylos

#6
You mean like using a call script to automatically return to the checkpoint?

You should be able to do so with "$game_checkpoint.do_quickload", I believe.




Acolyte

Yeah, I think that would work, but how do I bypass the continue screen?

Zylos

Oh, even better, I forgot you could simply use "checkpoint_load" in a script call slot, and it'll load from the last checkpoint. The default game over will work as normal if you turn the script off in the edit region, but the checkpoint_load command will still work just the same for you.




Acolyte

Okay, I'm derping again. Since I'm calling it from the game over map, it auto-checkpoints at the game over map transition. .-.
Is there a way to stop this?

Zylos

Is your game over map an actual map, or a script that you're calling?




Acolyte


Zylos

Hm. It shouldn't be making another checkpoint unless you specifically have an event creating one. Are you certain that there are no events with the checkpoint code in them running during the transition or in a common event?




Acolyte

As far as I can see, no, but I do have a habit of overlooking things, so I'll keep looking.

Zylos

No loops or parallel processes or anything with them? As far as I've been able to test, it can't create them without the checkpoint code in an event.




Acolyte

#15
Found the problem. There was a rogue checkpoint set to parallel process. :facepalm: