Localização

Esta página foi traduzida automaticamente e pode conter erros. Encontrou um problema? Use o link "Edit this page" para ajudar a corrigir.

O sistema de localização da Turian (ADR 0011) é compartilhado pelo engine, pelo jogo compilado e pelo próprio Studio — um único runtime, um único formato de autoria, uma única CLI. Esta página cobre o fluxo de trabalho: autoria → extração → tradução → compilação → publicação.


Duas formas de chegar a uma string

Ponto de entrada Para Chave Escrito por
tr("Open Scene…") Chrome de UI (menus, botões, labels de HUD) a própria string de origem programadores, no código
Locale.key("dlg.act1.intro") Conteúdo do jogo (diálogo, nomes de itens, missões) um id estável explícito designers, em um asset .strings

Ambos são compilados na mesma tabela e servidos pelo mesmo serviço Locale — a única diferença é de onde vem o id.

// Texto simples
frame.tr("Open Scene…")

// Desambiguado por contexto (duas strings em inglês idênticas, significados diferentes)
frame.trc("door", "Open")

// Plural (a regra cardinal CLDR escolhe a forma correta para o idioma ativo)
frame.trn("# file", "# files", count, &.{})

// Interpolado (placeholders nomeados de um subconjunto ICU, não especificadores std.fmt)
frame.trArgs("Save changes to \"{title}\" before closing?", &.{
    .{ .name = "title", .value = .{ .text = doc_title } },
})

// Conteúdo do jogo escrito por designers, buscado por id
frame.trKey("dlg.act1.intro", &.{})

tr/trc/trn recebem sua mensagem como um parâmetro comptime — um argumento não literal é um erro de compilação, não um comentário de revisão. Uma tradução faltante degrada para a fonte em inglês, nunca para uma chave crua. key/trKey degradam para ⟦the.key⟧ em builds de debug e para a chave nua em release, então uma tradução de conteúdo de designer faltante nunca fica silenciosamente invisível.

A sintaxe de mensagem é um subconjunto documentado do ICU MessageFormat: {name}, {count, plural, one {# file} other {# files}} (com um branch opcional de valor exato =0 {...}), e {gender, select, male {He} other {They}}.

Registrando o serviço

var locale = engine.Locale.init("en"); // default_locale
locale.loadTable(embedded_pt_br_strtab) catch {};
frame.services.register(engine.Locale, &locale);

Troque de idioma em tempo de execução — sem necessidade de recarregar a cena, já que a UI é renderizada novamente a cada quadro:

locale.setLocale("pt-BR");

Tabelas carregadas são mantidas em cache pela sessão e nunca são liberadas ao trocar, então qualquer slice de string já entregue permanece válido (ele só mostra o locale antigo até ser buscado novamente).

Escrevendo traduções

Um arquivo .strings é a fonte da verdade — JSON, um arquivo por locale:

{
  "version": 1,
  "locale": "pt-BR",
  "units": [
    { "id": "Open Scene…", "source": "Open Scene…", "target": "Abrir Cena…", "state": "translated" }
  ]
}

Extrair → traduzir → compilar

# Percorre uma árvore de código-fonte em busca de call sites de
# tr/trc/trn/trKey, escrevendo (ou atualizando, preservando traduções
# existentes) um arquivo .strings:
turian-cli i18n extract <src-dir> pt-BR my-project/i18n/pt-BR.strings.json

# Preencha "target" para cada unidade, depois compile para o formato de runtime:
turian-cli i18n compile my-project/i18n/pt-BR.strings.json my-project/i18n/pt-BR.strtab

extract é seguro para reexecutar a qualquer momento: ids correspondentes mantêm seu target existente; novos call sites são adicionados com state: "new". compile só emite unidades com um target não vazio — uma string não traduzida simplesmente não está na tabela, e recai para a fonte em inglês em tempo de execução, então uma cobertura de tradução parcial nunca é um erro fatal.

Traduzindo o próprio Studio

A UI do próprio Studio usa o mecanismo idêntico, através de studio/services/StudioLocale.zig (um wrapper fino que expõe tr/trc/trn/trArgs apoiado por uma instância Locale). O Studio não é um projeto, então seus catálogos são incorporados via @embedFile em vez de passar pelo pipeline de assets: studio/i18n/<locale>.strings.json (fonte) e studio/i18n/<locale>.strtab (compilado, incorporado).

Para atualizar o catálogo pt-BR do Studio após mexer no código de UI:

turian-cli i18n extract studio pt-BR studio/i18n/pt-BR.strings.json
# traduza quaisquer unidades novas (state: "new") no .strings.json
turian-cli i18n compile studio/i18n/pt-BR.strings.json studio/i18n/pt-BR.strtab

O seletor de idioma fica em Settings → UI → Language; a troca surte efeito imediatamente (o Studio persiste a escolha em editor.ui.language).

Plurais

A categoria de plural é resolvida a partir das regras cardinais CLDR para o idioma ativo — one/few/many/other (e zero/two para idiomas como o árabe) — não condicionais escritas manualmente por idioma. trn/{n, plural, ...} cobrem o caso comum; um branch explícito no estilo =0 {...} tem prioridade sobre a categoria quando presente.

Fora de escopo

Espelhamento de layout RTL, shaping BiDi e tradução automática não fazem parte deste sistema. Um campo direction está reservado nos metadados de locale para suporte futuro a RTL.


← Toda a documentação Editar esta página