Ren'Py Outlines with show text

Playstorepers

Member
May 24, 2020
160
79
Hey everyone,

Can someone tell me, what the right syntax for outlines in show text is?

According to the documentation it's:

outlines [ (absolute(1), "#000", absolute(0), absolute(0)) ]

But I don't know, how to apply it in the show text command.

I want to show a text in the middle of the screen, which works nicely, but I would prefer it , if the text shown in the middle has an outline.

My approach so far is just plain bad and doesn't work:

Python:
show text "{size=+30}THIS TEXT SHALL APPEAR IN THE MIDDLE OF THE SCREEN{/size}":
    outlines[(absolute(1), "#000", absolute(0), absolute(0))]
    Dissolve(1.2)
So it would be much appreciated, if anyone knows, how to add a outline for this part only.
I know, how to add an outline everywhere, but I only need the outline this once.

Thanks in advance.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
But I don't know, how to apply it in the show text command.
The answer is to use .

from memory:
Code:
label whatever:
    show expression Text( "{size=+30}THIS TEXT SHALL APPEAR IN THE MIDDLE OF THE SCREEN{/size}", outlines=[(absolute(1), "#000", absolute(0), absolute(0))] )
    with  Dissolve(1.2)
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
I must admit, I was getting nowhere with this.

Closest I'd gotten was:

Python:
style big_text_with_outline is text:
    outlines [ (12, "#00ff00", 0, 0) ]
    size 30

    show text "{=big_text_with_outline}THIS IS JUST ME MESSING ABOUT with text shadowing"

Which uses a {=stylename} tag to use a pre defined style. Except, it refused to recognize the outlines portion of the style.
I'm using a green outline just to be REALLY soddin' unsubtle.
Edit: It doesn't work, if that wasn't clear.

I can confirm that:

Python:
    show expression Text ("THIS IS JUST ME MESSING ABOUT with text shadowing", outlines=[ (12, "#00ff00", 0, 0) ], size=30) at truecenter

Works just as Anne says.
 
Last edited:

Playstorepers

Member
May 24, 2020
160
79
Thanks you two, but now I was trying out both of your methods and there were still a lot of problems.

I must admit, I was getting nowhere with this.

Closest I'd gotten was:

Python:
style big_text_with_outline is text:
    outlines [ (12, "#00ff00", 0, 0) ]
    size 30

    show text "{=big_text_with_outline}THIS IS JUST ME MESSING ABOUT with text shadowing"

Which uses a {=stylename} tag to use a pre defined style. Except, it refused to recognize the outlines portion of the style.
I'm using a green outline just to be REALLY soddin' unsubtle.

I can confirm that:

Python:
    show expression Text ("THIS IS JUST ME MESSING ABOUT with text shadowing", outlines=[ (12, "#00ff00", 0, 0) ], size=30) at truecenter
Works just as Anne says.

This one is just as you mentioned:
outlines doesn't yield the result, that I want it to.


The answer is to use .

from memory:
Code:
label whatever:
    show expression Text( "{size=+30}THIS TEXT SHALL APPEAR IN THE MIDDLE OF THE SCREEN{/size}", outlines=[(absolute(1), "#000", absolute(0), absolute(0))] )
    with  Dissolve(1.2)
And with this one, I don't know how to replace it.
The outlines work perfectly, but once I try to add another text, the first one remains.
Technically, I can work around by adding a new screen/scene over it, but that is kinda janky.

hide expression Text does nothing
and
a new show expression Text just adds a new text on top of the existing one.

But I am very grateful for your tips so far.
If worse comes to worst, I'll just add a new screen to kill the expressions, but I'm probably missing out on a trick to make the shown expression disappear, right?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
I can confirm that:
[...]
Works just as Anne says.
While writing it, I felt that there were a problem, but wasn't sure. And in fact yes, there's one :( It works, because it show the text, but because the Text object is created directly in the show statement, it also don't works because :
And with this one, I don't know how to replace it.
The outlines work perfectly, but once I try to add another text, the first one remains.
Yeah, globally speaking, the hide statement works by taking a reference to the element that have to be hidden, and removing it from the list of elements to display. Except that here you've no reference to this element, and therefore you can't hide it.

This while works :
Code:
label whatever:

    $ showedText = Text( "THIS TEXT SHALL APPEAR IN THE MIDDLE OF THE SCREEN", outlines=[ ( 1, "#000", 0, 0 ) ], size=30)
    show expression showedText  at truecenter
    pause
    hide expression showedText
 
  • Like
Reactions: UncleNanard

Playstorepers

Member
May 24, 2020
160
79
While writing it, I felt that there were a problem, but wasn't sure. And in fact yes, there's one :( It works, because it show the text, but because the Text object is created directly in the show statement, it also don't works because :


Yeah, globally speaking, the hide statement works by taking a reference to the element that have to be hidden, and removing it from the list of elements to display. Except that here you've no reference to this element, and therefore you can't hide it.

This while works :
Code:
label whatever:

    $ showedText = Text( "THIS TEXT SHALL APPEAR IN THE MIDDLE OF THE SCREEN", outlines=[ ( 1, "#000", 0, 0 ) ], size=30)
    show expression showedText  at truecenter
    pause
    hide expression showedText

Damn, I didn't think about that.

That's one of the best methods to implement it, I think.

Thanks
 

UncleNanard

I am to music what Kanye West is to adult games.
Game Developer
Jul 1, 2017
1,644
1,617
I must admit, I was getting nowhere with this.

Closest I'd gotten was:

Python:
style big_text_with_outline is text:
    outlines [ (12, "#00ff00", 0, 0) ]
    size 30

    show text "{=big_text_with_outline}THIS IS JUST ME MESSING ABOUT with text shadowing"

Which uses a {=stylename} tag to use a pre defined style. Except, it refused to recognize the outlines portion of the style.
I'm using a green outline just to be REALLY soddin' unsubtle.
Edit: It doesn't work, if that wasn't clear.

I can confirm that:

Python:
    show expression Text ("THIS IS JUST ME MESSING ABOUT with text shadowing", outlines=[ (12, "#00ff00", 0, 0) ], size=30) at truecenter

Works just as Anne says.
While writing it, I felt that there were a problem, but wasn't sure. And in fact yes, there's one :( It works, because it show the text, but because the Text object is created directly in the show statement, it also don't works because :


Yeah, globally speaking, the hide statement works by taking a reference to the element that have to be hidden, and removing it from the list of elements to display. Except that here you've no reference to this element, and therefore you can't hide it.

This while works :
Code:
label whatever:

    $ showedText = Text( "THIS TEXT SHALL APPEAR IN THE MIDDLE OF THE SCREEN", outlines=[ ( 1, "#000", 0, 0 ) ], size=30)
    show expression showedText  at truecenter
    pause
    hide expression showedText
e36.png
 

Tribe

Member
Game Developer
May 5, 2021
226
492
While writing it, I felt that there were a problem, but wasn't sure. And in fact yes, there's one :( It works, because it show the text, but because the Text object is created directly in the show statement, it also don't works because :


Yeah, globally speaking, the hide statement works by taking a reference to the element that have to be hidden, and removing it from the list of elements to display. Except that here you've no reference to this element, and therefore you can't hide it.

This while works :
Code:
label whatever:

    $ showedText = Text( "THIS TEXT SHALL APPEAR IN THE MIDDLE OF THE SCREEN", outlines=[ ( 1, "#000", 0, 0 ) ], size=30)
    show expression showedText  at truecenter
    pause
    hide expression showedText
I won't say that my hours of research and study to find a solution were a waste of my time, but It's hard. I can't imagine where the state of Ren'Py game development would be without you guys.
anne O'nymous 79flavors Thanks again, I love you guys, and Happy Holidays
 

coffeeaddicted

Well-Known Member
Apr 13, 2021
1,825
1,481
Mm.. i tried that but copy and paste doesn't seem to work in my case.

I have a name choice and want to have that text outlined as well.

Code:
$ mname = renpy.input("What would you like to be called by your son? \n{color=#ff0000}Default is Mom.{/color}", outlines=[(absolute(2), "#000", absolute(0), absolute(0))] )
$ mname = mname.strip()
This code does not work sadly. It gives me an error.

Code:
I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/reunion.rpy", line 8, in script
    $ mname = renpy.input("What would you like to be called by your son? \nDefault is Mom.", outlines=[(absolute(2), "#000", absolute(0), absolute(0))] )
  File "game/reunion.rpy", line 8, in <module>
    $ mname = renpy.input("What would you like to be called by your son? \nDefault is Mom.", outlines=[(absolute(2), "#000", absolute(0), absolute(0))] )
TypeError: renpy.input() got unexpected keyword argument(s): outlines

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/reunion.rpy", line 8, in script
    $ mname = renpy.input("What would you like to be called by your son? \nDefault is Mom.", outlines=[(absolute(2), "#000", absolute(0), absolute(0))] )
  File "D:\RenPy\renpy-8.0.0-sdk\renpy\ast.py", line 1131, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "D:\RenPy\renpy-8.0.0-sdk\renpy\python.py", line 1061, in py_exec_bytecode
    exec(bytecode, globals, locals)
  File "game/reunion.rpy", line 8, in <module>
    $ mname = renpy.input("What would you like to be called by your son? \nDefault is Mom.", outlines=[(absolute(2), "#000", absolute(0), absolute(0))] )
  File "D:\RenPy\renpy-8.0.0-sdk\renpy\exports.py", line 850, in input
    raise TypeError("renpy.input() got unexpected keyword argument(s): {}".format(", ".join(kwargs.keys())))
TypeError: renpy.input() got unexpected keyword argument(s): outlines

Windows-10-10.0.22621 AMD64
Ren'Py 8.0.3.22090809
Becoming Family 0.01alpha
Mon Nov 28 09:54:22 2022
Anyone know what i did wrong?

In screens.rpy i setup the dialog and names to be outlined.

Code:
style window is default
style say_label is default
style say_dialogue:
    outlines [ (absolute(2), "#000", absolute(0), absolute(0)) ]
style say_dialogue is default
style say_thought is say_dialogue

style namebox is default
style say_label:
    outlines [ (absolute(2), "#000", absolute(0), absolute(0)) ]
style namebox_label is say_label
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
Anyone know what i did wrong?
Thinking that renpy.input(), that is a function accepting a limited and strictly defined list of argument, works like Text(), that is a displayable accepting at least all style elements.

There's a way to change the style of the text for an input, but I guess that here it's probably better to rely on the text style. More limited, but easier to implement.
Code:
$ mname = renpy.input("What would you like to be called by your son? \n{color=#ff0000}{outlinecolor=#000}Default is Mom.{/outlinecolor}{/color}" )
 
  • Like
Reactions: coffeeaddicted

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
I'd offer a slightly different answer:

Remove the outlines parameter from the renpy.input - it doesn't work there.
Then alter the screen input(prompt): code within the screens.rpy file...

Python:
style input:
    xalign gui.dialogue_text_xalign
    xmaximum gui.dialogue_width
    outlines [(absolute(2), "#FF0000", absolute(0), absolute(0))]    # <--- I added this line to the style.

(I'm using a red outline, to be eye-catchingly obvious. You'll probably want to use black (#000) or a dark gray (#222).
This will change the text input box contents to have an outline (which seems to what you want).

You might choose to alter the style input_prompt: too.
 
  • Like
Reactions: coffeeaddicted

coffeeaddicted

Well-Known Member
Apr 13, 2021
1,825
1,481
I'd offer a slightly different answer:

Remove the outlines parameter from the renpy.input - it doesn't work there.
Then alter the screen input(prompt): code within the screens.rpy file...

Python:
style input:
    xalign gui.dialogue_text_xalign
    xmaximum gui.dialogue_width
    outlines [(absolute(2), "#FF0000", absolute(0), absolute(0))]    # <--- I added this line to the style.

(I'm using a red outline, to be eye-catchingly obvious. You'll probably want to use black (#000) or a dark gray (#222).
This will change the text input box contents to have an outline (which seems to what you want).

You might choose to alter the style input_prompt: too.
Sadly, anne O'nymous suggestion did not work for some reason.
So i used your example and it did work. Though it seems you have to added to the style input_prompt or maybe solely. Not sure.

But now that works.

Thank you both for this quick answer.

Here is how it looks.
2022-11-28 11_07_33-Becoming Family.jpg
 

coffeeaddicted

Well-Known Member
Apr 13, 2021
1,825
1,481
I have to say that my original plan to have no background for the letters isn't working as i found out that it's scene depended for readability.
On some, no matter what color you chose, it will look bad. So much so that it is hard to read.
So i am back with the transparent box to enhance the readability but keeping the outline to emphasize the letters.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,191
I have to say that my original plan to have no background for the letters isn't working as i found out that it's scene depended for readability.
On some, no matter what color you chose, it will look bad. So much so that it is hard to read.
So i am back with the transparent box to enhance the readability but keeping the outline to emphasize the letters.
There's a game, don't remember which since it was something like 2 years ago, that had a lots of scenes with a parts that was white & black check pattern. It was purely unreadable.
But if you define a background for your text, even at high level of transparency, it flatten the contrast of the images, what will make the text stand out more easily.
 
  • Like
Reactions: coffeeaddicted

coffeeaddicted

Well-Known Member
Apr 13, 2021
1,825
1,481
There's a game, don't remember which since it was something like 2 years ago, that had a lots of scenes with a parts that was white & black check pattern. It was purely unreadable.
But if you define a background for your text, even at high level of transparency, it flatten the contrast of the images, what will make the text stand out more easily.
Ah, that sounds like a trick. :)
Have to try that.

You know, i was a little struggling how many lines a text can or should have. And i think 2 is a nice appearance for a text.
Then i thought using \n is great to make it more orderly but if the sentence is short it looks odd to me.

I kinda liked the no frame behind the writing but it just looked bad. I am older and even for me it was hard to read and i don't want the player to miss the dialog. :)

So i will try that.
Thank you so much

This how it looks right now.
2022-12-01 18_37_15-Becoming Family.jpg

I think it looks pretty good. Not as transparent but readable.

Contrast on the other hand is important to me. So it takes me a lot of times to get the lights right to not over flash the scene which can look like an atomic bomb went off.

I am not spending a lot of time to design the UI of RenPy but presentation.
And of the things is readability which is actually complicated. Fonts for example.

Anyway, i will try this out and see how it will look. I am excited. :)
 
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
This how it looks right now.
At first sigh you can still goes a bit further on the transparency.

The best way to test is to take your favorite image software (Gimp, Photoshop, whatever) then:
  • Create a 2 color depth black and white image 4 times smaller than the size you use for your game
  • Generate random noise on it.
  • Resize your image to match the size you use for your game.

You now have an image with a pattern near to a black and white checked one, but with some inconstancy. The perfect background to test what level of transparency you need to use.
 
  • Like
Reactions: coffeeaddicted

Turning Tricks

Rendering Fantasies
Game Developer
Apr 9, 2022
1,340
2,491
You should probably add the text box transparency option to your preferences menu. I never understood why that's not a default in Ren'py. It's only two tiny code blocks to add to your screens.rpy. That way the player can set it however they want.


You've probably already run across this, but is a great place to find and test a ton of fonts, to pick what you want to use in your game. You can type a sentence in and compare all the types of fonts.

Python:
## Options.rpy file, around line 35 or so or wherever you put the extra variables
default persistent.textbox_transparency = 1.0 ## Whatever you want the default to be.

## For say screen
screen say(who, what):
    style_prefix "say"

    window:
        id "window"
        background Transform(style.window.background, alpha = 1 - persistent.textbox_transparency, xalign=0.5) ##remove 1 - to reverse the opacity slider
        if who is not None:

            window:
                id "namebox"
                style "namebox"
                text who id "who"

        text what id "what" size persistent.pref_text_size


    ## If there's a side image, display it above the text. Do not display on the
    ## phone variant - there's no room.
    if not renpy.variant("small"):
        add SideImage() xalign 0.0 yalign 1.0

      
## For preferences screen
label _("Textbox Transparency")

bar value FieldValue(persistent, "textbox_transparency", range=1.0, style="slider")
 
  • Like
Reactions: coffeeaddicted

coffeeaddicted

Well-Known Member
Apr 13, 2021
1,825
1,481
At first sigh you can still goes a bit further on the transparency.

The best way to test is to take your favorite image software (Gimp, Photoshop, whatever) then:
  • Create a 2 color depth black and white image 4 times smaller than the size you use for your game
  • Generate random noise on it.
  • Resize your image to match the size you use for your game.

You now have an image with a pattern near to a black and white checked one, but with some inconstancy. The perfect background to test what level of transparency you need to use.
I will test that tomorrow. Seems interesting and nevertheless that i never would come up on my own.
Thanks Anne.
 

coffeeaddicted

Well-Known Member
Apr 13, 2021
1,825
1,481
You should probably add the text box transparency option to your preferences menu. I never understood why that's not a default in Ren'py. It's only two tiny code blocks to add to your screens.rpy. That way the player can set it however they want.


You've probably already run across this, but is a great place to find and test a ton of fonts, to pick what you want to use in your game. You can type a sentence in and compare all the types of fonts.

Python:
## Options.rpy file, around line 35 or so or wherever you put the extra variables
default persistent.textbox_transparency = 1.0 ## Whatever you want the default to be.

## For say screen
screen say(who, what):
    style_prefix "say"

    window:
        id "window"
        background Transform(style.window.background, alpha = 1 - persistent.textbox_transparency, xalign=0.5) ##remove 1 - to reverse the opacity slider
        if who is not None:

            window:
                id "namebox"
                style "namebox"
                text who id "who"

        text what id "what" size persistent.pref_text_size


    ## If there's a side image, display it above the text. Do not display on the
    ## phone variant - there's no room.
    if not renpy.variant("small"):
        add SideImage() xalign 0.0 yalign 1.0

     
## For preferences screen
label _("Textbox Transparency")

bar value FieldValue(persistent, "textbox_transparency", range=1.0, style="slider")
Interesting. Also on my testing.
So with that code the player can adjust in anyway they like it. Seems fair.
I am already glad i found out how to put the default volume to half. Otherwise my ears falls off and i like sound.

Yes, google. Who doesn't like google.
In fact i am using their fonts. Though i have to browse more to see if there are better ones.

More and more i like Renpy of all the options you have. Some are secret. Sort of.

Thanks for sharing. :)
 

coffeeaddicted

Well-Known Member
Apr 13, 2021
1,825
1,481
You should probably add the text box transparency option to your preferences menu. I never understood why that's not a default in Ren'py. It's only two tiny code blocks to add to your screens.rpy. That way the player can set it however they want.


You've probably already run across this, but is a great place to find and test a ton of fonts, to pick what you want to use in your game. You can type a sentence in and compare all the types of fonts.

Python:
## Options.rpy file, around line 35 or so or wherever you put the extra variables
default persistent.textbox_transparency = 1.0 ## Whatever you want the default to be.

## For say screen
screen say(who, what):
    style_prefix "say"

    window:
        id "window"
        background Transform(style.window.background, alpha = 1 - persistent.textbox_transparency, xalign=0.5) ##remove 1 - to reverse the opacity slider
        if who is not None:

            window:
                id "namebox"
                style "namebox"
                text who id "who"

        text what id "what" size persistent.pref_text_size


    ## If there's a side image, display it above the text. Do not display on the
    ## phone variant - there's no room.
    if not renpy.variant("small"):
        add SideImage() xalign 0.0 yalign 1.0

     
## For preferences screen
label _("Textbox Transparency")

bar value FieldValue(persistent, "textbox_transparency", range=1.0, style="slider")
That gave me an error. I suppose i missed something to add. Is this supposed to be just added?