Ren'Py Change color text menu choice renpy

markt34

New Member
Aug 2, 2017
11
4
Could someone help me?
I am writing a script, and one of the decisions I need to be in green.
I put the code, but it only works in the first choice, in the others no matter what I do does not change the color.
Is it something I'm doing wrong?


Code:
 menu:
        "Do it again":
            jump sam

        "{color=#00ff00}Change{/color}":
            jump ch


label sam:
    scene black with medium_dissolve
    play sound "shoot.wav"
    
    jump a9


label a9:

    play sound "RUN.mp3" volume 0.2
    show i02
    "Your choice"
   

    menu:
        "Follow the left":
            jump left

        "{color=#00ff00}Open the door{/color}":
            jump Open


label Open:


    show i03
    with medium_dissolve
    call screen open
    if _return == "door":
        jump door



label door:

    show i67
    with dissolve

    menu:

        "Do not stay":
             jump stairs

        "{color=#00ff00}Take a look{/color}":
 
Last edited:

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
Okay... first things first... please swap all those show statements for scene statements.

show will add an image to the existing scene.
scene will clear the scene and add an image.

The difference is how many images being shown on screen at one time. Assuming full screen sized images...
25 x show statements means 25 images being handled by RenPy (with only the top one visible to the player).
25 x scene statements means 1 image being handled by RenPy (the latest one shown).

That is unless images like i02 and i03 are sprite images (smaller images overlaid onto the background).

We've seen games that eventually crash because they've used show only and ended up with hundreds (if not thousands) of full screen images all stacked on top of each other because the developer didn't known that show doesn't clean up after itself.

The rest of it...
Works fine.

There's nothing wrong with your {color=#00ff00} {/color} blocks.
I copied/pasted your code into a test project I use regularly - and it works how you want it to.

So something else is going on....
Or you changed your code in some way when you rewrote it to post it here on the forums.
 
  • Like
Reactions: markt34

markt34

New Member
Aug 2, 2017
11
4
Okay... first things first... please swap all those show statements for scene statements.

show will add an image to the existing scene.
scene will clear the scene and add an image.

The difference is how many images being shown on screen at one time. Assuming full screen sized images...
25 x show statements means 25 images being handled by RenPy (with only the top one visible to the player).
25 x scene statements means 1 image being handled by RenPy (the latest one shown).

That is unless images like i02 and i03 are sprite images (smaller images overlaid onto the background).

We've seen games that eventually crash because they've used show only and ended up with hundreds (if not thousands) of full screen images all stacked on top of each other because the developer didn't known that show doesn't clean up after itself.

The rest of it...
Works fine.

There's nothing wrong with your {color=#00ff00} {/color} blocks.
I copied/pasted your code into a test project I use regularly - and it works how you want it to.

So something else is going on....
Or you changed your code in some way when you rewrote it to post it here on the forums.
Thanks for the guidance on how to show the scenes, I'll fix that. I also don't understand why it doesn't work, I'm using this code for a game, and there will be a normal mode and another with walkthrough, I put this other script in another separate folder, with the intention of not having problems, could it be a conflict? because I already tried everything, I rewrote the code, I already put it in a test game, and I also opened another one in the expectation that it was my mistake, but it just doesn't work, the interesting thing is that I already tried color, bold and italics and letters, the changes only occur in the first choice in the rest , there is no change, not even in typing other words, it seems that it does not save the changes.
 

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,565
9,063
Thanks for the guidance on how to show the scenes, I'll fix that. I also don't understand why it doesn't work, I'm using this code for a game, and there will be a normal mode and another with walkthrough, I put this other script in another separate folder, with the intention of not having problems, could it be a conflict? because I already tried everything, I rewrote the code, I already put it in a test game, and I also opened another one in the expectation that it was my mistake, but it just doesn't work, the interesting thing is that I already tried color, bold and italics and letters, the changes only occur in the first choice in the rest , there is no change, not even in typing other words, it seems that it does not save the changes.
are labels the same in both files? that does seem like it would result in a conflict
 
  • Like
Reactions: markt34

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
You're including a walkthrough with your own game?
The "alternative labels" can be a good idea when writing a 3rd party walkthrough mod for an existing game - but as the game's developer you have more scope.

Personally, I think I would look at .

Something like:

Edit: Updated so it actually works (including Anne's improvements) :)

Python:
default persistent.walkthough = False

init python:

    def wtTag(tag, arg, contents):

        if not persistent.walkthrough:
            return [] + contents + []

        if arg == "":
            arg = "#00FF00"

        return [ (renpy.TEXT_TAG, u"color={}".format( arg )) ] + contents + [ (renpy.TEXT_TAG, u"/color") ]

    config.custom_text_tags["wt"] = wtTag

label start:

    scene black with fade
    "*** START ***"

label ask_the_question:

    menu:
        "{wt}Choice #1{/wt}":
            "You made a good choice."

        "{wt=#FF0000}Choice #2{/wt}":
            "You made a bad choice."

        "Enable Walkthrough":
            "Walkthrough enabled."
            $ persistent.walkthrough = True

        "Disable Walkthrough":
            "Walkthrough disabled."
            $ persistent.walkthrough = False

        "Quit":
            jump the_end

    jump ask_the_question

label the_end:

    "*** THE END ***"
    return

I've typed in that code purely from the documentation and forum posts here on F95. I haven't actually tested it yet. But it should work.

In this case, text surrounded by the {wt} {/wt} tags will be highlighted in green if the persistent.walkthrough flag is set. Otherwise, it will be displayed normally.
Basically, it's a good way of doing a walkthrough without repeating the same menu choices twice or more.

You could get more flamboyant and include small icons/pictures as part of the text too using renpy.TEXT_DISPLAYABLE.
And you could color code stuff, with more than one custom tag (perhaps separate tags for alternative routines in the walkthrough? 'Mom route', 'Sis route', 'Abstinence route', etc.) ... tags like {wt_m} {/wt_m}, {wt_s} {/wt_s} or {wt_a} {/wt_a}.
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
Python:
    def wtTag(tag, arg, contents):

        if walkthrough:
            return [ (renpy.TEXT_TAG, u"color=#00FF00"), (renpy.TEXT_TEXT, contents), (renpy.TEXT_TAG, u"/color") ]

        return [ (renpy.TEXT_TEXT, contents) ]
Like this it will not works. The tags are a bit weird in their approach, yet logical when you thing about it.


The callback is called each time a tag is found, therefore content isn't necessarily strictly a text. It is whatever is in between the current tag.

Let's say that the full string is "{wt=#00FF00}Invit {i}Sarah{/i} for a movie{/wt}". In this case the arguments sent to the callback will be:
tag will contain the tag itself, thefore "wt".
arg will contain the argument for this tag, here the color "#00FF00".
contents will contain everything that is between the opening and closing tag, therefore "Invit {i}Sarah{/i} for a movie".

Therefore never assume that content type is renpy.TEXT_TEXT.

As for the returned value, it's a three part element, not a list:
The first element is a list of opening tags to proceed before content.
The second element is content itself.
The first element is a list of closing tags to proceed after content.

Side note:
Self closing tags, like by example {nw} or {p}, are proceeded at a different level and therefore probably (don't remember having tested it) not usable in the return value.


In the end, the code should be:
[Note: Also updated to include the color argument, what can be useful since it offer more flexibility to the tag]
Python:
    def wtTag(tag, arg, contents):

        if walkthrough:
            return [ (renpy.TEXT_TAG, u"color={}").format( arg ) ] +  contents + [ (renpy.TEXT_TAG, u"/color") ]

        return [] + contents + []
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
Anne is improving on my code by passing the color to be used to the tag.
So instead of my always GREEN... you can be more flexible and set Choice#2 to be RED...
(again, only if the walkthrough flag is set)

Python:
label ask_the_question:

    menu:
        "{wt=#00FF00}Choice #1{/wt}":
            "You made a good choice."

        "{wt=#FF0000}Choice #2{/wt}":
            "You made a bad choice."

        "Enable Walkthrough":
            "Walkthrough enabled."
            $ persistent.walkthrough = True

        "Disable Walkthrough":
            "Walkthrough disabled."
            $ persistent.walkthrough = False

        "Quit":
            jump the_end

    jump ask_the_question

... or at least, that's what it looks like to me. Though maybe it needs quotes around the color code {wt="#00FF00"}.

I must admit, I thinking of something like {wt="m"} (for mom)... then using arg to pick from a series of icons to represent "mom route", etc. But that wasn't the question that was asked, no matter how much I wanted to include it in the answer (so I slapped it in here instead) :).
 
Last edited:

markt34

New Member
Aug 2, 2017
11
4
You're including a walkthrough with your own game?
The "alternative labels" can be a good idea when writing a 3rd party walkthrough mod for an existing game - but as the game's developer you have more scope.

Personally, I think I would look at .

Something like:

Python:
default persistent.walkthough = False

init python:

    def wtTag(tag, arg, contents):

        if walkthrough:
            return [ (renpy.TEXT_TAG, u"color=#00FF00"), (renpy.TEXT_TEXT, contents), (renpy.TEXT_TAG, u"/color") ]

        return [ (renpy.TEXT_TEXT, contents) ]

    config.custom_text_tags["wt"] = wtTag

label start:

    scene black with fade
    "*** START ***"

label ask_the_question:

    menu:
        "{wt}Choice #1{/wt}":
            "You made a good choice."

        "Choice #2":
            "You made a bad choice."

        "Enable Walkthrough":
            "Walkthrough enabled."
            $ persistent.walkthrough = True

        "Disable Walkthrough":
            "Walkthrough disabled."
            $ persistent.walkthrough = False

        "Quit":
            jump the_end

    jump ask_the_question

label the_end:

    "*** THE END ***"
    return

I've typed in that code purely from the documentation and forum posts here on F95. I haven't actually tested it yet. But it should work.

In this case, text surrounded by the {wt} {/wt} tags will be highlighted in green if the persistent.walkthrough flag is set. Otherwise, it will be displayed normally.
Basically, it's a good way of doing a walkthrough without repeating the same menu choices twice or more.

You could get more flamboyant and include small icons/pictures as part of the text too using renpy.TEXT_DISPLAYABLE.
And you could color code stuff, with more than one custom tag (perhaps separate tags for alternative routines in the walkthrough? 'Mom route', 'Sis route', 'Abstinence route', etc.) ... tags like {wt_m} {/wt_m}, {wt_s} {/wt_s} or {wt_a} {/wt_a}.
Hi, I'm really starting to rethink this idea , I think your vision seems more correct to me. I will analyze the posibilities and think about another way, thanks!
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
Hi, I'm really starting to rethink this idea , I think your vision seems more correct to me. I will analyze the posibilities and think about another way, thanks!
It depend how your game will be, but 79flavors approach is even more flexible than mine, and it can be extended a little bit for a total flexibility:

Python:
label whatever:

    menu:
        "How to spend the afternoon ?"
        "{wt=mom}Stay at home{/wt}:  # MC will pass time with his mom - advance mom route
            [...]
        "{wt=anna}Go for a walk{/wt}:   # MC will encounter a girl - starts Anna route
            [...]

label whateverElse:
    menu:
        "what movie to choose ?"
        "A comedy":
            [...]
        "{wt=Choose if in love route, else whatever is fine}A sweet romance{/wt}":
            [...]
        "An action movie":
            [...]
The code for the tag would be a bit more complex, but still relatively simple to use:
/!\ I'm at work, so I haven't tested it. But normally it should works /!\
Python:
   def wtTag(tag, arg, contents):

        # Inverted to simplify the code
        if not walkthrough:
            return [] + contents + []

        # If the argument is one of the pre-defined one
        if arg in [ "mom", "sister", "anna" ]:
            return [ (renpy.TEXT_TAG, u"color=#00FF00") ] +  contents + [ (renpy.TEXT_TEXT, " ({} route)".format( arg ) ), (renpy.TEXT_TAG, u"/color") ]
        # If the argument is a free text
        else:
            return [ (renpy.TEXT_TAG, u"color=#00FF00") ] +  contents + [ (renpy.TEXT_TEXT, " ({})".format( arg ) ), (renpy.TEXT_TAG, u"/color") ]