Ren'Py Hints in the choice

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,192
Is it possible to add hints to the choice without affecting the game scripts?
Since as a game author the question would be meaningless, I guess that you ask this from a modder point of view. And the answer is "yes, but".

The callback permit to change in real time the text of the menu choices. Something that would looks like this:
Python:
define walkthrough = { "original choice text 1": "[[hint]",
                                    "original choice text 2": "[[hint]",
                                    [...] }

init python:
    def smtf( text ):
        if text in walkthrough:
            return text + " " + walkthrough[text]
        else:
            return text

    config.say_menu_text_filter = smtf

But those text are generally short, and often not explicit enough in terms of uniqueness. Let's say that you have:
Python:
label whatever:
    menu:
        "Do you want to look the match with your friends ?"
        "yes":
            jump watchMatch
        "no":
            jump stayHome

label watchMatch:
    [...]
    menu:
        "The match suck, do you continue to watch it ?"
        "yes":
            jump continueWatch
        "no":
            jump returnHome
[...]
The right path being go watch the match, then return home early. That way you'll catch Mom furiously faping in your bed, and you'll finally be able to fuck her.

But of course, there's two "yes" and two "no", what isn't really helpful with the callback as used by default. You need to know which "yes" is related to "watch the match" and which one is related to "continue to watch".

One way to do could be to double this with . Each time the game enter a new label, you define a new walkthrough dictionary. Something that would looks like:
Python:
init python:
    config.label_overrides["whatever"] = "whateverWT"
    config.label_overrides["whateverReturn"] = "whatever"
    config.label_overrides["watchMatch"] = "watchMatchWT"
    config.label_overrides["watchMatchReturn"] = "watchMatch"
 
label whateverWT:
    $ walkthrough = { "yes": "[[if you want mom]" }
    jump whateverReturn 

label watchMatchWT:
    $ walkthrough = { "no": "[[if you want mom]" }
    jump watchMatchReturn
This way, the dictionary will be accurate for each label, and therefore for each menu. But to works, it need that the menus are in different labels, what isn't necessarily the case.

After, you can also do a bit more computation, having a two level dictionary and relying on the question itself:
Python:
define walkthroughIn = { "Do you want to look the match with your friends ?": { "yes": "[[if you want mom]" },
                                    "The match suck, do you continue to watch it ?": { "no": "[[if you want mom]" }, 
                                    [...] }
define walkthroughOut = [ "a string after the menu 1 choice 1", "a string after the menu 1 choice 2", [...] ]
default currentQuestion = None

init python:
    def smtf( text ):
        if text in walkthroughIn:
            store.currentQuestion = text
            return text
        elif text in walkthroughOut:
            store.currentQuestion = None
            return text
        elif text in walkthrough[store.currentQuestion]
            return text + " " + walkthrough[text]
        else:
            return text

    config.say_menu_text_filter = smtf
But it's not totally risk free, and it need more works seen you need to have the "walkthroughOUT" list in order to know when you leave the menu, to ensure that you'll not do unwanted substitutions.

After, there's other way, like counting the number of "yes", or more complex computation. But, well, they are more complex...
 
Jul 16, 2022
3
0
Since as a game author the question would be meaningless, I guess that you ask this from a modder point of view. And the answer is "yes, but".

The callback permit to change in real time the text of the menu choices. Something that would looks like this:
Python:
define walkthrough = { "original choice text 1": "[[hint]",
                                    "original choice text 2": "[[hint]",
                                    [...] }

init python:
    def smtf( text ):
        if text in walkthrough:
            return text + " " + walkthrough[text]
        else:
            return text

    config.say_menu_text_filter = smtf

But those text are generally short, and often not explicit enough in terms of uniqueness. Let's say that you have:
Python:
label whatever:
    menu:
        "Do you want to look the match with your friends ?"
        "yes":
            jump watchMatch
        "no":
            jump stayHome

label watchMatch:
    [...]
    menu:
        "The match suck, do you continue to watch it ?"
        "yes":
            jump continueWatch
        "no":
            jump returnHome
[...]
The right path being go watch the match, then return home early. That way you'll catch Mom furiously faping in your bed, and you'll finally be able to fuck her.

But of course, there's two "yes" and two "no", what isn't really helpful with the callback as used by default. You need to know which "yes" is related to "watch the match" and which one is related to "continue to watch".

One way to do could be to double this with . Each time the game enter a new label, you define a new walkthrough dictionary. Something that would looks like:
Python:
init python:
    config.label_overrides["whatever"] = "whateverWT"
    config.label_overrides["whateverReturn"] = "whatever"
    config.label_overrides["watchMatch"] = "watchMatchWT"
    config.label_overrides["watchMatchReturn"] = "watchMatch"
 
label whateverWT:
    $ walkthrough = { "yes": "[[if you want mom]" }
    jump whateverReturn 

label watchMatchWT:
    $ walkthrough = { "no": "[[if you want mom]" }
    jump watchMatchReturn
This way, the dictionary will be accurate for each label, and therefore for each menu. But to works, it need that the menus are in different labels, what isn't necessarily the case.

After, you can also do a bit more computation, having a two level dictionary and relying on the question itself:
Python:
define walkthroughIn = { "Do you want to look the match with your friends ?": { "yes": "[[if you want mom]" },
                                    "The match suck, do you continue to watch it ?": { "no": "[[if you want mom]" }, 
                                    [...] }
define walkthroughOut = [ "a string after the menu 1 choice 1", "a string after the menu 1 choice 2", [...] ]
default currentQuestion = None

init python:
    def smtf( text ):
        if text in walkthroughIn:
            store.currentQuestion = text
            return text
        elif text in walkthroughOut:
            store.currentQuestion = None
            return text
        elif text in walkthrough[store.currentQuestion]
            return text + " " + walkthrough[text]
        else:
            return text

    config.say_menu_text_filter = smtf
But it's not totally risk free, and it need more works seen you need to have the "walkthroughOUT" list in order to know when you leave the menu, to ensure that you'll not do unwanted substitutions.

After, there's other way, like counting the number of "yes", or more complex computation. But, well, they are more complex...
Thank you for your reply. It really helped me. Could you tell me if this will work with games that have multiple languages?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,192
Could you tell me if this will work with games that have multiple languages?
Hmmm... Yes and no.

I don't really have the time to validate this, but normally config.say_menu_text_filter is called before the translation, therefore a single dictionary would be enough.
But by default the replacement text would not have a translation, since not present in the original game. And that would be an issue.

This mean that you would need to force the translation (through _( ) by example) and include the translation files with the mod.
Python:
define walkthroughIn = { "Do you want to look the match with your friends ?": { "yes": _( "[[if you want mom]" ) },
                                    "The match suck, do you continue to watch it ?": { "no": _( "[[if you want mom]" ) }, 
                                    [...] }
But as I said, I don't guaranty this answer. It's what my memory, and logic, tell me, but I'm not always right.