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.

Overwriting a certain part of a Save file [Resolved]

Good day everybody!

The other day I nearly finished my Config system for my CMS when I had an interesting idea, I'm not sure exactly how to go about it though. Obviously, Config settings can be saved to your Save files through Scene's Title, Save and Load the standard way we do, but thats when you're saving the entire game. Well, this is what I'm wanting to do...

How would I open a standard Save file, and update the data of just one certain object within? For instance, all things related to the games configuration is stored/accessed via the ($game_config a/k/a CMS::Config class), how would I be able to tell my Save file "Open 'Save01' and overwrite '$game_config' only!"?

Reason I'm needing this is because when you exit from Scene_Config, you're asked to save your Config settings... I don't want to save the entire game session, I just want to update the info in $game_config within a previously created Save file. Whenever this file is loaded later, the player will start off wherever they did their last *real* save with whatever config settings they set independant of that last save. I hope you understand, thanks.
 
Marshal.dump($game_config, filename)

Replace 'filename' with the name and path of the file. ex: "Data/Config.rxdata"

And then load it with

$game_config = Marshal.load(filename)
 
Yeah, but what I'm wanting to do is take an existing save file and only read/write a certain object of objects from it. The "Config" data is going to be saved individually in Save files, not in any kind of seperate "Config" file. The way it is normally saved is...

Code:
  def write_data(file)

    # 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)

    # Other objects are added to this Marshal.dump process via alias

  end

Then when loaded, each object is re-assigned in the same order it was dumped...

Code:
  def read_data(file)

    # Read each type of game object

    $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)

    # Other objects are loaded from Marshal.load via alias

  end

But if you notice, this saving/loading process reads/writes objects in the same order, and just simply dumping one object will return a file with just that one object. Normal saving, you'd have to write/read in the same order, but what I want to do is just dig ONE object ($game_config) out of the whole file and read/write it without disturbing the rest of the saved session. That way, when people save in the Config menu, they're not overwritting the entire game save, just the Configuration settings within that said save file.
 
Huh... couldn't you just use a configuration file for each save file?
Or is it a matter of filesize? Like you could detect if it was a new
game or a loaded game, and if it was loaded from a file, use the
number of that file with "Config#{number}" and if it was a new
game, you force it to save a new file.

But for something like that, you'll want the option to not immediatly
save your configuration.
 
I'm not entirely sure how save files work so this is just kinda guessing, but if there's a way to know when the file is out of information to give (an eof kinda thing), could you have a loop Marshall.load the file over and over and check each item as it passes through if it's the config info, then push the data to an array? The replace the index that you detected as config info with the new config info and Marshall.dump it back into the file in order. Probably not the most efficient method but it should be relatively safe and compatible. .-.
 
Cool thats a good idea I went ahead and tried that! I'm having a problem still though, let me post the method I wrote for this first...

Code:
    arr = Array.new

    filename = (Scene_File.new("")).make_filename($game_temp.last_file_index)

    file = File.open(filename, 'rb')

    begin

      arr << Marshal.load(file)

    end until file.eof?

    arr.each {|obj| obj = $game_menu if obj.is_a?(CMS)}

    file.close

    file = File.open(filename, 'wb')

    arr.each {|obj| Marshal.dump(obj, file)}

    file.close

...As you see, I open the file and create a new Array object, then I Marshal.load all the data from that file into the array until End of File is reached, then I close it.

I reopen the file in write mode, then I iterate through the array of the old data, once I find the object that is CMS (a/k/a $game_menu) class I overwrite just that object within the array with the newly updated $game_menu object.

I then reopen the file (in 'wb' mode) and iterate through the array, Marshal.dump-ing everything in the same order back into the file.

The issue I'm having though is it seems like these changes aren't saved and I'm not sure why. I save the game with "Windowskin A", go into config and change it to "Windowskin B" then exit (thats when the changes of the one object are auto-saved), then reload the file..... to find that its still using "Windowskin A". Is there something I'm overlooking still? I've changed the object and saved it, why is the object still loading the old settings prior to being overwritten?

PS; I'll post the entire script/demo if need be.
 
If I remember well, when you are doing "arr.each {|obj|", and then changing the obj variable with "obj = $game_menu", you are not overwriting the object from the array, you are only changing the obj instance variable of that block. Try so:
Code:
    arr = Array.new

    filename = (Scene_File.new("")).make_filename($game_temp.last_file_index)

    file = File.open(filename, 'rb')

    begin

      arr << Marshal.load(file)

    end until file.eof?

    arr.each_index {|i| arr[i] = $game_menu if arr[i].is_a?(CMS)}

    file.close

    file = File.open(filename, 'wb')

    arr.each {|obj| Marshal.dump(obj, file)}

    file.close
 
Perfect, thanks for your help vgvgf and everybody! Now only the config settings save in the config menu without tampering with the rest of the save file's contents, excellent!

This topic is now closed and resolved :thumb:
 

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