Menu translation...

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Adorya
Miko-Class Veteran
Posts: 541
Joined: Fri Aug 18, 2006 4:51 pm
Contact:

Menu translation...

#1 Post by Adorya » Tue Aug 22, 2006 1:25 pm

As I was looking for a way to translate the menu, I found the snippet code in the extra folder which was handy since my VN project will be in english and in french.

Though it may be up to the coder to translate in his prefered language and in his own way, it would be nice to have in the website revamp the translation script already done for several language.

So here is mine, translation was not litteral and can be interpreted in many ways, but I tried to stick to the VN vocabulary :

Code: Select all

init:

    # Translatable strings found in common/mainmenu.rpy

    $ library.translations[u'Start Game'] = u'Nouvelle partie'
    $ library.translations[u'Continue Game'] = u'Charger'
    $ library.translations[u'Preferences'] = u'Préférences'
    $ library.translations[u'Quit'] = u'Quitter'

    # Translatable strings found in common/gamemenu.rpy

    $ library.translations[u'Return'] = u'Retour'
    $ library.translations[u'Begin Skipping'] = u'Lecture rapide'
    $ library.translations[u'Save Game'] = u'Sauvegarder'
    $ library.translations[u'Load Game'] = u'Charger'
    $ library.translations[u'Main Menu'] = u'Menu Principal'
    $ library.translations[u'Empty Slot.'] = u'Emplacement vide.'
    $ library.translations[u'Yes'] = u'Oui'
    $ library.translations[u'No'] = u'Non'
    $ library.translations[u'Please click to continue.'] = u'Cliquez pour continuer.'
    $ library.translations[u'Are you sure you want to quit?'] = u'Voulez vous vraiment quitter?'
    $ library.translations[u'Are you sure you want to return to the main menu?\nThis will lose unsaved progress.'] = u'Voulez vous vraiment revenir au menu principal?\nLes parties non sauvegardées seront perdues.'
    $ library.translations[u'Loading will lose unsaved progress.\nAre you sure you want to do this?'] = u'Les parties non sauvegardées seront perdues après chargement.\nVoulez vous continuer?'
    $ library.translations[u'Are you sure you want to overwrite your save?'] = u'Voulez vous sauvegarder sur cet emplacement déjà occupé?'
    $ library.translations[u'The error message was:'] = u'Message d\'erreur:'
    $ library.translations[u'You may want to try saving in a different slot, or playing for a while and trying again later.'] = u'Sauvegardez dans un emplacement différent, ou continuez à jouer et sauvergardez plus tard.'
    $ library.translations[u'Save Failed.'] = u'Echec de la sauvegarde.'
    $ library.translations[u'Previous'] = u'Précédent'
    $ library.translations[u'Next'] = u'Suivant'

    # Translatable strings found in common/library.rpy

    $ library.translations[u'Skip Mode'] = u'Mode lecture rapide'
    $ library.translations[u'Fast Skip Mode'] = u'Mode lecture rapide avancé'

    # Translatable strings found in common/preferences.rpy

    $ library.translations[u'Test'] = u'Test'
    $ library.translations[u'Joystick Mapping'] = u'Calibration de la manette'
    $ library.translations[u'Not Assigned'] = u'Non assigné'
    $ library.translations[u'Music Volume'] = u'Volume musical'
    $ library.translations[u'Sound Volume'] = u'Volume sonore'
    $ library.translations[u'Left'] = u'Gauche'
    $ library.translations[u'Right'] = u'Droite'
    $ library.translations[u'Up'] = u'Haut'
    $ library.translations[u'Down'] = u'Bas'
    $ library.translations[u'Select/Dismiss'] = u'Selection/Rejet'
    $ library.translations[u'Rollback'] = u'Retour arrière'
    $ library.translations[u'Hold to Skip'] = u'Appuyer pour défiler'
    $ library.translations[u'Toggle Skip'] = u'Basculer en défilement'
    $ library.translations[u'Hide Text'] = u'Cacher le texte'
    $ library.translations[u'Menu'] = u'Menu'
    $ library.translations[u'Move the joystick or press a joystick button to create the mapping. Click the mouse to remove the mapping.'] = u'Bouger la manette ou appuyer sur un bouton pour la calibrer. Cliquer avec la souris pour enlever la calibration.'
    $ library.translations[u'Display'] = u'Ecran'
    $ library.translations[u'Window'] = u'Fenêtre'
    $ library.translations[u'Fullscreen'] = u'Plein écran'
    $ library.translations[u'Transitions'] = u'Transitions'
    $ library.translations[u'All'] = u'Tous'
    $ library.translations[u'Some'] = u'Parfois'
    $ library.translations[u'None'] = u'Aucun'
    $ library.translations[u'Skip'] = u'Défilement auto'
    $ library.translations[u'Seen Messages'] = u'Messages déjà vus'
    $ library.translations[u'All Messages'] = u'Tous les messages'
    $ library.translations[u'After Choices'] = u'Après les choix'
    $ library.translations[u'Stop Skipping'] = u'Arrêter le défilement'
    $ library.translations[u'Keep Skipping'] = u'Continuer le défilement'
    $ library.translations[u'Text Speed'] = u'Vitesse du texte'
    $ library.translations[u'Auto-Forward Time'] = u'Vitesse de défilement auto'
    $ library.translations[u'Joystick...'] = u'Manette...'
    $ library.translations[u'Joystick Configuration'] = u'Configuration de la manette'
Only missing would be the "back to main menu" button but not all VN have this option in their gameplay:

Code: Select all

python hide:
ui.textbutton('Retour au Menu Principal.', clicked=ui.returns(True), xpos=0.5, xanchor='center', ypos=0.5, yanchor='center', textalign=0.5)

User avatar
monele
Lemma-Class Veteran
Posts: 4101
Joined: Sat Oct 08, 2005 7:57 am
Location: France
Contact:

#2 Post by monele » Tue Aug 22, 2006 3:35 pm

Ah, fellow frenchie ^.^. Hmm, does this mean you can get english *and* french menus, or only one version of these in a single game ?

User avatar
yummy
Miko-Class Veteran
Posts: 733
Joined: Fri Jul 07, 2006 9:58 pm
Projects: Suna to Majo
Location: France
Contact:

#3 Post by yummy » Tue Aug 22, 2006 6:24 pm

Oh another frenchie :)

As far as I know, you have to directly modify the script so that you have distinct versions, one french and one english.

But I think that it can be possible with if statements somehow...
although I don't know how you could possibly detect the language you want to use... That would mean the program would then detect the language before it even runs, which is impossible...

So I think localisation has to be made on different script files.

User avatar
monele
Lemma-Class Veteran
Posts: 4101
Joined: Sat Oct 08, 2005 7:57 am
Location: France
Contact:

#4 Post by monele » Wed Aug 23, 2006 8:09 am

I can think of one possibility, part of which I'm already using :

- Test the presence of the language setting in the persistent scope (persistent.language for example). If not set, use a choice for the user to pick the right one and save it. The trick is to have it in the splashscreen label which is run *before* the main menu :

Code: Select all

label splashscreen:
    if not persistent.set_language:
        call f_language from _call_f_language_1
    #

label f_language:
    $ persistent.set_language = True
    menu m_langue_persist:
        "Choisissez votre langue / Pick your language"
        "Français":
            $ persistent.language = "FR"
        "English":
            $ persistent.language = "EN"
    #
    return
#
This works, I use it for my game.

Now the additional thing is to test this value during initialization of the menu translations. What happens :

The variable isn't set yet : default to french.
The variable is set : use it to determine the translation to use.

Problem : the first time the game is run, the user chooses english and still gets french menu because init is *before* splashscreen. Arg uh? :)
Possible solution : when the language is chosen, define translations once again. But PyTom is usually against setting config variables at runtime :/... If it's only because they're not saved, then it won't cause a problem here though.

User avatar
Jake
Support Hero
Posts: 3826
Joined: Sat Jun 17, 2006 7:28 pm
Contact:

#5 Post by Jake » Wed Aug 23, 2006 9:02 am

monele wrote:But PyTom is usually against setting config variables at runtime :/... If it's only because they're not saved, then it won't cause a problem here though.
I thought it was as much a politeness thing - just that setting config variables like auto-forward speed or music volume at runtime robs the user of the chance to choose their own values... I'd certainly be interested myself if there's more to it than that.


And as it goes...
yummy wrote:That would mean the program would then detect the language before it even runs, which is impossible...
I know that it's technically easily feasible in Windows to make an educated guess, at least - you can get information from the OS as to what language the user's system uses, and then make your choices based on that. The .NET framework has this quite heavily integrated, you can more or less have it make the choices for you, even... but I don't know how readily this functionality is available on other platforms, or through Python.
Server error: user 'Jake' not found

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#6 Post by PyTom » Wed Aug 23, 2006 9:50 am

You want to avoid changing styles and config variables at runtime. This is because changes to these variables often won't take effect if they're changed late in the process... and if they do, it may not work in the way you'd hope.

Changing fields (but not variables) defined in the init process is similarly undefined, as they won't be saved, and may (often will) persist beyond a single game session. When Ren'Py is restarted, or a game is loaded,they will go back to their old values... making them impossible to reason about. The library.whatever fields fall into this category.

The solution to having a multi-language menu is to redefine the undocumented _ function. This function takes a string, and returns a translated string. If we store the user's language choice in a persistent variable, then we can have _ factor it in when making a decision.

Code: Select all

init:
    # Set these up like library.translations.
    $ french_translations = {  }
    $ english_translations = { }

    python:
        def _(s):
            if persistent.language == "french":
                return french_translations.get(s, s)
            else:
                return english_translations.get(s, s)

label splashscreen:

    menu:
        "Proceed in English.":
             $ persistent.language = "english"
        "Procéder en français":
             $ persistent.language = "french"

    return
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

yuirei
Regular
Posts: 47
Joined: Fri Aug 04, 2006 10:00 am
Contact:

#7 Post by yuirei » Thu Aug 24, 2006 3:51 pm

I don't know if this would be helpful but you could try tinkering about python's XML API and specify your translations there (you only traverse to the langauge you only need). I haven't really used it .. so I'm not really sure about this idea ^^

We had a web development project that involved multilingual support, what we did is to define a resource bundle (a text file that has key-value pairs) and call labels in that resource as we needed it.

Post Reply

Who is online

Users browsing this forum: Google [Bot], Majestic-12 [Bot]