Communitygithub.com

DrunkMan9o/agent-skills

Lokalisierung von UI-Texten in Unity (Mono)-Spielen oder beliebigen .NET-Programmen in vereinfachtes Chinesisch mit integrierter Prüfung auf Vollständigkeit, Konsistenz, Format und strukturelle Risiken vor dem Schreiben.

Was ist agent-skills?

Dieses Skill-Set bietet eine vollständige Pipeline zur Lokalisierung von Unity (Mono)-Spielen oder .NET-Anwendungen, bei denen UI-Texte fest im #US-String-Heap der Assembly-CSharp.dll codiert sind, ohne lokalisierte Ressourcen wie PO-Dateien oder CSV-Tabellen. Es extrahiert alle ldstr-Token, bewertet Risiken (welche Strings nicht übersetzt werden dürfen), wendet Übersetzungen an und führt eine detaillierte Selbstprüfung durch, um fehlende Übersetzungen, Inkonsistenzen, Formatfehler oder strukturelle Risiken zu erkennen. Die Pipeline ist in vier Phasen unterteilt: Initialisierung, Extraktion, Anwendung und Audit. Ein besonderer Fokus liegt auf der Risikobewertung, um zu verhindern, dass Schlüsselstrings (wie Ressourcenpfade, Eingabeaktionen oder Formatstrings) übersetzt werden, was das Spiel zum Absturz bringen könnte. Die Selbstprüfung umfasst 31 Prüfpunkte in sechs Kategorien, die von P0 (kritisch) bis P2 (Hinweis) reichen und sicherstellen, dass das lokalisierte Spiel stabil bleibt. Die Pipeline unterstützt Plattformen wie Claude Code, Cursor und Codex und wird über ein zentrales Konfigurationsfenster (l10n.json) und mehrere Übersetzungstabellen gesteuert.

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

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Unity-Lokalisierungspipeline (mit Selbstprüfung)

Eine wiederverwendbare Vier-Phasen-Pipeline für: Extraktion → Risikobewertung → Übersetzung → Anwendung → Selbstprüfung. Der Kern liegt nicht in der Übersetzung selbst, sondern darin, zuerst zu entscheiden, welche Strings nicht übersetzt werden dürfen – das ist der einzige Punkt, an dem das Spiel kaputtgehen kann.

Wann man sie verwendet

Überprüfe vor der Nutzung drei Bedingungen:

  1. Wo ist der Text?: Unity-Spiel mit Mono/IL2CPP, Text ist hartcodiert in der verwalteten Assembly (*_Data/Managed/Assembly-CSharp.dll) oder resources.assets, ohne Localization-Tabelle, .po- oder .csv-Ressourcen. Bei vorhandener Lokalisierungstabelle direkt damit arbeiten, die Assembly nicht ändern.
  2. Zugriff auf Originaldatei: Änderungen betreffen ausführbare Dateien, daher muss eine unveränderte Originaldatei als Basis (Backup, neu heruntergeladen nach Steam-Validierung) vorhanden sein. Ohne Basis keine direkten Änderungen.
  3. Chinesisch wird angezeigt: Das Projekt verwendet eine eingebettete dynamische Schriftart (TMP oder Legacy Font). Bei statischen Schriftarten/Bitmap-Schriften müsste die Textur ersetzt werden – diese Pipeline verarbeitet nur dynamische Schriftarten.

IL2CPP (keine Assembly-CSharp.dll, nur GameAssembly.dll) wird nicht unterstützt – hierfür ist Il2CppDumper + Neukompilierung nötig.

Schnellstart

# 0) Projektgerüst erstellen (l10n.json generieren)
python <skill>/scripts/zhl10n.py init -C dein_projektverzeichnis

# 1) Alle ldstr-Stellen erfassen (ca. 10 s / 5000 Einträge)
python <skill>/scripts/zhl10n.py extract

# 2) Risikostufen anzeigen: welche übersetzbar, welche nur gezielt, welche absolut nicht
python <skill>/scripts/zhl10n.py risk

# 3) trans_map.json / site_map.json füllen, dann anwenden (Original unverändert, Ausgabe in out/build/)
python <skill>/scripts/zhl10n.py apply

# 4) Selbstprüfung (liest out/build-Ergebnisse)
python <skill>/scripts/zhl10n.py audit --fail-on P1

Kompletter Durchlauf: zhl10n.py all (extract → apply → audit).

Abhängigkeiten installieren: pip install dnfile dncil UnityPy fonttools. Nur audit erfordert kein UnityPy.

Verantwortlichkeiten der Phasen

PhaseEinstiegEingabeAusgabeVerantwortungsbereich
initzhl10n.py initZiel-Spiel-Pfadl10n.json, leere TabellenNur Konfiguration erzeugen, Spiel-Dateien nicht anfassen
extractextract.pyOriginale DLL (+ optionale assets)out/extract/sites.jsonJeder Eintrag mit str/type/method/token/offsetNur lesen. Muss ungepatchtes Original lesen, sonst werden bereits lokalisierte Strings extrahiert
riskrisk.pysites.jsonKonsolenstatistik der StufenNur bewerten, keine Tabellen ändern
applyapply.pyOriginale DLL + Übersetzungstabellen + Schriftarten-Subsetout/build/Assembly-CSharp.dllout/build/resources.assetsNeue Dateien schreiben, Original unverändert (--inplace erstellt .orig-Backup). Übersetzungen, die auf Blocklist treffen, werden abgelehnt und gemeldet
auditaudit.pyProdukte + Übersetzungstabellen + Glossar + Logsout/audit/audit.{json,md,html}fixlist.csvNur lesen. Kann auf beliebigen Versionen laufen, für Vorher-Nachher-Vergleich

Drei Übersetzungstabellen, unterschiedliche Aufgaben:

  • trans_map.json – Globale Tabelle: Ersetzt Strings an allen Vorkommen. Nur Strings, die „als Chinesisch übersetzt die Logik nicht beschädigen“.
  • site_map.json – Gezielte Tabelle: Schlüssel ist Typ::Methode, ändert nur das ldstr an dieser Stelle. Für Fälle wie „gleiches Wort im Menü übersetzbar, im Eingabesystem nicht“.
  • enum_map.json – Enumerationsnamen-Tabelle: Ändert Feldnamen im #Strings-Heap. Für von ToString() zurückgegebene Anzeigenamen von Enums.

Prüfreihenfolge: Gezielt → Global. Wenn gezielt zutrifft, wird global nicht mehr angewendet.

Selbstprüfung (Audit)

Die Selbstprüfung ist der Schwerpunkt dieser Pipeline. Sie liest nach dem Schreiben die Produkte unabhängig und vertraut nicht den Aussagen der Übersetzungstabellen.

Ausgabe

DateiInhalt
audit.jsonVollständige strukturierte Ergebnisse: jeder Fund mit check/severity/count/items[]/hint
audit.mdMenschlich lesbare Zusammenfassung, sortiert nach P0→P2
audit.htmlEinklappbarer Einzeldatei-Report
fixlist.csvListe der zu behebenden Probleme, eine Zeile pro Problem, direkt als Aufgabenliste nutzbar

Prüfpunkte (31 Punkte, 6 Familien)

CV Vollständigkeit – Fehlende Übersetzungen

NummerStufePrüfungEntscheidungsgrundlage
CV1P1Unübersetzter TextAnzeigbarer String + keine Übersetzung in beiden Tabellen + nicht von Risikoregeln ausgenommen
CV1bP2Text, der wie UI-Text aussieht, blockiert wurdeErklärung: Engine-Einschränkung, kein fehlender Übersetzungsfehler; gezielte Übersetzung + Test nötig
CV2P1Leere / Platzhalter-ÜbersetzungÜbersetzung leer oder enthält TODO/待译
CV3P1Übersetzung von langen Strings identisch mit OriginalVerdacht: Gar nicht übersetzt
CV4P2Übersetzung von kurzen Wörtern/Symbolen identisch mit OriginalIcons, Tastennamen belassen meist richtig
CV5P2Tote Einträge in gezielfter TabelleDeklariert, aber im Original-IL nicht gefunden; Methoden umbenannt oder von globaler Tabelle überdeckt

CS Konsistenz – Terminologie stimmt nicht überein

| Nummer | Stufe | Prüfung | |---|---|---|---| | CS1 | P2 | Gleicher Originaltext in globaler und gezielter Tabelle unterschiedlich übersetzt | | CS2 | P1 | Pflichtübersetzung aus Glossar nicht eingehalten | | CS3 | P1 | Übersetzung enthält verbotene Glossarbegriffe | | CS4 | P2 | Doppelte Schlüssel (nur Groß-/Kleinschreibung / Leerzeichen unterschiedlich) | | CS5 | P2 | Chinesische Satzzeichen teilweise halbbreit |

FM Format – Verkettungen könnten brechen

NummerStufePrüfungKonsequenz
FM1P1Platzhalter nicht konserviertString.Format löst Ausnahme aus oder Zahlen verschwinden
FM1bP2Entfernung englischer Plural-PlatzhalterKorrektes Vorgehen, nur Hinweis, dass nicht versehentlich echte Parameter gelöscht wurden
FM2P2Unterschiedliche ZeilenumbrücheLayout verschoben
FM3P1Einheit/Teilstück fehlende führende/nachfolgende Leerzeichen1000coins verklebt
FM4P2Andere Leerzeichen am Anfang/Ende geändertZwischen Chinesisch meist egal
FM5/FM6P2Halbbreite Satzzeichen / aufeinanderfolgende LeerzeichenÄsthetik
FM7P2Übersetzung zu stark verlängertMeist wird Erklärung ins Label geschrieben

RK Risiko – Könnte das Spiel zum Absturz bringen

| Nummer | Stufe | Prüfung | |---|---|---|---| | RK1 | P0 | Hochrisiko-Strings in Übersetzungstabelle aufgenommen (Pfade, Engine-Keys, Regex, Eingabeaktionen…) | | RK2 | P2 | Globale Tabelle enthält Einzelidentifikator, besser gezielt | | RK3 | P1 | Übersetzungstabellen-Key enthält Chinesisch, zweite Anwendung fehlerhaft | | RK4 | P2 | Übersetzung enthält englische Fragmente |

IG Struktur – Ist die Datei selbst noch gültig

| Nummer | Stufe | Prüfung | |---|---|---|---| | IG0/IG1/IG2/IG4 | P0 | Ziel-Datei fehlt, PE/Metadaten anomal, #US nicht lesbar, ldstr-Token ungültig, Metadaten-Zeilenanzahl abweichend | | IG3 | P2 | Nach Patch noch englische Stellen (erwartete Whitelist, zum Abgleich) | | IG5/IG6 | P1 | Schriftart fehlende Zeichen / Schriftart-Datei nicht lesbar |

RT Laufzeit – Spiel hat selbst etwas gestanden

| Nummer | Stufe | Prüfung | |---|---|---|---| | RT1 | P1 | Ausnahme-Stack in Player.log (benötigt source.logs Konfiguration) |

Auslösemethoden

# 1. Sofort nach dem Schreiben (im Entwicklungszyklus am häufigsten)
zhl10n.py audit

# 2. Als Gate: CI oder vor Veröffentlichung, nicht bestanden führt zu Exit-Code != 0
zhl10n.py audit --fail-on P0      # Bestehen nur ohne blockierende Fehler
zhl10n.py audit --fail-on P1      # Standard-Strenge, für Veröffentlichung empfohlen
zhl10n.py audit --fail-on P2      # Auch Hinweise müssen beseitigt werden

# 3. Regression: Diese Änderung vs. letzte – welche neuen Probleme
zhl10n.py audit --baseline

apply führt nach dem Schreiben automatisch audit aus und gibt die Ergebnisse aus – so wird kein defektes Paket unwissentlich produziert.

Wie man Audit-Ergebnisse nutzt

  1. Zuerst P0 ansehen. Kein P0 darf veröffentlicht werden, es bedeutet „Spiel könnte nicht starten“.
  2. Dann P1 ansehen. CV1 sind fehlende Übersetzungen, FM1 sind Absturzgarantien, RT1 ist Beweis für bereits aufgetretene Abstürze.
  3. P2 als Checkliste nutzen: CV1b zeigt Engine-Einschränkungen, keine fehlenden Übersetzungen; CV5/CS4 sind direkt löschbare Müll-Einträge.
  4. fixlist.csv direkt Zeile für Zeile abarbeiten, dann erneut laufen lassen, bis P0=0 und P1=0.

Konfiguration (l10n.json)

{
  "project": "Spielname", "version": "1.0",
  "source": {
    "dll":     "…/Managed/Assembly-CSharp.dll",   // Nur zur Orientierung, extract liest backup
    "backup":  "…/_Backup/Assembly-CSharp.dll",   // Muss unverändertes Original sein
    "assets":  ["…/resources.assets"],
    "logs":    ["…/Player.log"]                    // Optional, für 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": [] }
}

Zwei Ausweichmöglichkeiten bei Fehlern:

  • risk.extra_patterns – Projektbekannte, nicht übersetzbare Strings (Regex). Beispiel: ^Levels$
  • risk.extra_allow – Bestätigte, nicht zu übersetzende Strings. Aufnahme gilt nicht als fehlende Übersetzung

Glossar glossary.csv: en,zh,forbidden drei Spalten, forbidden mit | getrennte Synonyme. CS2/CS3 benötigen es, sonst werden diese Prüfungen übersprungen.

Entscheidungsregeln: Welche Strings dürfen auf keinen Fall übersetzt werden

Kurzversion: Strings, die im Code als „Schlüssel“ verwendet werden, sind nach Übersetzung unauffindbar.

KategorieBeispielFolge bei Übersetzung
Ressourcenpfade"Levels", "UI/Fonts/X"Leveltabelle leer → NRE bei Speicherwiederherstellung → Hängenbleiben im Ladebildschirm
Eingabeaktionen/FeldnamenMove/Up/ButtonTastenbelegungen ungültig
SpeicherfelderlegacySkillPointCreditSpeicherstand nicht lesbar
EnumerationsnamenDeposit (neben ToString() gibt es Enum.Parse)Parse-Fehler
Regex-Muster([0-9.]+)% more coinsTextüberarbeitung fehlgeschlagen, zurück zu Englisch
Objekt-/Ressourcennamennew GameObject("Display glass")Normalerweise kein Absturz, aber verunreinigt Ressourcennamen
Format-Strings{0:N0} / {1:N0}String.Format-Ausnahme

Gleiche Form, unterschiedliche Bedeutung: Pause im Einstellungsmenü ist Schaltflächentext (übersetzbar), in GameInput ist es Aktionsname (nicht übersetzbar). Nur durch den Kontext „in welchem Typ, welcher Methode“ unterscheidbar. Das macht risk.py's _code_shape():

  • Methoden, die Objekte erstellen (.ctor/Build/Initialize/Create/Ensure…): Literale → Namen, nicht übersetzen
  • Methoden, die UI zeichnen (Draw/OnGUI/Format/get_…): Texte, übersetzen
  • Methoden, die vergleichen (Is/Has/Matches/Find…): Werte zum Abgleich, nicht übersetzen

Nach Hinzufügen neuer Regeln muss mit Negativtest validiert werden: Absichtlich "Levels": "等级" in die Übersetzungstabelle einfügen, Audit muss P0 melden.

Schriftart-Problematik

Eingebettete dynamische Schriftarten können nur gleichlang in situ ersetzt werden. Ein vollständiges Neuschreiben von resources.assets verändert die Texture2D m_StreamData-Offsets, Texturen werden komplett verschoben.

Vorgehen: In der font-Phase ein Subset nach „tatsächlich benötigtem Zeichensatz“ erstellen, in TTF konvertieren (Unity unterstützt CFF/OTF instabil), dann in m_FontData einsetzen. Wenn die Anzahl der Glyphen nicht ausreicht, Schriftgröße reduzieren oder Gewicht verringern, darf die Originalgröße nicht überschreiten.

Bangers-Regular (nur wenige KB) kann kein Chinesisch aufnehmen – besser den Schriftpfad auf eine andere chinesische Schriftart umleiten (in l10n.json unter font.targets konfigurieren), das ist zuverlässiger als gewaltsames Einfügen.

Checkliste vor Auslieferung

[ ] audit --fail-on P1 bestanden
[ ] Spiel tatsächlich starten, jeden Bildschirm durchgehen: Hauptmenü / Einstellungen / Speicherliste / In-Game-HUD / Dialoge / Fehler
[ ] Player.log keine neuen Ausnahmen (RT1 = 0)
[ ] Backup-Originalpfad in Release Notes dokumentieren (nur so kann man wiederherstellen)
[ ] MD5 der Produkte notieren, in Versionshinweise aufnehmen

Fehlersuche bei Fehlern: Zuerst nur die Original-DLL zurücklegen, andere Dateien behalten – wenn das normal läuft, liegt das Problem im Assembly-Patch. Dann nur die DLL patchen, andere Original. Binäre Suche ist schneller als Code-Lesen.

Referenzdokumente

  • references/flow.md – Detaillierte Implementierung und Datenstrukturen jeder Phase
  • references/audit-spec.md – Vollständige Definition der 31 Prüfungen, Stufen, Reparaturanleitungen
  • references/risk-rules.md – Risikoregel-Tabelle und reale Vorfälle dahinter
  • assets/l10n.example.json / assets/glossary.example.csv – Konfigurationsvorlagen

Individual skills in this repo

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

Verwandte Skills