Problem with persistent data

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
nychold
Newbie
Posts: 4
Joined: Tue Jul 21, 2009 6:39 pm
Contact:

Problem with persistent data

#1 Post by nychold »

I'm trying to include fourth wall breaks at certain points in the game, where the characters will mock the player for saving in the middle of certain dialogs, usually where major decisions are made. I thought I could do this with persistent data--just save a value into the data immediately before the load, and check it at various points throughout the game, resetting before where I want my fourth wall breaks. In order to demonstrate this, I took the template game and added the reset/checking code:

Code: Select all

#
# snipped from script.rpy
#
label start:
    $ persistent.recently_loaded = False

    # Show a background. This uses a placeholder by default, but you can
    # add a file (named either "bg room.png" or "bg room.jpg") to the
    # images directory to show it.

    scene bg room

    # This shows a character sprite. A placeholder is used, but you can
    # replace it by adding a file named "eileen happy.png" to the images
    # directory.

    show eileen happy
    
    # These display lines of dialogue.

    e "You've created a new Ren'Py game."
    
    e "persistent.recently_loaded = [persistent.recently_loaded]"
    
    if persistent.recently_loaded:
      e "Really?  You're already interrupting me?"
      $ persistent.recently_loaded = False

    e "Once you add a story, pictures, and music, you can release it to the world!"
    
    if persistent.recently_loaded:
      e "Again?  You're terrible."
      $ persistent.recently_loaded = False

    # This ends the game.

    return
Then, I "borrowed" (stole) the code from 00action_file.rpy to create my own action called FileInterjectAction:

Code: Select all

# interject.rpy

init -10 python:
  if persistent.recently_loaded is None:
    persistent.recently_loaded = False
  
  def __slotname(name, page=None):
    if page is None:
      page = persistent._file_page

    try:
      page = int(page)
      page = page + persistent._file_folder * config.file_pages_per_folder
    except ValueError:
      pass

    if config.linear_saves_page_size is not None:
      try:
        page = int(page)
        name = int(name)
        return str((page - 1) * config.linear_saves_page_size + name)
      except ValueError:
        pass

    return str(page) + "-" + str(name)
    
        
  def __newest_slot():
    return renpy.newest_slot(r'\d+')


  class FileInterjectLoad(Action, DictEquality):
    alt = "Load slot [text]"

    def __init__(self, name, confirm=True, page=None, newest=True):
      if name is None:
        name = __unused_slot_name(page)

      self.name = name
      self.confirm = confirm
      self.page = page
      self.newest = newest

      try:
        self.alt = __("Load slot %s: [text]") % (name,)
      except:
        self.alt = "Load slot %s: [text]" % (name,)

    def __call__(self):
      if not self.get_sensitive():
        return

      fn = __slotname(self.name, self.page)

      if not main_menu:
        if self.confirm:
          if config.autosave_on_quit and not fn.startswith("auto-"):
            renpy.loadsave.force_autosave()

          ############################# IMPORTANT BIT #############################
          layout.yesno_screen(layout.LOADING, FileInterjectLoad(self.name, False, self.page))
          ############################# IMPORTANT BIT #############################

          return

      ############################# IMPORTANT BIT #############################
      persistent.recently_loaded = True
      renpy.save_persistent()
      renpy.log(">>> persistent.recently_loaded = %s" % persistent.recently_loaded)
      renpy.load(fn)
      ############################# IMPORTANT BIT #############################

    def get_sensitive(self):
      if _in_replay:
        return False

      return renpy.can_load(__slotname(self.name, self.page))

    def get_selected(self):
      if not self.confirm or not self.newest:
        return False

      return __newest_slot() == __slotname(self.name, self.page)

        
  ############################# IMPORTANT BIT #############################
  def FileInterjectAction(name, page=None, **kwargs):
    if renpy.current_screen().screen_name[0] == "load":
      return FileInterjectLoad(name, page=page, **kwargs)
    else:
      return FileSave(name, page=page, **kwargs)
  ############################# IMPORTANT BIT #############################
Lastly, I modified screens.rpy to use the new action for loads and saves:

Code: Select all

#
# snipped from screens.rpy, screen file_slots
#
                for i in range(gui.file_slot_cols * gui.file_slot_rows):

                    $ slot = i + 1

                    button:
                        #action FileAction(slot)
                        action FileInterjectAction(slot)

                        has vbox
As you can see, I'm setting the persistent value recently_loaded to True and saving the persistent data immediately before loading, which (at least to my understanding) should save it immediately to the persistent data file, which can then be checked in the game code, to see if the player is loading a game in the middle of one of these scenes. But no matter what I do, persistent.recently_loaded stays false in the script.

What am I doing wrong?

nychold
Newbie
Posts: 4
Joined: Tue Jul 21, 2009 6:39 pm
Contact:

Re: Problem with persistent data

#2 Post by nychold »

I think I figured it out. I guess Ren'Py loads the game by replying all the code in order, including the initial "persistent.recently_loaded = False", so after I set it true, the load function sets it false. When I removed it from the beginning of script.rpy, it worked fine. Which means this system won't work as is, because I can't reset the flag. Rats.

Post Reply

Who is online

Users browsing this forum: No registered users