PicklingError while saving a game with data structures.

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Geistbas
Regular
Posts: 34
Joined: Mon Jan 25, 2016 4:02 pm
Projects: Flow of Phantasmagory
Deviantart: Geistbas
Skype: geistbas
Location: Czech Republic
Contact:

PicklingError while saving a game with data structures.

#1 Post by Geistbas »

What I'm making is a dice game with VN and RPG battle mechanics.

Here is the traceback:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "renpy/common/00action_file.rpy", line 357, in __call__
    renpy.save(fn, extra_info=save_name)
PicklingError: Can't pickle <class 'store.boardClass'>: it's not the same object as store.boardClass

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "renpy/common/_layout/screen_load_save.rpym", line 35, in script
    $ ui.interact()
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/ast.py", line 805, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/python.py", line 1641, in py_exec_bytecode
    exec bytecode in globals, locals
  File "renpy/common/_layout/screen_load_save.rpym", line 35, in <module>
    $ ui.interact()
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/ui.py", line 278, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/core.py", line 2496, in interact
    repeat, rv = self.interact_core(preloads=preloads, **kwargs)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/core.py", line 3172, in interact_core
    rv = root_widget.event(ev, x, y, 0)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/layout.py", line 928, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/layout.py", line 928, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/layout.py", line 928, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/screen.py", line 646, in event
    rv = self.child.event(ev, x, y, st)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/layout.py", line 928, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/layout.py", line 204, in event
    rv = d.event(ev, x - xo, y - yo, st)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/layout.py", line 928, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/layout.py", line 204, in event
    rv = d.event(ev, x - xo, y - yo, st)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/behavior.py", line 868, in event
    return handle_click(self.clicked)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/behavior.py", line 803, in handle_click
    rv = run(action)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/display/behavior.py", line 302, in run
    return action(*args, **kwargs)
  File "renpy/common/00action_file.rpy", line 357, in __call__
    renpy.save(fn, extra_info=save_name)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/loadsave.py", line 281, in save
    dump((roots, renpy.game.log), logf)
  File "/home/lilsage/Plocha/renpy-6.99.11-sdk/renpy/loadsave.py", line 43, in dump
    cPickle.dump(o, f, cPickle.HIGHEST_PROTOCOL)
PicklingError: Can't pickle <class 'store.boardClass'>: it's not the same object as store.boardClass

Linux-3.13.0-24-generic-i686-with-debian-jessie-sid
Ren'Py 6.99.11.1749
Cyan Code Mirage 0.0
And here's what class boardClass looks like:

Code: Select all

class boardClass():
        
        def __init__(self):
            
            ## General Info
            self.name = ""
            self.gfxfile = None
            self.gfxover = None
            self.length = 0
            self.offsetX = 0
            self.offsetY = 0
            
            ## Individual Field Info
            self.field = [Fields() for i in range(0, max_fields)]
            
            ## How the field looks like
            self.fldEnv = [VisualField() for i in range(0, max_fields)]
            
            ## List of NPCs that are currently on the field
            self.fldNpc = [NpcField() for i in range (0, max_fields)]
            
            ## List of items that can be picked on the field
            self.fldItem = [ItemField() for i in range (0, max_fields)]
The object is created here, right under label start:

Code: Select all

# The game starts here.
label start:

    $ diceGameStage = [boardClass() for i in range(0, max_stages + 1)]
I'm unsure if I'm not going too far with the hybrid features unknowing if something doesn't break ren'py rules and such.

I am grateful for any help I can get!

User avatar
PyTom
Ren'Py Creator
Posts: 16093
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: PicklingError while saving a game with data structures.

#2 Post by PyTom »

You have to define your class in an init python block and make your you don't overwrite the class with a variable of the same name. (Your error is almost certainly one of these two things.)
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

User avatar
Geistbas
Regular
Posts: 34
Joined: Mon Jan 25, 2016 4:02 pm
Projects: Flow of Phantasmagory
Deviantart: Geistbas
Skype: geistbas
Location: Czech Republic
Contact:

Re: PicklingError while saving a game with data structures.

#3 Post by Geistbas »

I'm not exactly sure, however, when I put the object definition to the data rpy file, inside an init python block, Ren'py didn't complain about the board class anymore but complained about an itemData class instead.

But creating variables in an init block doesn't save them right?

For reference, I checked the source of my other mini project, Riverrsum, where I declared a player state class, and defined the object under label start:

Code: Select all

# The game starts here.
label start:
    
    $ slots = 24

    $ Player = playerData()
I tried to save the game, and I got no errors. But with this game, I get an error for more than one class:

When I moved diceGameStage definition to the init python, it started giving an error about itemData class.

When I moved Items definition (itemData class) back to the init python, it started giving me an error about effectGraphics class.

Code: Select all

label start:
    
    python:
        bgMapData()
        bgFieldData()
        stageMapData()
        fieldCoordinates()
            
            
        itemMapData()
        Char = [characterData() for i in range(0, max_characters)]
        player = playerStateClass()

        Party = [partyData() for i in range(0, max_parties)]
        EffectGFX = [effectGraphics() for i in range(Ef.e_total)]
I'm honestly surprised it troubleshoots the effectGraphics class, since it's just:

Code: Select all

class effectGraphics(object):
        
        def __init__(self):
            
            self.intensityGFX = [None for i in range(1, 3)]
Then it started giving errors about every class there is(characterData, playerStateClass, partyData), when I moved the definitions one by one.

I've checked. All of the classes are in an init python block.

Once I moved all the object definitions back to the init python block, all the way down below the classes, it stopped giving the error while saving, but of course, save files are broken with variables not being saved due to being created in an init block. (I'm aware)

I don't know what I am missing. Riverrsum(the other project) object creation under label start doesn't troubleshoot while saving.
I'm also sorry if I misunderstood something. I myself can't really pinpoint the objects being "overwritten" in the source.

User avatar
Geistbas
Regular
Posts: 34
Joined: Mon Jan 25, 2016 4:02 pm
Projects: Flow of Phantasmagory
Deviantart: Geistbas
Skype: geistbas
Location: Czech Republic
Contact:

Re: PicklingError while saving a game with data structures.

#4 Post by Geistbas »

I noticed something.

I actually could save the game successfully after rolling the dice at least once.

I did these tests:

1) Launched game >>> Opened inventory >>> Tried to Save = Got Error.
2) Launched Game >>> Opened inventory >>> Opened crafting UI >>> Made an Amethyst >>> Tried to Save = Got Error
3) Launched Game >>> Tried to Save >>> Got Error
4) Launched Game >>> Opened Map UI >>> Got Error
5) Launched Game >>> Opened Map UI >>> Clicked a button to roll the dice >>> player figure moved a few squares >>> Tried to Save >>> Didn't get an error.
6) Loaded game from save point of test 5 >>> Made a Diamond >>> Tried to Save again >>> Didn't get an error
7) Closed game >>> Launched Game again >>> Loaded Save from 5) and 6) >>> Tried to do very minor change like opening/closing an UI window >>> Tried to Save >>> Didn't get an error.

----
So in summary, I only get the error when trying to save the game before rolling the dice one time. After I press a dice rolling button, and then try to save, it doesn't give me any errors.

If it helps to get any answer about why Ren'py gives errors BEFORE rolling a dice just one time, and then being able to use an ongoing save file and resave, I will put the dice rolling source code here:

One of the imagebuttons for testing, a tetrahedron dice:

Code: Select all

imagebutton:
                idle "images/gui_tetra_idle.png"
                hover "images/gui_tetra_hover.png"
                clicked [ SetVariable("num_roll", diceRoll(4)), SetVariable("type_roll", 0), Jump("begin_phase") ]
                xpos 18 ypos 200 xanchor 0 yanchor 0
Now how the game processes dice rolling, note that I know it's perhaps badly written, I do plan to rewrite it into UUD instead of label switching, I figured back then that labels would work nicely since no dialogue is supposed to ever show while moving the player's figure on the game board:

Code: Select all

label master_phase:
    
    $ fieldlabel = "dgs" + str(player.stageIn) + "_fld" + str(player.fieldOn)
    $ renpy.jump(fieldlabel)
    
label field_phase:
    
    $ can_roll = "False"
    window show None
    system "Left the field.{fast}"
    jump ready_phase
    
label ready_phase:
    
    window show None
    $ can_roll = "True"
    system "You can roll the dice now.{fast}"
    
    jump ready_phase

label begin_phase:
    
    window show None
    python:
        can_roll = "False"
        stack_roll = num_roll
        player.waiting = "False"
    jump wait_phase
    
label wait_phase:
    
    window show None
    if player.waiting == "False" and stack_roll > 0:
        $ player.waiting = "True"
        jump main_phase
    jump main_phase
    
label standby_phase:
    if stack_roll == 0:
        $ player.waiting = "False"
        $ renpy.sound.play("sfx/fmove.wav", channel=0)
    $ savepos_x, savepos_y = diceGameStage[player.stageIn].field[player.fieldOn].pos
    $ pauseval = getMoveDelay(num_roll)
    if player.waiting == "True":
        $ renpy.sound.play("sfx/fmove.wav", channel=0)

    $ renpy.pause(pauseval, hard=True)
    jump wait_phase
        
label main_phase:
    window show None
        
    $ moveTo = 0
    if stack_roll > 0:
        if type_roll == 0 and diceGameStage[player.stageIn].field[player.fieldOn].fieldSet == None:
            
            $ player.fieldOn = player.fieldOn + 1
            if player.fieldOn == diceGameStage[player.stageIn].length:
                $ stack_roll = 0
            else:
                $ stack_roll = stack_roll - 1
        elif type_roll == 0 and diceGameStage[player.stageIn].field[player.fieldOn].fieldSet != None:
            $ player.fieldOn = diceGameStage[player.stageIn].field[player.fieldOn].fieldSet
            if player.fieldOn == diceGameStage[player.stageIn].length:
                $ stack_roll = 0
            else:
                $ stack_roll = stack_roll - 1
        
                
        elif type_roll == 3:
            
            $ player.fieldOn = player.fieldOn - 1
            if player.fieldOn == 0:
                $ stack_roll = 0
            else:
                $ stack_roll = stack_roll - 1
        else:
            $ moveTo = arrowGetField()
            if moveTo != 0:
                $ player.fieldOn = moveTo
                $ stack_roll = stack_roll - 1
            else:
                $ stack_roll = 0
                $ renpy.sound.play("fmove.wav", channel=0)
                
    else:            
       $ num_roll = 0
       $ renpy.jump("end_phase")
       
    $ renpy.jump("standby_phase")

    

label end_phase:
    
    window show None
    $ player.waiting = "False"
    $ can_roll = "True"
    
    jump field_phase
That'd be it. Crafting items in the inventory before rolling the dice apparently still shows an error while saving, but after the dice is rolled once, the saving works perfectly. I totally don't understand what's happening.

It also seems to not save inventory actions very well, but everything works save-wise after rolling the dice after making changes in the other UIs.

User avatar
PyTom
Ren'Py Creator
Posts: 16093
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: PicklingError while saving a game with data structures.

#5 Post by PyTom »

We need to see more of your code to figure out why boardClass is being redefined. The entire file, as it's not clear for the parts of it you're showing.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

Post Reply

Who is online

Users browsing this forum: No registered users