Pickling error in adding new function to history callback

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
KuroOneHalf
Regular
Posts: 129
Joined: Fri Apr 25, 2014 6:18 pm
Completed: Cuttlebone
Projects: Somewhere In The Shade
Deviantart: KuroOneHalf
itch: kuroonehalf
Contact:

Pickling error in adding new function to history callback

#1 Post by KuroOneHalf » Sun Feb 14, 2021 2:02 pm

I've been trying to implement the ability for the history system to store a screenshot with each rollback state, so that in the history/text log screen I could show what the game looked like during any given line, and thanks to the help of Rhyme on the discord server I was able to get it working, with the following code:

Code: Select all

init python:
    screenshot_w, screenshot_h = 1280/6, 720/6
    def screenshot_srf():
        srf = renpy.display.draw.screenshot(None) # Take screenshot
        srf = renpy.display.scale.smoothscale(srf, (screenshot_w, screenshot_h)) # Resize to 1/6th the size
        return srf

    class GetScreenshot(renpy.Displayable):
        def __init__(self):
            super(GetScreenshot, self).__init__()
            self.width, self.height = screenshot_w, screenshot_h
            self.srf = screenshot_srf()

        def render(self, width, height, st, at):
            render = renpy.Render(self.width, self.height)
            render.blit(self.srf, (0, 0))
            return render

    def history_screenshot_callback(x):
        x.screenshot = GetScreenshot()
    # Add new function to the history callbacks
    if history_screenshot_callback not in config.history_callbacks:
        config.history_callbacks.append(history_screenshot_callback)
        
screen text_history:
	for x,h in enumerate(_history_list):
		add h.screenshot
And this works as intended, but makes the game error out any time I try to reload the game from the developer menu or save the game, which I believe is a pickling issue, right? This is the traceback I get when I try to save, for example:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "renpy/common/00gamemenu.rpy", line 173, in script
    $ ui.interact()
  File "renpy/common/00gamemenu.rpy", line 173, in <module>
    $ ui.interact()
  File "renpy/common/00action_file.rpy", line 372, in __call__
    renpy.save(fn, extra_info=save_name)
TypeError: no default __reduce__ due to non-trivial __cinit__ (perhaps store._history_list[0].screenshot.srf = <Surface(213x120x32)>)

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

Full traceback:
  File "renpy/common/00gamemenu.rpy", line 173, in script
    $ ui.interact()
  File "C:\Users\Kuro\Desktop\Renpy/renpy/ast.py", line 913, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/python.py", line 2111, in py_exec_bytecode
    exec(bytecode, globals, locals)
  File "renpy/common/00gamemenu.rpy", line 173, in <module>
    $ ui.interact()
  File "C:\Users\Kuro\Desktop\Renpy/renpy/ui.py", line 298, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/core.py", line 2978, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, **kwargs)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/core.py", line 3776, in interact_core
    rv = root_widget.event(ev, x, y, 0)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 1027, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 1027, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 1027, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/screen.py", line 720, in event
    rv = self.child.event(ev, x, y, st)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 1027, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 245, in event
    rv = d.event(ev, x - xo, y - yo, st)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/behavior.py", line 969, in event
    return handle_click(self.clicked)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/behavior.py", line 904, in handle_click
    rv = run(action)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/behavior.py", line 323, in run
    return action(*args, **kwargs)
  File "renpy/common/00action_file.rpy", line 372, in __call__
    renpy.save(fn, extra_info=save_name)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/loadsave.py", line 416, in save
    reraise(t, e, tb)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/loadsave.py", line 399, in save
    dump((roots, renpy.game.log), logf)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/loadsave.py", line 49, in dump
    cPickle.dump(o, f, cPickle.HIGHEST_PROTOCOL)
  File "stringsource", line 2, in pygame_sdl2.surface.Surface.__reduce_cython__
TypeError: no default __reduce__ due to non-trivial __cinit__ (perhaps store._history_list[0].screenshot.srf = <Surface(213x120x32)>)

And when I disable cpickle this is the traceback I get:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "renpy/common/00gamemenu.rpy", line 173, in script
    $ ui.interact()
  File "renpy/common/00gamemenu.rpy", line 173, in <module>
    $ ui.interact()
  File "renpy/common/00action_file.rpy", line 372, in __call__
    renpy.save(fn, extra_info=save_name)
TypeError: no default __reduce__ due to non-trivial __cinit__ (perhaps store._history_list[0].screenshot.srf = <Surface(213x120x32)>)

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

Full traceback:
  File "renpy/common/00gamemenu.rpy", line 173, in script
    $ ui.interact()
  File "C:\Users\Kuro\Desktop\Renpy/renpy/ast.py", line 913, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/python.py", line 2111, in py_exec_bytecode
    exec(bytecode, globals, locals)
  File "renpy/common/00gamemenu.rpy", line 173, in <module>
    $ ui.interact()
  File "C:\Users\Kuro\Desktop\Renpy/renpy/ui.py", line 298, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/core.py", line 2978, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, **kwargs)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/core.py", line 3776, in interact_core
    rv = root_widget.event(ev, x, y, 0)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 1027, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 1027, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 1027, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/screen.py", line 720, in event
    rv = self.child.event(ev, x, y, st)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 1027, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/layout.py", line 245, in event
    rv = d.event(ev, x - xo, y - yo, st)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/behavior.py", line 969, in event
    return handle_click(self.clicked)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/behavior.py", line 904, in handle_click
    rv = run(action)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/display/behavior.py", line 323, in run
    return action(*args, **kwargs)
  File "renpy/common/00action_file.rpy", line 372, in __call__
    renpy.save(fn, extra_info=save_name)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/loadsave.py", line 416, in save
    reraise(t, e, tb)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/loadsave.py", line 399, in save
    dump((roots, renpy.game.log), logf)
  File "C:\Users\Kuro\Desktop\Renpy/renpy/loadsave.py", line 51, in dump
    pickle.dump(o, f, pickle.HIGHEST_PROTOCOL)
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 1376, in dump
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 224, in dump
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 286, in save
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 554, in save_tuple
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 286, in save
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 655, in save_dict
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 687, in _batch_setitems
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 331, in save
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 419, in save_reduce
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 639, in _batch_appends
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 331, in save
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 425, in save_reduce
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 286, in save
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 655, in save_dict
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 687, in _batch_setitems
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 331, in save
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 425, in save_reduce
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 286, in save
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 655, in save_dict
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 687, in _batch_setitems
  File "/home/tom/ab/renpy-build/tmp/install.android-x86_64/lib/python2.7/pickle.py", line 306, in save
  File "stringsource", line 2, in pygame_sdl2.surface.Surface.__reduce_cython__
TypeError: no default __reduce__ due to non-trivial __cinit__ (perhaps store._history_list[0].screenshot.srf = <Surface(213x120x32)>)


User avatar
PyTom
Ren'Py Creator
Posts: 15893
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: Pickling error in adding new function to history callback

#2 Post by PyTom » Sun Feb 14, 2021 7:01 pm

renpy.display.draw.screenshot and renpy.display.scale.smoothscale aren't documented parts of Ren'Py.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
KuroOneHalf
Regular
Posts: 129
Joined: Fri Apr 25, 2014 6:18 pm
Completed: Cuttlebone
Projects: Somewhere In The Shade
Deviantart: KuroOneHalf
itch: kuroonehalf
Contact:

Re: Pickling error in adding new function to history callback

#3 Post by KuroOneHalf » Sun Feb 14, 2021 7:42 pm

PyTom wrote:
Sun Feb 14, 2021 7:01 pm
renpy.display.draw.screenshot and renpy.display.scale.smoothscale aren't documented parts of Ren'Py.
Er, meaning you don't support the solving of problems that involve those functions? Are there documented functions that would let me capture a screenshot and save it to the history list? From my research I saw that you can take the screenshot, but then only the save functionality seems to be able to retrieve the image. Or have it be exported to a file. Neither are quite what I'm looking for.

Should I perhaps open a request issue on github?

Post Reply

Who is online

Users browsing this forum: No registered users