Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Internacionalizando jogos

Introdução

Embora jogos independentes ou de nicho geralmente não precisem de localização, jogos voltados para um mercado mais amplo frequentemente requerem localização. O Godot oferece muitas ferramentas para tornar esse processo mais fácil, então este tutorial é mais uma coleção de dicas e truques.

A localização geralmente é feita por estúdios específicos contratados para isso. Apesar da grande quantidade de software e formatos de arquivo disponíveis, a forma mais comum de localização ainda é o uso de planilhas. O processo de criação e importação dessas planilhas é abordado no tutorial Importando traduções. Se você ainda não leu a página de importação de traduções, recomenda-se lê-la antes desta página.

Nota

Usaremos a demo oficial como exemplo; você pode baixá-la na Asset Library.

Configurando a tradução importada

Traduções podem ser atualizadas e reimportadas quando alteradas, mas ainda precisam ser adicionadas ao projeto. Isso é feito em Project > Project Settings > Localization > Translations:

../../_images/localization_dialog.webp

A caixa de diálogo acima é usada para adicionar ou remover traduções em todo o projeto.

Localizando recursos

Também é possível instruir a Godot para usar versões alternativas de assets (recursos), dependendo do idioma atual. Isso pode ser usado para imagens localizadas, como outdoors (anúncios) dentro do jogo, ou vozes localizadas.

A aba Remaps pode ser usada para isso:

../../_images/localization_remaps.webp

Selecione o recurso a ser remapeado e então adicione alternativas para cada localidade.

Nota

O sistema de remapeamento de recursos não é suportado para DynamicFonts. Para usar fontes diferentes dependendo do script do idioma, use o sistema de fallback do DynamicFont, que permite definir quantas fontes de fallback você desejar.

A vantagem do sistema de fallback do DynamicFont é que ele funciona independentemente do idioma atual, tornando-o ideal para coisas como o chat multiplayer, onde o idioma do texto pode não corresponder ao idioma do cliente.

Definição automática de idioma

Recomenda-se definir como padrão o idioma preferido do usuário, que pode ser obtido via OS.get_locale_language(). Se o seu jogo não estiver disponível nesse idioma, ele voltará para o Fallback em Project > Project Settings > General > Internationalization > Locale, ou para en se estiver vazio. No entanto, permitir que os jogadores alterem o idioma no jogo é recomendado por vários motivos (por exemplo, qualidade da tradução ou preferência do jogador).

var language = "automatic"
# Load here language from the user settings file
if language == "automatic":
   var preferred_language = OS.get_locale_language()
   TranslationServer.set_locale(preferred_language)
else:
   TranslationServer.set_locale(language)

Localidade (Locale) vs. idioma

Uma localidade (locale) costuma ser a combinação de um idioma com uma região ou país, mas também pode conter informações como um script ou uma variante.

Exemplos:

  • en: Idioma inglês

  • en_GB: Inglês na Grã-Bretanha / Inglês britânico

  • en_US: Inglês nos EUA / Inglês americano

  • en_DE: Inglês na Alemanha

Jogos indie geralmente precisam apenas se preocupar com o idioma, mas continue lendo para obter mais informações.

A razão pela qual as localidades existem pode ser ilustrada por meio dos EUA e da Grã-Bretanha. Ambos falam o mesmo idioma (inglês), mas diferem em muitos aspectos:

  • Ortografia: por exemplo, gray (EUA), grey (Grã-Bretanha)

  • Uso de palavras: por exemplo, eggplant (EUA), aubergine (Grã-Bretanha)

  • Unidades ou moedas: por exemplo, pés/polegadas (EUA), metros/cm (Grã-Bretanha)

No entanto, isso pode ficar mais complexo. Imagine que você oferece conteúdos diferentes na Europa e na China (por exemplo, em um MMO). Você precisará traduzir cada uma dessas variações de conteúdo para vários idiomas e armazená-las e carregá-las de acordo.

Convertendo chaves em texto

Alguns controles, como Button e Label, buscam automaticamente uma tradução se o texto corresponder a uma chave de tradução. Por exemplo, se o texto de um Label for MAIN_SCREEN_GREETING1 e essa chave existir na tradução atual, então o texto será traduzido automaticamente.

Este comportamento de tradução automática pode ser indesejável em certos casos. Por instância, ao usar uma Etiqueta (Label) para mostrar o nome do jogador, você provavelmente não quer que o nome do jogador seja traduzido se ele se encaixa em uma chave de tradução. Para desabilitar a tradução automática em um nó específico, defina Auto Translate > Mode para Desabilitado no inspetor.

No código, a função Object.tr() pode ser usada. Isso apenas pesquisará o texto nas traduções e o converterá se encontrado:

level.text = tr("LEVEL_5_NAME")
status.text = tr("GAME_STATUS_%d" % status_index)

Nota

Se nenhum texto for exibido após alterar o idioma, tente usar uma fonte diferente. A fonte padrão do projeto suporta apenas um subconjunto do conjunto de caracteres Latin-1, que não pode ser usado para exibir idiomas como o russo ou o chinês.

Um bom recurso para fontes multilíngues é o Noto Fonts. Certifique-se de baixar a variação correta se estiver usando um idioma menos comum.

Depois de baixar a fonte, carregue o arquivo TTF em um recurso DynamicFont e use-o como uma fonte customizada (custom font) do seu nó Control. Para uma melhor reutilizabilidade, associe um novo recurso Theme ao seu nó Control raiz e defina a DynamicFont como a Default Font (Fonte Padrão) no tema.

Lugar reservado

Para incluir placeholders nas suas strings traduzidas, use o Formatação de Strings em GDScript ou o recurso equivalente em C#. Isso permite que os tradutores movam o local do placeholder na string livremente, fazendo com que as traduções pareçam mais naturais. Placeholders nomeados com a função String.format() devem ser usados sempre que possível, pois também permitem que os tradutores escolham a ordem em que os placeholders aparecem:

# The placeholder's locations can be changed, but not their order.
# This will probably not suffice for some target languages.
message.text = tr("%s picked up the %s") % ["Ogre", "Sword"]

# The placeholder's locations and order can be changed.
# Additionally, this form gives more context for translators to work with.
message.text = tr("{character} picked up the {weapon}").format({character = "Ogre", weapon = "Sword"})

Contextos de tradução

Se você estiver usando o inglês simples como strings de origem (em vez de códigos de mensagem como LIKE_THIS), você pode se deparar com ambiguidades quando tiver que traduzir a mesma string em inglês para strings diferentes em certos idiomas de destino. Você pode opcionalmente especificar um contexto de tradução para resolver essa ambiguidade e permitir que os idiomas de destino usem strings diferentes, mesmo que a string de origem seja idêntica:

# "Close", as in an action (to close something).
button.set_text(tr("Close", "Actions"))

# "Close", as in a distance (opposite of "far").
distance_label.set_text(tr("Close", "Distance"))

Pluralização

A maioria dos idiomas exige strings diferentes dependendo se um objeto está no formato singular ou plural. No entanto, hardcodar a condição "é plural" dependendo apenas se há mais de 1 objeto não é válido em todos os idiomas.

Alguns idiomas têm mais de duas formas plurais, e as regras sobre a quantidade de objetos necessários para cada forma plural variam. O Godot oferece suporte para pluralização para que as localidades de destino possam lidar com isso automaticamente.

A pluralização é destinada a ser usada apenas com números inteiros positivos (ou zero). Valores negativos e de ponto flutuante geralmente representam entidades físicas para as quais o singular e o plural não se aplicam claramente.

var num_apples = 5
label.text = tr_n("There is %d apple", "There are %d apples", num_apples) % num_apples

Isso pode ser combinado com um contexto, se necessário:

var num_jobs = 1
label.text = tr_n("%d job", "%d jobs", num_jobs, "Task Manager") % num_jobs

Tornando os controles redimensionáveis

O mesmo texto em diferentes idiomas pode variar muito em comprimento. Para isso, certifique-se de ler o tutorial em Tamanho e âncoras, pois ajustar dinamicamente os tamanhos de controle pode ajudar. Container pode ser útil, assim como as opções de quebra de texto disponíveis em Label.

Para verificar se a sua interface de usuário (UI) pode acomodar traduções com strings mais longas que o original, você pode ativar a pseudolocalização nas Configurações Avançadas do Projeto. Isso substituirá todas as suas strings localizáveis por versões mais longas delas mesmas, ao mesmo tempo em que substitui alguns caracteres das strings originais por versões acentuadas (mas ainda legíveis). Os placeholders são mantidos como estão, de modo que continuam funcionando quando a pseudolocalização está ativada.

Por exemplo, a string Hello world, this is %s! torna-se [Ĥéłłô ŵôŕłd́, ŧh̀íš íš %s!] quando a pseudolocalização está ativada.

Embora pareça estranha no início, a pseudolocalização traz vários benefícios:

  • Ela permite detectar rapidamente strings não localizáveis, para que você possa revisá-las e torná-las localizáveis (se fizer sentido fazer isso).

  • Ela permite verificar elementos da interface de usuário que não conseguem comportar strings longas. Muitos idiomas apresentarão traduções muito mais longas do que o texto original, por isso é importante garantir que sua interface possa acomodar strings mais longas que o habitual.

  • Ela permite verificar se a sua fonte contém todos os caracteres necessários para suportar vários idiomas. No entanto, como o objetivo da pseudolocalização é manter as strings originais legíveis, ela não é um teste eficaz para verificar se uma fonte oferece suporte a idiomas CJK ou que são escritos da direita para a esquerda.

As configurações do projeto permitem que você ajuste o comportamento da pseudolocalização, de modo que você pode desativar partes dela se desejar.

TranslationServer

O Godot possui um servidor responsável pelo gerenciamento de localização em baixo nível chamado TranslationServer. Traduções podem ser adicionadas ou removidas em tempo de execução; o idioma atual também pode ser alterado em tempo de execução.

Texto bidirecional e espelhamento de interface de usuário (UI mirroring)

O árabe e o hebraico são escritos da direita para a esquerda (exceto pelos números e palavras em latim misturadas no meio), e a interface do usuário para esses idiomas também deve ser espelhada. Em alguns idiomas, o formato de um glifo muda dependendo dos caracteres ao redor.

O suporte para sistemas de escrita bidirecionais e espelhamento de interface é transparente; normalmente você não precisa alterar nada ou ter qualquer conhecimento do sistema de escrita específico.

Para idiomas RTL (da direita para a esquerda), o Godot aplicará automaticamente as seguintes alterações na interface do usuário:

  • Espelha as âncoras e margens esquerdas/direitas.

  • Inverte o alinhamento de texto à esquerda e à direita.

  • Espelha a ordem horizontal dos nós de controle filhos nos containers e dos itens nos controles Tree/ItemList.

  • Usa a ordem espelhada dos elementos internos de controle (por exemplo, o botão de dropdown do OptionButton, o alinhamento de CheckBox/CheckButton, a ordem das colunas de Listas, os ícones do TreeItem e o alinhamento das linhas de conexão). Em alguns casos, controles espelhados usam estilos de tema separados.

  • Sistema de Coordenadas não está espelhado.

  • Nós que não pertencem à interface (sprites, etc.) não são afetados.

É possível sobrescrever a direção do texto e do layout do controle usando as seguintes propriedades de controle:

  • text_direction, define a direção base do texto. Quando definida como "auto", a direção depende do primeiro caractere com direção forte no texto, de acordo com o Algoritmo Bidirecional Unicode.

  • language, sobrescreve a localidade atual do projeto.

  • A propriedade structured_text_bidi_override e o callback _structured_text_parser ativam o tratamento especial para textos estruturados.

  • layout_direction, sobrescreve o espelhamento do controle.

../../_images/ui_mirror.png

Ver também

Você pode ver como a tipografia da direita para a esquerda funciona na prática usando o projeto de demonstração BiDI and Font Features.

Adicionando dados de quebra de linha ao projeto exportado

Alguns idiomas são escritos sem espaços. Nesses idiomas, a quebra de palavras e linhas requer mais do que regras sobre sequências de caracteres. O Godot inclui dados do iterador de quebras baseados em dicionários e regras da ICU, mas esses dados não são incluídos por padrão em projetos exportados.

Para incluí-los, vá em Project > Project Settings > General > Internationalization > Locale e ative Include Text Server Data, depois exporte o projeto. Os dados do iterador de quebras têm cerca de 4 MB de tamanho.

Sobrescrita de BiDi em texto estruturado

O algoritmo BiDi do Unicode foi projetado para funcionar com texto natural e é incapaz de lidar com textos que possuem uma ordem de nível superior, como nomes de arquivos, URIs, endereços de e-mail, expressões regulares ou código-fonte.

../../_images/bidi_override.png

Por exemplo, o caminho para a estrutura de diretórios exibida será mostrado incorretamente (controle "LineEdit" superior). A sobrescrita de texto estruturado do tipo "File" divide o texto em segmentos, aplicando então o algoritmo BiDi a cada um deles individualmente para exibir corretamente os nomes dos diretórios em qualquer idioma e preservar a ordem correta das pastas (controle "LineEdit" inferior).

Callbacks customizados fornecem uma maneira de sobrescrever o BiDi para outros tipos de texto estruturado.

Localização de números

Controles projetados especificamente para entrada ou saída de números (por exemplo, ProgressBar, SpinBox) usarão o sistema de numeração localizado automaticamente; para outros controles, TextServer.format_number(string, language) pode ser usado para converter números arábicos ocidentais (0..9) para o sistema de numeração localizado e TextServer.parse_number(string, language) para convertê-los de volta.

Localização de ícones e imagens

Ícones com setas apontando para a esquerda e para a direita podem precisar ser invertidos para as localidades em árabe e hebraico, caso indiquem movimento ou direção (por exemplo, botões de voltar/avançar). Caso contrário, eles podem permanecer os mesmos.

Testando traduções

Você pode querer testar a tradução de um projeto antes de lançá-lo. O Godot oferece três maneiras de fazer isso.

Em Project > Project Settings > General > Internationalization > Locale (com configurações avançadas habilitadas) existe uma propriedade Test. Defina esta propriedade para o código de localidade (locale) do idioma que você deseja testar. O Godot executará o projeto com essa localidade quando o projeto for executado (seja a partir do editor ou quando exportado).

../../_images/locale_test.webp

Lembre-se de que, como essa é uma configuração do projeto, ela aparecerá no controle de versão quando for definida como um valor não vazio. Portanto, ele deve ser definido como um valor vazio antes de confirmar as alterações no controle de versão.

Segundo, de dentro do editor, vá até a barra superior e clique em View, depois desça até Preview Translation e selecione o idioma que deseja pré-visualizar.

../../_images/locale_editor_preview.webp

Todo o texto nas cenas do editor agora deve ser exibido no idioma selecionado.

As traduções também podem ser testadas ao executar o Godot pela linha de comando. Por exemplo, para testar um jogo em francês, o seguinte argumento pode ser fornecido:

godot --language fr

Traduzindo o nome do projeto

O nome do projeto torna-se o nome do aplicativo ao exportar para diferentes sistemas operacionais e plataformas. Para especificar o nome do projeto em mais de um idioma, vá para Project > Project Settings > General > Application > Config. A partir daí, clique no botão Localizable String (Size 0) e, em seguida, no botão Add Translation. Isso o levará a uma página onde você poderá escolher o idioma (e o país, se necessário) para a tradução do nome do projeto. Após fazer isso, você poderá digitar o nome localizado.

../../_images/localized_name.webp

Se você não tem certeza sobre o código do idioma a ser usado, consulte a lista de códigos de localização.