Page 1 of 1

How to check if label has been executed during current playthrough

Posted: Fri Mar 08, 2019 7:48 pm
by Woetoo
Okay. So I have a game that is released in chapters and I missed setting a variable in the previous chapter. Users have already played the bugged version.
I had the foresight to add a variable stored within the save to let me know which version of the game that save was saved under.

My original plan that I could use after_load: to correct a problem like this by simply setting the value for any savegame when I detect the known incorrect version number.

Which was fine, except I forgot to account for the fact that someone playing a say "chapter 6" save file, might still only be playing through chapter 1.

What I'd like to do is something similar to renpy.seen_label("ch05_wandering_the_park") - but not at a global level.
I don't want to know if "ch05_wandering_the_park" has ever been executed... I want to know if that label has been executed during THIS playthrough.

I vaguely recall there being an array of labels that had been executed since the game started, but not persistent. But I can't find it (again) in the online documentation.

Could someone point me in the right direction, please...? Code examples being especially welcome.
Or at least, tell me that it isn't possible.

Apologies if this has been asked and answered before, but searches like "renpy seen label" are throwing up so many result for "other" problems, that I can't see the wood for the trees.

Re: How to check if label has been executed during current playthrough

Posted: Fri Mar 08, 2019 7:56 pm
by Imperf3kt
Not a direct answer, sorry, but when browsing the documentation I find the general index super handy.
https://www.renpy.org/doc/html/genindex.html

You might be able to use
https://www.renpy.org/doc/html/other.ht ... gue_blocks
Or
https://www.renpy.org/doc/html/other.ht ... gue_blocks

Re: How to check if label has been executed during current playthrough

Posted: Fri Mar 08, 2019 8:16 pm
by Woetoo
Imperf3kt wrote:
Fri Mar 08, 2019 7:56 pm
Not a direct answer, sorry, but when browsing the documentation I find the general index super handy.
https://www.renpy.org/doc/html/genindex.html
Much appreciated, that will undoubtedly help me in the future.
You may well be right. But if there's a way of using either - I can't imagine it.

Oh... wait.. renpy.count_seen_dialogue_blocks might be in the right ball park... Nope. It looks to be persistent too. Starting a new game and pressing F2 to show "newly seen/total-count) doesn't reset the numbers. It seems to be purely "ever" and not something I can use retrospectively... again, unless I'm missing something (highly likely).

Re: How to check if label has been executed during current playthrough

Posted: Fri Mar 08, 2019 8:33 pm
by Remix
I'd consider suggesting to add a switch to that function to Tom, as there are a number of scenarios where it could be rather useful, especially alongside get_all_labels to create a very basic event/progression system.

renpy.seen_label( "label_name", ever=True )

Should be ok for any existing game that uses it and ones that want to use just session based returns would set the flag to False.

I will PM an attribute name to you so as not to just post it in this thread. It does not seem to be fully documented so I am loathe to just mention it here.

Re: How to check if label has been executed during current playthrough

Posted: Fri Mar 08, 2019 8:42 pm
by Woetoo
Remix wrote:
Fri Mar 08, 2019 8:33 pm
I'd consider suggesting to add a switch to that function to Tom, as there are a number of scenarios where it could be rather useful, especially alongside get_all_labels to create a very basic event/progression system.

renpy.seen_label( "label_name", ever=True )
For compatibility's sake... if implemented, "ever=" should probably default to True if omitted.
Sorry... grandmother... sucking eggs... and all that.

Re: How to check if label has been executed during current playthrough

Posted: Fri Mar 08, 2019 8:51 pm
by Remix
Yup, hence the *ever=True* bit
Maybe *session=False* (and toggle to True for just session based results) would be better semantically though.

Re: How to check if label has been executed during current playthrough

Posted: Fri Mar 08, 2019 9:20 pm
by Woetoo
To clarify my question... I'm looking for a way of checking if a label has been executed since the player started playing the game this time around.
But not exclusively this particular session.

By which I mean:

I'm not interested in if a label was reached on a previous play through. If the player has chosen to restart the game from the beginning (i.e. Start -> label start:), then the fact they previously reached ch10_visited_temple doesn't impact my check.

Or maybe another way of putting it is if I save, then quit renpy, then restart renpy and load that same save... I'd like to check the label (or list of labels) executed up to that point... including labels reached before I saved and quit. Not just this session, but all sessions since the player clicked "Start".

If "ever" and "this session" are my only options... that's fine. It just means I can't do the check I'm hoping for and I'll need to look for a different solution.

Re: How to check if label has been executed during current playthrough

Posted: Sat Mar 09, 2019 1:56 am
by strayerror
EDIT: Misunderstood OP's goal, skip to next post for a more relevant suggestion.

You can use config.label_callback (https://www.renpy.org/doc/html/config.h ... l_callback) to achieve this. The following code will store each label that is encountered into a set, named my_seen_labels, that will be local to a single play through, so it'll be preserved in saved games, and if you start a new game, it will reset.

Code: Select all

init python:
    def saw_label(label, flow_switch):
        try:
            my_seen_labels.add(label)
        except NameError:
            pass # my_seen_labels doesn't exist during game init, but we don't want to raise errors

    config.label_callback = saw_label

default my_seen_labels = set()
And usage:

Code: Select all

if 'my_label_name' in my_seen_labels:
    do_something()
Hope that's what you're looking for! :)

Re: How to check if label has been executed during current playthrough

Posted: Sat Mar 09, 2019 2:47 am
by strayerror
Ahh, my bad, just twigged as to what you're trying to achieve. I don't believe Ren'Py stores this data explicitly, so as far as I'm aware there's no foolproof way to identify which labels have or have not been touched in a specific playthrough for a game that has not already been tracking them (using something like the solution above).

It may however, be possible to get a fairly strong signal of progression by extracting data from the internal rollback log. Standard disclaimers about the use of internals apply. The following code extracts label names from the rollback log carried in save game data, it is not exhaustive as it is limited by the size of the rollback log of your game (iirc, the default size is 128 if left unchanged). The upshot of this is that it may be possible to identify labels entered within (roughly) the last 128 interactions/lines of dialogue. You could potentially, inside after_load, combine this limited view of labels with your knowledge of the order labels are encountered in during a playthrough to make an informed guess about progression.

Hopefully the following gives you a good idea of how you may go about this:

Code: Select all

labels_in_chpt_one = {'a', 'b', 'c', 'd'}
labels_in_chpt_two = {'e', 'f', 'g', 'h'}
labels_in_chpt_three = {'i', 'j', 'k', 'l'}
labels_in_chpt_four = {'m', 'n', 'o', 'p'}

# This uses Ren'Py internals and is, as such, implicitly unstable between versions of Ren'Py, use with caution.
labels_in_rollback = set(entry.context.current for entry in renpy.game.log.log if isinstance(entry.context.current, basestring))

# try to find latest recognised chapter using set intersections
if labels_in_rollback & labels_in_chpt_four:
    print('player reached chpt 4')
elif labels_in_rollback & labels_in_chpt_three:
    print('player reached chpt 3')
elif labels_in_rollback & labels_in_chpt_two:
    print('player reached chpt 2')
elif labels_in_rollback & labels_in_chpt_one:
    print('player reached chpt 1')
else:
    print("unable to guess at player's progression :(")
Hope this is more use than my previous answer! :)

Re: How to check if label has been executed during current playthrough

Posted: Sat Mar 09, 2019 6:39 am
by Woetoo
strayerror wrote:
Sat Mar 09, 2019 2:47 am
I don't believe Ren'Py stores this data explicitly, so as far as I'm aware there's no foolproof way to identify which labels have or have not been touched in a specific playthrough for a game that has not already been tracking them (using something like the solution above).
Thank you.
It was the answer I was coming to fear. But that's okay... It's not RenPy' fault that I forgot to add something.

And yes, the "informed guess" is probably the best I can hope for. Thank you for pointing me in the right direction for that particular solution.

Conversely, I may use your first solution in future projects. Either for this sort of thing, or gallery logic. Thanks for that too.