Communitygithub.com

DrunkMan9o/agent-skills

Traduza textos de interface de jogos Unity (Mono) ou qualquer aplicação .NET para Chinês Simplificado, com auditoria automática de integridade, consistência, formato e risco estrutural antes da escrita. Use ao localizar um jogo Unity/.NET para Chinês, extraindo strings de UI hardcoded do heap #US, patcheando tokens ldstr, ou auditando uma localização chinesa existente para texto ausente/não traduzido/inconsistente.

O que é agent-skills?

Esta skill implementa um pipeline completo e reutilizável de quatro fases para a localização de jogos Unity (Mono) ou aplicações .NET para Chinês Simplificado. O foco principal não é a tradução em si, mas sim a **avaliação de risco** para determinar quais strings **não podem** ser traduzidas, evitando que o jogo quebre. O pipeline é indicado para projetos onde o texto da interface está codificado diretamente no heap #US do assembly gerenciado (Assembly-CSharp.dll), sem tabelas de localização, e que utilizam fontes dinâmicas incorporadas (TMP ou Legacy Font). As fases incluem: iniciação do projeto, extração de todas as strings ldstr, classificação de risco (P0, P1, P2), aplicação da tradução com suporte a três tipos de tabelas de tradução (global, por site e de enumeração), e uma rigorosa auditoria automática com 31 verificações agrupadas em 6 categorias (CV, CS, FM, RK, IG, RT). A auditoria gera relatórios em JSON, Markdown e HTML, além de uma lista de correções (fixlist.csv), e pode ser usada como gate de CI/CD com níveis de falha configuráveis (P0, P1 ou P2). A skill também lida com desafios específicos de fontes dinâmicas, aplicando apenas substituições in-place de mesmo tamanho para evitar corromper texturas, e oferece uma configuração flexível via arquivo l10n.json. Em resumo, é uma ferramenta de localização profissional que prioriza a segurança e a integridade do jogo, indo além da simples substituição de texto.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/DrunkMan9o/agent-skills/tree/HEAD/skills/unity-zh-l10n

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Pipeline de Localização para Chinês (Unity, com Auto-Auditoria)

Transforma o processo de "extrair → avaliar risco → traduzir → aplicar → auditar" em um pipeline reutilizável de quatro fases. O núcleo não é a tradução em si, mas sim determinar quais strings não podem ser traduzidas — este é o único ponto que pode quebrar o jogo.

Quando usar

Antes de usar, verifique três condições; se qualquer uma não for atendida, não prossiga:

  1. Onde está o texto: Jogos Unity Mono/IL2CPP com texto codificado diretamente no assembly gerenciado (*_Data/Managed/Assembly-CSharp.dll) ou em resources.assets, sem tabela de localização, .po, .csv, etc. Se houver uma tabela de localização existente, use-a; não modifique o assembly.
  2. Arquivo original disponível: A modificação é em um arquivo executável. Você deve ter uma cópia não modificada original como baseline (um backup, ou o arquivo baixado após verificação Steam). Sem baseline, não faça edições in-place.
  3. Chinês é exibível: O projeto usa fontes dinâmicas incorporadas (TMP ou Legacy Font). Fontes estáticas/atlas de caracteres chineses exigem troca de textura; este pipeline lida apenas com fontes dinâmicas.

IL2CPP (sem Assembly-CSharp.dll, apenas GameAssembly.dll) não é suportado; requer Il2CppDumper + recompilação, fora do escopo.

Início Rápido

# 0) Criar esqueleto do projeto (gera l10n.json)
python <skill>/scripts/zhl10n.py init -C /caminho/do/seu/projeto

# 1) Listar todos os locais de ldstr (~10s para 5000 entradas)
python <skill>/scripts/zhl10n.py extract

# 2) Ver a classificação de risco: quais podem ser traduzidos, quais só com direcionamento, quais absolutamente não
python <skill>/scripts/zhl10n.py risk

# 3) Preencher trans_map.json / site_map.json e aplicar a tradução (não modifica o original; saída em out/build/)
python <skill>/scripts/zhl10n.py apply

# 4) Auditoria automática (lê os artefatos em out/build por padrão)
python <skill>/scripts/zhl10n.py audit --fail-on P1

Comando único: zhl10n.py all (extract → apply → audit).

Instalar dependências: pip install dnfile dncil UnityPy fonttools. Para executar apenas audit, UnityPy não é necessário.

Responsabilidades de cada fase

FaseEntradaSaídaEscopo
initCaminho do jogo alvol10n.json, tabelas vaziasApenas gera configuração, não toca nos arquivos do jogo
extractDLL original (+ assets opcionais)out/extract/sites.jsonCada item em sites.json contém str/type/method/token/offsetApenas leitura. Deve ler o original sem patch, caso contrário extrairá strings já traduzidas
risksites.jsonEstatísticas de classificação no consoleApenas avaliação, não modifica nenhuma tabela
applyDLL original + tabela de tradução + subconjunto de fonteout/build/Assembly-CSharp.dllout/build/resources.assetsEscreve novos arquivos; o original não é tocado (--inplace modifica no local, mas primeiro cria um backup .orig). Qualquer tradução que atinja uma regra de bloqueio é rejeitada e um erro é gerado
auditArtefato + tabela de tradução + glossário + logsout/audit/audit.{json,md,html}fixlist.csvApenas leitura. Pode ser executado em qualquer versão do arquivo para comparação entre versões

Três tipos de tabelas de tradução, com responsabilidades distintas:

  • trans_map.json — Tabela global, substitui a string em todas as ocorrências. Coloque apenas strings que "traduzir para chinês não quebra a lógica".
  • site_map.json — Tabela direcionada, a chave é Tipo::Método, modifica apenas o ldstr naquele local. Usada para casos onde "a mesma palavra deve ser traduzida no menu, mas não no sistema de entrada".
  • enum_map.json — Tabela de nomes de enumeração, modifica os nomes dos campos no heap #Strings. Usada para nomes de exibição de enumerações vindas de ToString().

Ordem de avaliação: Direcionada → Global. Se a direcionada for encontrada, a global não é usada.

Auditoria Automática

A auditoria automática é o ponto central deste pipeline. Ela lê o artefato após a aplicação de forma independente, sem confiar na própria tabela de tradução.

Saídas

ArquivoConteúdo
audit.jsonResultado estruturado completo: cada achado contém check/severity/count/items[]/hint
audit.mdResumo legível, ordenado por P0→P2
audit.htmlRelatório em arquivo único, com seções recolhíveis
fixlist.csvLista de itens a corrigir, uma linha por item, pronta para uso como lista de tarefas

Verificações (31 itens, 6 famílias)

CV Integridade — se algo foi esquecido

IDSeveridadeVerificaçãoCritério
CV1P1Texto não traduzidoSite exibível + nenhuma tradução em ambas as tabelas + não liberado por regra de risco
CV1bP2Texto com aparência de UI mas bloqueadoIndica restrição do mecanismo, não esquecimento; requer tradução direcionada e teste real
CV2P1Tradução vazia / placeholderTradução vazia, contendo TODO/待译
CV3P1Texto longo idêntico ao originalSuspeito de não ter sido traduzido
CV4P2Palavras curtas/símbolos idênticos ao originalManter original para caracteres de ícone, nomes de teclas geralmente correto
CV5P2Entradas órfãs na tabela direcionadaDeclaradas mas não encontradas no IL original; método renomeado ou sobrescrito pela tabela global

CS Consistência — se a terminologia corresponde

| ID | Severidade | Verificação | |---|---|---|---| | CS1 | P2 | Mesmo texto original com traduções diferentes na tabela global e direcionada | | CS2 | P1 | Tradução obrigatória do glossário não respeitada | | CS3 | P1 | Tradução atinge palavra proibida do glossário | | CS4 | P2 | Chaves duplicadas (diferindo apenas por maiúsculas/minúsculas/espaços) | | CS5 | P2 | Pontuação chinesa com estilo parcialmente half-width |

FM Formato — se a concatenação quebrará

| ID | Severidade | Verificação | Consequência | |---|---|---|---|---| | FM1 | P1 | Placeholders não preservados | String.Format lança exceção ou números desaparecem | | FM1b | P2 | Placeholder de plural em inglês removido | Prática correta, apenas confirma que não removeu um parâmetro real acidentalmente | | FM2 | P2 | Número de quebras de linha diferente | Layout desalinhado | | FM3 | P1 | Espaços iniciais/finais de unidade/fragmento perdidos | 1000moedas colado | | FM4 | P2 | Outras alterações de espaços iniciais/finais | Geralmente irrelevante entre caracteres chineses | | FM5/FM6 | P2 | Pontuação half-width / espaços consecutivos | Estética | | FM7 | P2 | Expansão excessiva do comprimento da tradução | Geralmente ocorre quando uma descrição é colocada dentro de um rótulo |

RK Risco — se o jogo pode quebrar

| ID | Severidade | Verificação | |---|---|---|---| | RK1 | P0 | String de alto risco incluída na tabela de tradução (caminhos, chaves do mecanismo, regex, nomes de ação de entrada…) | | RK2 | P2 | Tabela global contém identificador único; sugere usar direcionada | | RK3 | P1 | Chave da tabela de tradução contém chinês; segunda aplicação resultará em confusão | | RK4 | P2 | Tradução contém fragmento em inglês residual |

IG Estrutura — se o arquivo em si ainda é válido

| ID | Severidade | Verificação | |---|---|---|---| | IG0/IG1/IG2/IG4 | P0 | Arquivo alvo ausente, anomalia de PE/metadados, #US não analisável, token ldstr inválido, número de linhas de metadados diferente do original | | IG3 | P2 | Site ainda em inglês após patch (whitelist esperada, para verificação) | | IG5/IG6 | P1 | Fonte com falta de glifos / arquivo de fonte não analisável |

RT Runtime — se o jogo reclamou

| ID | Severidade | Verificação | |---|---|---|---| | RT1 | P1 | Stack trace de exceção em Player.log (requer configuração source.logs) |

Formas de Acionamento

Três modos, escolha conforme o cenário:

# 1. Auto-verificação imediatamente após a escrita (mais comum no ciclo de desenvolvimento)
zhl10n.py audit

# 2. Como gate: no CI ou antes do lançamento, sai com código de erro se não atingir o padrão
zhl10n.py audit --fail-on P0      # Falha se houver qualquer bloqueio
zhl10n.py audit --fail-on P1      # Rigor padrão, recomendado para lançamento
zhl10n.py audit --fail-on P2      # Até os avisos precisam ser resolvidos

# 3. Comparação de regressão: quantos problemas a mais que na última versão
zhl10n.py audit --baseline

Ao final de apply, uma auditoria é executada automaticamente e os resultados são exibidos — a fase de aplicação não produzirá um pacote defeituoso sem conhecimento.

Como usar os resultados da auditoria

  1. Olhe primeiro os P0. Nenhum P0 pode ser lançado, ele significa "o jogo pode não iniciar".
  2. Depois, os P1. CV1 é a lista de textos não traduzidos, FM1 é a lista de bugs garantidos, RT1 é a evidência de que já quebrou.
  3. P2 como lista de verificação: CV1b informa quais são restrições do mecanismo e não esquecimento; CV5/CS4 são entradas lixo que podem ser removidas.
  4. fixlist.csv pode ser usado diretamente, linha por linha. Corrija e execute novamente até P0=0 e P1=0.

Configuração (l10n.json)

{
  "project": "NomeDoJogo", "version": "1.0",
  "source": {
    "dll":     "…/Managed/Assembly-CSharp.dll",   // Apenas para localização; extract lê o backup
    "backup":  "…/_Backup/Assembly-CSharp.dll",   // Deve ser o original não modificado
    "assets":  ["…/resources.assets"],
    "logs":    ["…/Player.log"]                    // Opcional, para RT1
  },
  "output": { "dir": "out" },
  "text":   { "map": "trans_map.json", "site_map": "site_map.json", "enum_map": "enum_map.json" },
  "glossary": "glossary.csv",
  "font":   { "subset": "font/zh-subset.ttf", "source": "font/NotoSansSC-Bold.otf", "targets": {} },
  "audit":  { "severity_fail": "P1", "max_expansion_ratio": 2.5, "max_expansion_abs": 40 },
  "risk":   { "extra_patterns": [], "extra_allow": [] }
}

Duas saídas de emergência, pense nelas ao encontrar um erro:

  • risk.extra_patterns — Strings conhecidas que não podem ser traduzidas no projeto (regex). Ex.: ^Levels$
  • risk.extra_allow — Strings específicas já confirmadas que não precisam de tradução. Adicioná-las aqui as remove da lista de não traduzidas

Glossário glossary.csv: três colunas en,zh,forbidden, forbidden separa sinônimos com |. CS2/CS3 dependem dele; se ausente, essas verificações são ignoradas.

Regras de Decisão: Quais Strings Absolutamente Não Podem Ser Traduzidas

Versão resumida: Strings usadas como "chave" no código, se traduzidas, não serão encontradas.

CategoriaExemploO que acontece se traduzir
Caminho de recurso"Levels", "UI/Fonts/X"Tabela de fases vazia → NRE ao restaurar save → tela de carregamento trava
Nome de ação de entrada/campoMove/Up/ButtonAtalhos de teclado quebram
Campo de savelegacySkillPointCreditSave não carrega
Nome de enumeraçãoDeposit (usado em Enum.Parse além de ToString())Falha na análise
Padrão regex([0-9.]+)% more coinsSubstituição de texto de dica falha, retorna ao inglês
Nome de objeto/recursonew GameObject("Display glass")Geralmente não quebra, mas polui o nome do recurso
String de formato{0:N0} / {1:N0}Exceção String.Format

Mesma forma, significado diferente: Pause no menu de configurações é texto de botão (deve ser traduzido), em GameInput é nome de ação (não pode ser traduzido). É impossível distinguir apenas pela forma do texto; só é possível pelo "tipo e método em que aparece". É o que _code_shape() no risk.py faz:

  • Métodos que criam objetos (.ctor/Build/Initialize/Create/Ensure…) → literais são nomes, não traduzir
  • Métodos que desenham UI (Draw/OnGUI/Format/get_…) → são textos, traduzir
  • Métodos de comparação (Is/Has/Matches/Find…) → são chaves para correspondência, não traduzir

Após adicionar uma nova regra, deve-se validar com teste negativo: insira deliberadamente na tabela de tradução "Levels": "Níveis" e confirme que a auditoria reporta P0.

Problemas com Fontes

Fontes dinâmicas incorporadas só permitem substituição in-place de mesmo tamanho. Reescrever resources.assets completamente altera o offset m_StreamData do Texture2D, corrompendo todas as texturas.

Processo: a fase font cria um subconjunto com base no "conjunto real de caracteres chineses usados", converte para TTF (Unity tem suporte instável para CFF/OTF) e insere em m_FontData. Se o número de glifos for maior que o suportado, reduza o tamanho da fonte ou comprima o peso; não pode exceder o tamanho original.

Fontes como Bangers-Regular, com apenas dezenas de KB, não comportam chinês — redirecione o caminho da fonte para outra fonte chinesa (configurado em font.targets no l10n.json), é mais confiável do que forçar a substituição.

Lista de Verificação Pré-Lançamento

  • audit --fail-on P1 passa
  • Iniciar o jogo e percorrer cada tela: menu principal / configurações / lista de saves / HUD do jogo / pop-ups / erros
  • Player.log sem novas exceções (RT1 = 0)
  • Localização do arquivo original de backup incluída nas notas de lançamento (é a única forma de restaurar)
  • Registrar MD5 do artefato nas notas de versão

Método de localização de defeitos: Primeiro troque apenas o DLL original, mantenha o resto; se funcionar, o problema está no patch do assembly. Depois troque apenas o DLL, mantenha o resto; se reproduzir, confirme. Bisseção é mais rápido que ler código.

Documentos de Referência

  • references/flow.md — Implementação detalhada e estruturas de dados de cada fase
  • references/audit-spec.md — Definição completa das 31 verificações, níveis, guia de correção
  • references/risk-rules.md — Tabela de regras de risco e os acidentes reais por trás delas
  • assets/l10n.example.json / assets/glossary.example.csv — Modelos de configuração

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Habilidades Relacionadas