EnginesGuiasFAQPatreonDiscordBaixar
Entrar
RuneTranslate · traduza jogos japoneses de ponta a ponta
EnginesGuiasCompararTexto em imagensEditor de savesModo CheatFAQBaixarPatreonDiscordYouTubePrivacidadeTermosContato
Todos os posts
unity · textmeshpro · fonts · troubleshooting

Por que o texto traduzido vira quadrados

18 de ago. de 2026·9 min de leitura

Você traduziu o jogo, a exportação terminou limpa e a caixa de diálogo está cheia de □□□. Isso quase nunca é um problema de tradução — é um problema de fonte, e tem uma correção diferente das duas falhas com que costumam confundi-lo. Veja como distinguir um glifo ausente de um caractere descartado e de mojibake, e como cada caso se resolve no Unity, no TextMeshPro, no Ren'Py e nas ferramentas em tempo de execução.

A exportação terminou, o jogo abriu, e cada linha de diálogo é uma fileira de retângulos vazios idênticos. Não há nada de errado com a tradução. O texto no arquivo é exatamente o que o provedor devolveu, e se você abrir esse arquivo em um editor de texto ele está legível. O que falhou foi a última etapa da cadeia: a fonte que o jogo entrega ao renderizador não tem desenho para aqueles caracteres.

O que é, de fato, um quadrado de tofu

Uma fonte é uma tabela que mapeia um ponto de código Unicode para uma forma. Quando o renderizador recebe um ponto de código que a fonte não contém, ele substitui pelo glifo ausente da fonte — normalmente um retângulo vazio ou cortado, formalmente chamado de .notdef e conhecido em todo lugar como quadrado de tofu. Um quadrado equivale a um caractere que a fonte não conseguiu desenhar. É esse o mecanismo inteiro.

Duas consequências decorrem disso, e ambas ajudam no diagnóstico. Primeira: a contagem de quadrados bate com a contagem de caracteres — cinco caracteres tailandeses produzem cinco quadrados, não uma sequência embaralhada mais curta. Segunda: a string está intacta na memória — o jogo ainda consegue medi-la, compará-la, salvá-la e recarregá-la. Só faltam os pixels. É por isso que um menu traduzido pode estar completamente ilegível e ainda assim navegar corretamente.

Três sintomas, três problemas diferentes

Boa parte da confusão em torno de "minha tradução quebrou" é gente aplicando a correção de um desses casos em outro. Leia o formato do dano antes de mudar qualquer coisa.

  • Quadrados □□□ — os caracteres estão corretos, a fonte não consegue desenhá-los. Corrija a fonte.
  • ???? — os caracteres sumiram. Alguma coisa recodificou a string para um conjunto de caracteres mais estreito e substituiu tudo o que não conseguia representar. Nenhuma fonte traz isso de volta. Corrija a codificação, ou escolha um idioma de destino que o formato consiga guardar.
  • Latim embaralhado como テキスト, ou テキスト exibido como テキスト — mojibake. Os bytes estão certos, o decodificador está errado: um texto escrito em uma codificação está sendo lido em outra. Corrija qual codificação está sendo lida.

Um separador rápido: quadrados e mojibake mantêm a contagem de bytes mais ou menos proporcional ao original, mas o mojibake produz lixo visível e variado, enquanto o tofu produz retângulos idênticos e uniformes. Uniforme quer dizer "fonte". Variado quer dizer "codificação".

Quadrados: um glifo ausente

O jogo veio com uma fonte que cobre só o que ele precisava. Nada no fluxo está quebrado — você pediu um ponto de código que o artista nunca incluiu. A correção é sempre dar ao renderizador uma fonte que tenha o glifo, seja substituindo a fonte, seja adicionando um fallback que o renderizador consulta quando a fonte principal não tem nada.

Pontos de interrogação: os caracteres foram descartados

Quando uma string precisa ser gravada de volta em um formato que armazena texto em uma codificação legada de um ou dois bytes, todo caractere fora dessa codificação precisa virar alguma coisa. Por convenção, essa coisa é ?. Shift-JIS e cp932 guardam japonês, ASCII e pouquíssimo mais; um campo ASCII estrito não guarda nada de grego, cirílico, tailandês ou CJK. Isso é uma propriedade do formato do arquivo, não da fonte, e acontece no momento da exportação — quando o jogo lê o arquivo, a informação já se perdeu.

O RuneTranslate tem um motor em que esse limite é real e ele é declarado em vez de escondido: o YU-RIS recodifica suas strings como cp932, o que serve bem ao inglês e a outras saídas latinas, mas entrega o tailandês como ?. Destinos fora do cp932 nesse motor precisam de um font hack que ainda não existe.

Latim embaralhado: mojibake

Texto japonês escrito como Shift-JIS e lido como UTF-8 (ou o contrário) produz longas sequências de letras latinas acentuadas e caracteres de desenho de caixa. Isso aparece quando uma ferramenta grava um arquivo na codificação errada, ou quando o carregador do próprio jogo pressupõe uma codificação que a sua exportação não usou. A correção é gravar o arquivo na codificação que o motor espera — nunca trocar a fonte, o que não muda nada.

Por que CJK e tailandês sofrem mais

O latim precisa de cerca de cem glifos. O japonês precisa de vários milhares, o chinês de mais ainda. Arquivos de fonte são grandes, e os jogos embarcam o menor que cobre o próprio script, então a cobertura que você herda depende inteiramente do idioma para o qual o jogo foi feito.

  • Um jogo feito para o japonês normalmente traz kana, kanji comuns e ASCII. Traduza para russo, grego, tailandês ou coreano e todo caractere fora do ASCII cai fora.
  • Um jogo feito para o inglês normalmente traz só latim — então japonês, chinês, coreano, tailandês, grego e cirílico falham todos de uma vez.
  • O tailandês é o pior caso na prática: está fora de toda fonte comum de jogo, e ainda precisa de marcas combinantes de vogal e de tom posicionadas acima e abaixo do caractere base, então uma fonte que tecnicamente tem os pontos de código ainda pode renderizá-lo mal.
  • O latim não é automaticamente seguro. Polonês, tcheco, húngaro, turco, vietnamita e romeno usam caracteres do Latin-Extended que uma fonte feita para inglês ou japonês costuma omitir. O RuneTranslate embarca uma fonte mais ampla exatamente para esses destinos no Ren'Py, porque "latim está tranquilo" acabou se revelando falso.

Unity e TextMeshPro em específico

O Unity tem dois sistemas de texto e eles falham de formas diferentes. O Text do uGUI legado usa um objeto Font. O TextMeshPro — que a maioria dos jogos modernos usa — não usa arquivo de fonte nenhum em tempo de execução. Ele usa um asset de fonte TMP: um atlas de textura com imagens de glifos pré-renderizadas, mais uma tabela que mapeia pontos de código para posições nesse atlas.

É por isso que um asset de fonte TMP tem um conjunto de caracteres fixo. Quando o desenvolvedor o gerou, escolheu uma faixa de caracteres — normalmente só o idioma que ia lançar — e o TMP assou exatamente aqueles glifos no atlas. Um asset de fonte estático nunca consegue renderizar nada fora desse conjunto, não importa o que você mande nele. Um asset de fonte dinâmico guarda uma referência ao arquivo de fonte de origem e consegue rasterizar novos glifos sob demanda, que é o único modo capaz de crescer para cobrir um idioma que o desenvolvedor nunca considerou.

A saída de emergência do TMP é a lista de fallback. Cada asset de fonte tem uma lista m_fallbackFontAssets, e as TMP Settings têm uma lista global de fallback; quando o asset principal não tem glifo para um ponto de código, o TMP percorre essas listas procurando um que tenha. Esse é o lugar certo para intervir, porque deixa a fonte do próprio jogo no comando de tudo o que ela já desenha — a interface mantém a aparência pretendida e só os caracteres de que ela não dá conta vêm de outro lugar.

Corrigindo com uma ferramenta em tempo de execução

O XUnity.AutoTranslator faz hook no jogo enquanto ele roda e consegue trocar fontes pelo arquivo de configuração. As opções relevantes, em [Behaviour]:

  • OverrideFont — substitui a fonte usada pelos componentes Text da UI legada do Unity. Recebe o nome de uma fonte que o jogo ou o sistema operacional consiga resolver.
  • OverrideFontTextMeshPro — substitui o asset de fonte TMP por completo. Aponte para um arquivo AssetBundle de fonte TMP, ou para o nome de um asset que o jogo já tenha.
  • FallbackFontTextMeshPro — o mais seguro dos dois: adiciona uma fonte que o TMP consulta só para os glifos que faltam no asset do próprio jogo, deixando a tipografia original no lugar em todo o resto.
  • tmp_font_assetbundles — a coleção mantida pela comunidade de AssetBundles de fonte TMP prontos, para a qual OverrideFontTextMeshPro e FallbackFontTextMeshPro costumam apontar. Eles são compilados por versão do Unity, e um bundle compilado para uma versão diferente da do jogo não carrega — bater a versão é o passo que as pessoas esquecem.

Uma ferramenta em tempo de execução é por máquina e por configuração: ela conserta o jogo no PC em que está instalada, e qualquer outra pessoa que rode aquela build precisa da mesma configuração. O RuneTranslate consegue ler e gravar o próprio arquivo _AutoGeneratedTranslations.txt do plugin, então um projeto que já o usa não é um beco sem saída — veja a comparação para saber onde cada abordagem se encaixa.

Corrigindo em nível de arquivo

O RuneTranslate segue o caminho do fallback direto nos dados do jogo. Na exportação para Unity, ele localiza as TMP Settings do jogo, um asset de fonte que possa servir de modelo e uma Font, e então constrói um novo asset de fonte TMP em modo Dynamic em torno de uma fonte embutida que cobre o script de destino e o acrescenta à lista de fallback. As entradas de fallback existentes ficam intactas e a fonte do próprio jogo continua sendo a principal — então um jogo japonês traduzido para tailandês mantém o estilo original em tudo que é latino e puxa os glifos tailandeses do asset injetado.

Duas observações honestas sobre isso. Ele precisa que as TMP Settings, um modelo utilizável de asset de fonte e uma Font existam no mesmo contêiner de assets do jogo; um jogo que organize isso de outro jeito pode ficar de fora. E quando a injeção é pulada, a exportação avisa nos alertas em vez de terminar no verde — uma exportação que sai em quadrados não pode parecer idêntica a uma que funciona. Se você vir esse aviso, o caminho da ferramenta em tempo de execução acima é o plano B.

O Ren'Py chega ao mesmo resultado por outro mecanismo, porque o Ren'Py não tem TMP: o RuneTranslate pode embutir uma fonte CJK ou não latina na build exportada e registrá-la pelo próprio config.font_replacement_map do Ren'Py, para que o motor a substitua sempre que a fonte do jogo ficar devendo.

Checklist de trabalho

  1. Olhe o dano. Retângulos uniformes, caracteres ? ou letras embaralhadas — decida qual dos três você tem antes de mexer em qualquer coisa.
  2. Se for ?, abra o arquivo exportado. Se as interrogações estão no arquivo, os caracteres foram perdidos na gravação e nenhuma fonte vai ajudar; verifique se a codificação de strings do motor consegue guardar o seu idioma de destino.
  3. Se forem letras embaralhadas, verifique a codificação que o motor espera para aquele arquivo, e não a fonte.
  4. Se forem quadrados, confirme que o conteúdo do arquivo está correto — quase sempre está — e trate como um trabalho de fonte.
  5. No Unity, prefira adicionar um fallback a substituir a fonte do jogo. A substituição muda a aparência de todas as strings, inclusive as que já estavam sendo renderizadas bem.
  6. Se usar um AssetBundle de fonte TMP, combine-o com a versão do Unity do jogo.
  7. Reexporte e confira os caracteres específicos que estavam falhando, não só a primeira linha de diálogo. Latin-Extended e as marcas do tailandês costumam passar por uma conferência rápida e falhar em outro lugar.

Para onde ir depois

Para o fluxo completo do Unity — que texto o Unity realmente expõe e o que fica fora de alcance — leia como traduzir jogos Unity e a página do motor Unity. Texto pintado na arte, e não em dados, é um problema à parte com uma ferramenta à parte: veja tradução de imagens. E o FAQ cobre o resto das surpresas comuns de primeira execução.

O RuneTranslate é gratuito de usar, com todos os motores e todos os provedores desbloqueados, incluindo três que não precisam de chave de API nenhuma. Ele lê os próprios arquivos do jogo e exporta uma build traduzida jogável que fica com você. Baixe o app ou veja os motores suportados.

Leitura relacionada
01

XUnity.AutoTranslator não está traduzindo

unityxunity-autotranslatortroubleshooting18 de ago. de 2026 · 9 min
Ler →
02

Como traduzir um jogo Unity para o português

unitytutorialengine9 de jun. de 2026 · 6 min
Ler →
03

Como traduzir jogos RPG Maker

rpg-makerhow-toenginecontrol-codes18 de ago. de 2026 · 10 min
Ler →

Pronto para experimentar o RuneTranslate?

O plano gratuito libera todos os motores + todos os provedores de tradução. O plano Supporter ($3/mo) libera velocidade total.

Baixar para Windows