I eventually figured out what was wrong and think it's something that might be useful to share. The problem is related to how I chose to implement my own script (and therefore there wouldn't be an issue otherwise).
Here's a method in DataManager that creates a save header.
The save header is used by the save and load scenes to display "header" information. This is what it uses to draw previews for your save games (like your party members and playtime)
def self.make_save_header header = {} header[:characters] = $game_party.characters_for_savefile header[:playtime_s] = $game_system.playtime_s header[:system] = Marshal.load(Marshal.dump($game_system)) header[:timer] = Marshal.load(Marshal.dump($game_timer)) header[:message] = Marshal.load(Marshal.dump($game_message)) header[:switches] = Marshal.load(Marshal.dump($game_switches)) header[:variables] = Marshal.load(Marshal.dump($game_variables)) header[:self_switches] = Marshal.load(Marshal.dump($game_self_switches)) header[:actors] = Marshal.load(Marshal.dump($game_actors)) header[:party] = Marshal.load(Marshal.dump($game_party)) header[:troop] = Marshal.load(Marshal.dump($game_troop)) header[:map] = Marshal.load(Marshal.dump($game_map)) header[:player] = Marshal.load(Marshal.dump($game_player)) headerendHere's the top half of a method defined in a window class that draws the save preview. In particular, it draws the characters in your party for that save file. The rest of the code that I've taken out is just more position calculations and draw calls.
Code:
For context, in certain parts of the default engine, objects are being cloned and operated on, and this was causing problems with my script because I was relying on certain fields from the object as hash keys, but because clones are being made, I couldn't distinguish between the original object and a cloned object, and one of my requirements is that cloned objects are not the same as the original object and should be stored as separate entries. If you had 10 clones, then you would create an extra entry for each one.For compatibility purposes as well as backwards compatibility with default scripts (which makes life harder and leads to questionable design decisions), I didn't exactly want to go and change the way the cloning was performed, because this just means any script that performs cloning on the particular objects I'm working with would be vulnerable to the same bug.def draw_save_characters(dx, dy) return if @header[:party].nil? reset_font_settings make_font_smaller dw = (contents.width - dx) / @header[:party].max_battle_members dx += dw/2 for member in @header[:party].battle_members next if member.nil? member = @header[:actors][member.id] change_color(normal_color) draw_actor_graphic(member, dx, dy) # more codeSo I went and looked for something that was guaranteed to be unique without me having to explicitly make it unique, and figured I'll just use ruby's object ID's as a unique identifier. Every object in ruby has a unique ID that the ruby interpreter uses for whatever purposes. Even if you're a clone, you still have a unique ID, and so I decided to use that as my hash key.
Granted, this isn't necessarily a good idea. It might even be a bad idea since this data is being stored in a save file, as I'm exposing myself to even more bugs since now I'm working with data that is unpredictable(?).
Now, my script ran into problems with the script where I extracted those snippets above because of the way the save data was being handled.
Looking at just these two snippets, can you see any potential issues, given that I rely on object ID's for lookups?
EDIT: looking at my code again, I'm making a pretty bad assumption here by working with object ID's. It would be easier to try to find a better solution that doesn't involve object ID's.