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.

Saving(Resolved)

It saves $game_variables but not any others.

Simply go to Scene_Save and search for all the lines with $game_ etc.

Add below this any you have made, plus the rest etc.

Do the same in Scene_Load.

Example:
Code:
#--------------------------------------------------------------------------
  def write_save_data(file)
    # Make character data for drawing save file
    characters = []
    for i in 0...$game_party.actors.size
      actor = $game_party.actors[i]
      characters.push([actor.character_name, actor.character_hue])
    end
    # Write character data for drawing save file
    Marshal.dump(characters, file)
    # Wrire frame count for measuring play time
    Marshal.dump(Graphics.frame_count, file)
    # Increase save count by 1
    $game_system.save_count += 1
    # Save magic number
    # (A random value will be written each time saving with editor)
    $game_system.magic_number = $data_system.magic_number
    # Write each type of game object
    Marshal.dump($game_system, file)
    Marshal.dump($game_switches, file)
    Marshal.dump($game_variables, file)
    Marshal.dump($game_self_switches, file)
    Marshal.dump($game_screen, file)
    Marshal.dump($game_actors, file)
    Marshal.dump($game_party, file)
    Marshal.dump($game_troop, file)
    Marshal.dump($game_map, file)
    Marshal.dump($game_player, file)
[color=red]Marshal.dump($your_variable, file)[/color]
  end
end
 
Marshal can store and load any type of object, to my understanding. THat means you don't need to put a variable into an object and dump it when you can just dump the variable. Make sure you load the data in the same order that you dump it.
 
Yeyinde;107406":it80g3ws said:
Marshal can store and load any type of object, to my understanding.

Not exactly. Marshal can save some default classes like Arrays, Strings, Integers, Hashes and more, and even its variables with all objects inside them. But there´re some complex classes that can´t be saved, and good examples are Sprites and Bitmaps. In this special case if you really want to save them you must create a serialization method, like a new dump process for these cases.

Marshal is a library that converts all data from an object/objects into a byte stream, permitting the scripter to save this object into a file (outside the Ruby Interpreter´s memory) and recover it later on. Some objects cannot be dumped: if the objects to be dumped include bindings, procedure objects, instances of class IO, or singleton objects, a TypeError will be raised, so take care with what you dump. I have tried once to save an entire Bitmap for example, and the game crashed xD

Usage is fairly simple. This library has only two methods and they´re simple and very straightforward.
  • Marshal.dump(object, [anIO, [limit]])
This method converts all the objects´ data into a byte stream. object is te object to be serialized.​
anIO is not necessary, but if passed it must be an instance of the IO class (this is an special object that can be saved as an ordinary file, for you to know). In this case, Marshal.dump will dump the object´s stream into this IO object. Otherwise, it will return a string with the serialized object.​
In Marshal.dump, more than one object can be dumped into an IO object, and in this case the user can make the process check to see the number of dumps made in this IO object. limit[/b] represents the maximum number of objects that can be inside the IO object. -1 is the default value, and if it is that value, no ckeck will be made. As anIO, this argument is not necessary.

  • Marshal.load(object, [proc])
Marshal.load is the part responsible for recovering the dumped object´s data. object must be an instance of IO class, a String or any class that responds to the to_str method.​
This method returns the recovered object. If an IO object is passed and if it has more than one object dumped, it will load the objects in the same order they were dumped (the first dumped object will be the first to be loaded), and will return only ONE object each time you ask for it to load objects from that IO class. This operation must be done in order, so take care.​
proc is a Proc object that can be passed to be executed each time you load an object. Don´t really care with it since it´s a bit complicated for most scripters ^^ (if you want i can explain about Procs later).​
So... The two methods are explained, so let´s take some examples for you to understand about them:

Suppose we have those two classes:
Code:
# Class that will hold some text...
class Text
 
  attr_accessor :data
  def initialize
    @data = "Hi"
  end
 
end
 
# Class that will be the real object we´ll use
class Handler
 
  def initialize
    @text = Text.new
  end
 
  def say_something
    return @text.data
  end
 
  def record_this_text(txt)
    @text.data = txt
  end
 
end

So, we need new instances of them to start explaining anything.
Code:
myObject = Handler.new
print myObject.say_something     => "Hi"
 
# Changing some data
myObject.record_this_text("Hello World!")

As you can see we changed the object´s data and wants to store it. Suppose we can´t do it with IO objects, the only way to do is with Strings:
Code:
# Serializing the object and getting the result
string = Marshal.dump(myObject)

Now our object is serialized inside string. To recover it we call Marshal.load:
Code:
recoveredObject = Marshal.load(string)
print recoveredObject.say_something     => "Hello World!"

As you can see it´s very easy. Now let´s get more in depth... We will save it into a file. First, create a new IO object for that:
Code:
filename = "Handler.rxdata"
mode = "wb"  # in this case the file will be in the write mode only
file = File.open(filename, mode)

* NOTE: File.open opens the file specified in filename and returns a IO object that contains the bytes of it. If the file doesn´t exists it creates a new file with the name passed. Note that filename must contain the complete path and filename, but in our case we just used the default Game folder (supposing we´re writing it in RMXP). So, the new file will appear in the same place where Game.exe is.

Pass it to Marshal.dump...
Code:
# In this case Marshal.dump returns nothing. 
Marshal.dump(myObject, file)
 
# It´s REALLY important to close the IO object, otherwise
# the object won´t be saved correctly. Make this after dumping
# all the needed objects.
file.close

Now, to recover our object, first open the file:
Code:
filename = "Handler.rxdata"
mode = "rb"  # in this case the file will be in the read mode only
file = File.open(filename, mode)

Next, call Marshal.load:
Code:
recoveredObject = Marshal.load(file)
recoveredObject.say_something     => "Hello World!"

The magic is done ^^

Now your saved and recovered myObject is in recoveredObject. And sure, you can dump more than one object into a file. Take RMXP for example:
SAVING:
Code:
    file = File.open(filename, "wb")
    Marshal.dump($game_system, file)
    Marshal.dump($game_switches, file)
    Marshal.dump($game_variables, file)
    Marshal.dump($game_self_switches, file)
    Marshal.dump($game_screen, file)
    Marshal.dump($game_actors, file)
    Marshal.dump($game_party, file)
    Marshal.dump($game_troop, file)
    Marshal.dump($game_map, file)
    Marshal.dump($game_player, file)
    file.close

LOADING:
Code:
    file = File.open(filename, "rb")
    $game_system        = Marshal.load(file)
    $game_switches      = Marshal.load(file)
    $game_variables     = Marshal.load(file)
    $game_self_switches = Marshal.load(file)
    $game_screen        = Marshal.load(file)
    $game_actors        = Marshal.load(file)
    $game_party         = Marshal.load(file)
    $game_troop         = Marshal.load(file)
    $game_map           = Marshal.load(file)
    $game_player        = Marshal.load(file)
    file.close

Note that it´s just the condensated and simplified Scene_Save and Scene_Load most important code. I gave focus only to the Marshal methods. Note that the files are saved and loaded at the same order, that´s very important.

Now, if your object can´t be saved by Marshal library bu default, you can create a serialization method for the specific object. For that, and for more informations about Marshal, check here. (Sorry i´m so tired, i will explain the serialization method in another time ^^)

And magic, our object is saved inside Handler.rxdata ^^

I REALLY hope you understand what i´m trying to explain, and i´m sorry if i was too obvious and pointless in any part.
 

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