• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • It's time to vote for your favorite Pokémon Battle Revolution protagonist in our new weekly protagonist poll! Click here to cast your vote and let us know which PBR protagonist you like most.
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

[Scripting Question] Save File Corruption when trying to dispose Viewport

  • 5
    Posts
    2
    Years
    • Seen Sep 3, 2022
    So I'm making a battle record for my game, and yesterday I got it to successfully pull up and get rid of the screens as desired. Here is the code in question:

    Code:
    def battle_history_window(switch)
      
      if switch == "on" then
      
      
        @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
        @viewport.z = 99999
        @sprites = {}
        
        total_stats = "LIFETIME RECORD (W-D-L): #{$game_variables[60]}-#{$game_variables[61]}-#{$game_variables[62]}"
        history_stats = "%s/%s/%s\n" % ["TRAINER", "CUP", "RESULT"]
        
        for indx in 91..100 do
          if $game_variables[indx] != 0 then
            history_stats += "%s/%s/%s\n" % [$game_variables[indx][0], $game_variables[indx][1], $game_variables[indx][2]]
          end
        end
        @sprites["lifetime"] = Window_UnformattedTextPokemon.newWithSize(total_stats, 0, 0, Graphics.width, 64, @viewport)
        @sprites["recent"] = Window_UnformattedTextPokemon.newWithSize(history_stats, 0, 64, Graphics.width, Graphics.height - 64, @viewport)
      elsif switch == "off" then
        @sprites["lifetime"].dispose
        @sprites["recent"].dispose
      end
      
    end

    I've also tried to do
    Code:
    @viewport.dispose
    and it does the same thing as
    Code:
    @sprites["x"].dispose


    But then when I try to save, I get this error:
    Code:
    [2022-09-03 18:21:40 -0600]
    [Pokemon Essentials version 20]
    
    Exception: TypeError
    Message: no _dump_data is defined for class Viewport
    
    Backtrace:
    024:SaveData:60:in `dump'
    024:SaveData:60:in `block in save_to_file'
    024:SaveData:60:in `open'
    024:SaveData:60:in `save_to_file'
    031:StartGame:117:in `save'
    290:UI_Save:100:in `pbSaveScreen'
    277:UI_PauseMenu:263:in `block in <main>'
    277:UI_PauseMenu:124:in `block in pbStartPokemonMenu'
    277:UI_PauseMenu:117:in `loop'
    277:UI_PauseMenu:117:in `pbStartPokemonMenu'

    And the game crashes. Then when I try to reload, this error shows up:
    Code:
    [2022-09-03 18:30:42 -0600]
    [Pokemon Essentials version 20]
    
    Exception: ArgumentError
    Message: marshal data too short
    
    Backtrace:
    <internal:marshal>:34:in `load'
    024:SaveData:28:in `load'
    024:SaveData:28:in `block in get_data_from_file'
    024:SaveData:27:in `open'
    024:SaveData:27:in `get_data_from_file'
    024:SaveData:45:in `read_from_file'
    031:StartGame:23:in `set_up_system'
    405:Main:31:in `mainFunctionDebug'
    405:Main:18:in `block in mainFunction'
    014:Errors:80:in `pbCriticalCode'

    I know the code in question is the culprit, but what can I do to change it so the viewport goes away AND I don't get this error.
     
    You're lucky, I got the very same error in my own code.

    First, I don't know if Essentials v20 has this function, but look for:
    Code:
    def pbDisposeSpriteHash(sprites)
    to easily dispose all your sprites.

    Also, the switch should be a boolean (true or false), not a string.

    So, about your error. This error is due to the fact that viewports cannot be saved. Thus, viewports should not be attributes of a class.
    In your code, replace all occurrences of "@viewport" with "viewport" (without the @ symbol).
     
    YES. THANK YOU SO MUCH.

    I found the pbDisposeSpriteHash function and replaced it. Works just as well.

    As for the switch variable, it's actually in the events as a string parameter. I realize this isn't great coding practice, but I was just trying to get something to work lol. I may consider cleaning it up if I'm up to it.
     
    I apologize for the necropost here, but this is the only place that talks about this particular error on the searchable internet and I just beat my head against a wall for three hours trying to fix a different iteration of it.

    If you, dear reader, have NOT added any new viewports and encounter the "no _dump_data is defined for class Viewport" error, there is in fact another way that you can encounter it! And that is by saving a battle itself as a variable of a class.

    So, here's the stupid idiot dumb thing I did because I am a moron:

    In order to easily and quickly reference a new battle, I just saved it as a variable called "ongoing_battle" of the $game_map class. That way, I could use it to run battle functions easily by just typing out $game_map.ongoingbattle.pbDoTheThing. However, the problem is that when you exit the battle, the battle is still saved as a variable- and I believe, as a result, the viewport of the battle is thus saved by proxy. So, when you then go to save, this can result in the save also corrupting and throwing you this error.

    If you still want to save the battle as a variable of another object because you love bad code and living dangerously like myself, the fix is to simply reset the variable that saves the battle at the end of the battle. So basically, at the end of pbEndBattle in Battle_Scene, just put $game_map.ongoing_battle = 0, which will empty that battle out and let you save a nice, complacent 0 that won't cause your entire save to explode into fiery vapors.

    Hope this is helpful to a random stranger in another couple of years, like the last reply was for me.
     
    Back
    Top