Ren'Py Get translations to work on Renpy init python

Sakrilas

Just Another Member
Game Developer
Oct 26, 2017
363
2,654
My game's translation is done by volunteer native speakers from different languages, this means that the translation team changes with time.

I credit the translators in the about page and also in the end credits of the game. And I used to have it be like this:
1655753586882.png

The thing is, every time the translation team changed, the translations of this entire "about section" gets invalidated.

I don't want to increase the work of our volunteer translators to be more than it needs to be. So, with the intent of being able to change people names and their url links without invalidating the translations of the about page, I decided to change my approach to this:

Python:
init python:
    about_developed_by = _("Developed by")

    about_main_writer = _("Main Writer and Author")
    about_support_writer = _("Support Writer")
    about_render = _("3D Renders")
    about_renpy_script = _("Renpy Script")
    about_ui_support = _("UI Support")

    about_russian_translation = _("Russian Translation")
    about_french_translation = _("French Translation")
    about_german_translation = _("German Translation")
    about_italian_translation = _("Italian Translation")
    about_polish_translation = _("Polish Translation")
    about_portuguese_translation = _("Portuguese Translation")

    about_team = [
        {"name": 'VelcroFist', "link": 'https://www.literotica.com/stories/memberpage.php?uid=5399309', "roles": about_main_writer},
        {"name": 'Sakrilas', "link": 'https://f95zone.to/members/sakrilas.262944/', "roles": "%s, %s, %s\n" % (about_support_writer, about_render, about_renpy_script)},

        {"name": 'Alexander Chebykin', "link": 'https://github.com/CAI79', "roles": "%s, %s" % (about_ui_support, about_russian_translation)},
        {"name": 'Rustam Eyniyev', "link": 'https://github.com/Rustam-Eyniyev', "roles": about_russian_translation},

        {"name": 'Laurent Rochette', "link": 'https://www.facebook.com/laurent.rochette.75', "roles": about_french_translation},
        {"name": 'Babar', "link": 'https://f95zone.to/members/babar.73468/', "roles": about_french_translation},

        {"name": 'Fenris', "link": 'https://placeholder.com/', "roles": about_german_translation},
        {"name": 'Websl', "link": 'https://placeholder.com/', "roles": about_german_translation},


        {"name": 'GIN', "link": 'https://f95zone.to/threads/gin-italian-translations.109604/post-7641553', "roles": about_italian_translation},

        {"name": 'Piotr', "link": 'https://github.com/optimapz', "roles": about_polish_translation},

        {"name": 'Zero', "link": 'https://f95zone.to/members/zerodead.386180', "roles": about_portuguese_translation},
        {"name": 'Rui Ferreira', "link": 'https://placeholder.com/', "roles": about_portuguese_translation},
    ]

    interpolated_about = "%s:\n" % about_developed_by
    for person in about_team:
        interpolated_about += "- {a=%s}%s{/a}: %s\n" % (person["link"],person["name"], person["roles"])


define gui.about = interpolated_about
It works great, except that it is no longer translating the credits to the currently selected language.

Side note:

I also have tried using the double-underscore translation function, i.e "__("blablabla")", but the problem remains.


What am I doing wrong here? I would appreciate any kind of assistance
 
Last edited:

Sakrilas

Just Another Member
Game Developer
Oct 26, 2017
363
2,654
Hey everyone,

I'm just dropping back here to say that I got it to work now. Hopefully this will be of help for anyone reading this in the future.

The solution was to bypass the define gui.about variable altogether.

I went to screens.rpy and added the logic I had shown in the post above into the existing screen about():


Here's the final result (it's working really well):



Python:
screen about():

    python:
        about_developed_by = __("Developed by")

        about_main_writer = __("Main Writer and Author")
        about_support_writer = __("Support Writer")
        about_render = __("3D Renders")
        about_renpy_script = __("Renpy Script")
        about_ui_support = __("UI Support")

        about_russian_translation = __("Russian Translation")
        about_french_translation = __("French Translation")
        about_german_translation = __("German Translation")
        about_italian_translation = __("Italian Translation")
        about_polish_translation = __("Polish Translation")
        about_portuguese_translation = __("Portuguese Translation")

        about_team = [
            {"name": 'VelcroFist', "link": 'https://www.literotica.com/stories/memberpage.php?uid=5399309', "roles": about_main_writer},
            {"name": 'Sakrilas', "link": 'https://f95zone.to/members/sakrilas.262944/', "roles": "%s, %s, %s\n" % (about_support_writer, about_render, about_renpy_script)},

            {"name": 'Alexander Chebykin', "link": 'https://github.com/CAI79', "roles": "%s, %s" % (about_ui_support, about_russian_translation)},
            {"name": 'Rustam Eyniyev', "link": 'https://github.com/Rustam-Eyniyev', "roles": about_russian_translation},

            {"name": 'Laurent Rochette', "link": 'https://www.facebook.com/laurent.rochette.75', "roles": about_french_translation},
            {"name": 'Babar', "link": 'https://f95zone.to/members/babar.73468/', "roles": about_french_translation},

            {"name": 'Web', "link": 'https://www.twitter.com/Webchan', "roles": about_german_translation},
            {"name": 'Fenris', "link": 'https://placeholder.com/', "roles": about_german_translation},

            {"name": 'GIN', "link": 'https://f95zone.to/threads/gin-italian-translations.109604/post-7641553', "roles": about_italian_translation},

            {"name": 'Piotr', "link": 'https://github.com/optimapz', "roles": about_polish_translation},

            {"name": 'Zero', "link": 'https://f95zone.to/members/zerodead.386180', "roles": about_portuguese_translation},
            {"name": 'Rui Ferreira', "link": 'https://placeholder.com/', "roles": about_portuguese_translation},
        ]

        interpolated_about = "%s:\n" % about_developed_by
        for person in about_team:
            interpolated_about += "- {a=%s}%s{/a}: %s\n" % (person["link"],person["name"], person["roles"])

    tag menu

    ## This use statement includes the game_menu screen inside this one. The
    ## vbox child is then included inside the viewport inside the game_menu
    ## screen.
    use game_menu(_("About"), scroll="viewport"):

        style_prefix "about"

        vbox:

            label "[config.name!t]"
            text _("Version [config.version!t]\n")

            text "[interpolated_about!ti]"

            text _("Made with {a=https://www.renpy.org/}Ren'Py{/a} [renpy.version_only].\n\n[renpy.license!t]")

I hope this will be of help. Cheers!
 
  • Like
Reactions: Bev_

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,607
2,256
Not sure about __(), but _() is the workaround RenPy uses to mark strings that wouldn't be normally translated for translation.

gui.about is just a variable called about within the gui datastore. It's used within screen about(): to show all that text in one go.

It doesn't matter how gui.about is set. You can use the standard logic to set it as a single value all in one go.
But you could also build it slowly, by appending one value after another until it's how you want it.

If you broke it down that way, you could wrap _() around the individual parts before they're appended them together, making translation easier.

Loosely...

Python:
define about_part1 = _("First Line")
define about_part2 = _("Second Line")
define about_part3 = _("Third Line")

define gui.about = about_part1 + about_part2 + about_part3

Though you might need to add the Carriage Return and Line Feed character into the mix to separate each line (CRLF).

Alternatively, the route you've taken...

Just don't use gui.about within the screen about(): and instead do each line separately.

For the record, """ is for .
 
Last edited:

Sakrilas

Just Another Member
Game Developer
Oct 26, 2017
363
2,654
Not sure about __(), but _() is the workaround RenPy uses to mark strings that wouldn't be normally translated for translation.

gui.about is just a variable called about within the gui datastore. It's used within screen about(): to show all that text in one go.

It doesn't matter how gui.about is set. You can use the standard logic to set it as a single value all in one go.
But you could also build it slowly, by appending one value after another until it's how you want it.

If you broke it down that way, you could wrap _() around the individual parts before they're appended them together, making translation easier.

Loosely...

Python:
define about_part1 = _("First Line")
define about_part2 = _("Second Line")
define about_part3 = _("Third Line")

define gui.about = about_part1 + about_part2 + about_part3

Though you might need to add the Carriage Return and Line Feed character into the mix to separate each line (CRLF).

Alternatively, the route you've taken...

Just don't use gui.about within the screen about(): and instead do each line separately.

For the record, """ is for .
What you mentioned was my original attempt, but the code was way too hard to maintain considering the size of the team. That's why I moved towards using a for loop in regular python, but then if I changed languages in the game options, the About menu wouldn't update to the translated version of the new language.

I realize the gui.about is just a variable like all others, but my point is that for me to populate it with variables that were computed in regular python I was having to write code running at the "init python:" label level (really early in the lifecycle), when I stopped trying to use the gui.about I could just use the regular "python:" label within the about screen function, which somehow allowed the translations to work again.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,192
[...] when I stopped trying to use the gui.about I could just use the regular "python:" label within the about screen function, which somehow allowed the translations to work again.
I'm not sure that it was what make the translation works again. It help since you assign the strings each time the screen is displayed, but normally you're still assigning the English version to the different variables.
It's more sure the !t in your text "[interpolated_about!ti]", that made it works again. !t being the special operator telling Ren'Py to force the translation of the content.

I guess that if you moved the assignation from the screen to an "init" block, it would still works.
 

moskyx

Forum Fanatic
Jun 17, 2019
4,219
13,959
I'm not sure that it was what make the translation works again. It help since you assign the strings each time the screen is displayed, but normally you're still assigning the English version to the different variables.
It's more sure the !t in your text "[interpolated_about!ti]", that made it works again. !t being the special operator telling Ren'Py to force the translation of the content.

I guess that if you moved the assignation from the screen to an "init" block, it would still works.
That's right. The !t is what makes the text to be displayed correctly translated, since all the variable's data are originally written in English. But only after you wrote the double underscore __( )

The double underscore __( ) wrapping the text in a Python block stores the translated value instead of the original English whenever the code is run (in this case, whenever the screen is processed). But if you were playing let's say in Russian and then pick another language, the stored value will be the Russian one, and without the !t (as the OP already experiencied) the stored value to be displayed in all languages would be the Russian one as it's the last language the game was launched, no matter what language you are currently playing in. The !t thingy forces Ren'Py to look for a valid translation and display that stored text in the current language in use.
 
Last edited: