Screen prediction when using the Function() action

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
goldo
Regular
Posts: 63
Joined: Mon Jan 23, 2017 8:23 am
Contact:

Screen prediction when using the Function() action

#1 Post by goldo » Wed Jan 13, 2021 7:07 am

Hi guys, I'm a bit puzzled by this, searched the forum but couldn't find an answer.

The 'Function()' screen action doesn't prevent screen prediction from running the function code.

I have a difficulty setting screen which looks like this:

Code: Select all

screen set_diff(diff_settings):
        vbox spacing 6 box_wrap True:

                        $ y = len(diff_settings)

                        grid 2 y:
                            for ds in diff_settings:
                                textbutton diff_setting_name[ds] + ": " + percentage_description(game.get_diff_setting(ds), False) text_color c_brown background None text_size 18 action NullAction() tooltip diff_setting_description[ds]

                                hbox: # The player can push those buttons to change difficulty and activate 'custom' difficulty
                                    textbutton "-" text_size 18 action Function(game.change_diff_setting, ds, -0.05)
                                    textbutton "+" text_size 18 action Function(game.change_diff_setting, ds, 0.05)
And the Game class change_diff_setting() looks like this:

Code: Select all

class Game():
      [...]

      def change_diff_setting(self, setting, chg):
            self.diff = "custom"

            if self.diff_settings[setting] + chg > 0:
                self.diff_settings[setting] += chg

            self.update_achievements()

      def update_achievements(self):

            self.achievements = True

            # Disables achievements if difficulty settings are not at least equal to easy mode.
            for k, v in self.diff_settings.items():
                if v > diff_dict["easy"][k]: # Higher value = easier difficulty
                    self.achievements = False
                    break
The purpose of this code is to disable achievements for players who set one or more of the difficulty settings beyond "easy" difficulty. But it doesn't work as intended, because screen prediction runs the code before the player actually changes the value.

Now as far as I understand, 'game.change_diff_setting' should be excluded from screen prediction because it is called with the Function() action, but this is not what happens. Achievements are disabled before the player actually clicks the button to change the difficulty.

I know screen prediction is messing with this because adding a simple 'renpy.notify("bla bla bla")' to the 'update_achievements' method makes the notification loop constantly. However, that behavior is not consistent (on the first try the screen works as intended), so setting a simple offset doesn't work either.

Am I misunderstanding what the screen action 'Function()' does? Is it because I'm calling a class method, or because the methods are nested?

Any hint would be appreciated. Thank you!

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Projects: The Button Man
Organization: NILA
Github: hell-oh-world
Location: Philippines
Contact:

Re: Screen prediction when using the Function() action

#2 Post by hell_oh_world » Wed Jan 13, 2021 11:34 am

is game defaulted?
default game = Game(...)
You mighg want to try that first.

goldo
Regular
Posts: 63
Joined: Mon Jan 23, 2017 8:23 am
Contact:

Re: Screen prediction when using the Function() action

#3 Post by goldo » Wed Jan 13, 2021 1:14 pm

No, sorry game is an instance of Game() that gets created upon starting a new game. I should have mentioned that.

User avatar
_ticlock_
Veteran
Posts: 391
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

Re: Screen prediction when using the Function() action

#4 Post by _ticlock_ » Wed Jan 13, 2021 3:59 pm

Hi, goldo,

Is by any chance your class is defined in filename.py file and not filename.rpy?

goldo
Regular
Posts: 63
Joined: Mon Jan 23, 2017 8:23 am
Contact:

Re: Screen prediction when using the Function() action

#5 Post by goldo » Wed Jan 13, 2021 7:25 pm

Nope, everything is defined in .rpy files. The game object is used for a bunch of things in the game and works just fine otherwise.

philat
Eileen-Class Veteran
Posts: 1853
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Screen prediction when using the Function() action

#6 Post by philat » Wed Jan 13, 2021 9:03 pm

The following works fine, so it's not Function. I don't know what it is based on what you posted.

Code: Select all

init python:
    class Game():
        def __init__(self):
            self.diff = 5
            self.achievements = True

        def change_diff(self, amount):
            self.diff += amount
            self.update_achievements()

        def update_achievements(self):
            if self.diff < 3:
                self.achievements = False

screen test(g):
    vbox:
        text str(g.diff)
        text str(g.achievements)
        hbox:
            textbutton "-" action Function(g.change_diff, -1)
            textbutton "+" action Function(g.change_diff, 1)

default game = Game()

label start:
    scene black
    call screen test(game)

Post Reply

Who is online

Users browsing this forum: Google [Bot]