--- title: Vernacular emoji: 👀 colorFrom: green colorTo: purple sdk: gradio sdk_version: 6.16.0 python_version: '3.13' app_file: app.py pinned: false license: mit short_description: Translate games. Keep every character's voice --- # Vernacular Character-aware translation pipeline for *Riverstone*, a narrative mystery mobile game. Every string in the language pack is machine-translated locally; character dialogue additionally passes through a tone model that rewrites the draft in the character's voice (using per-character wikis distilled from the game's own chat logs). A Gradio review tool lets a human approve, reject, or correct every line before the final pack is exported. ``` English_JSON ─► TranslateGemma (llama.cpp) ─► tone pass (Ollama gemma4 + character wiki) │ translations/de/ review records │ app.py (Gradio review: approve / reject / edit) │ pipeline/export_pack.py ─► German_JSON/ ``` ## Setup Two local model servers (both required only for the *translation* step, not for reviewing or exporting): ```bash # 1. TranslateGemma 12B via llama.cpp (auto-downloads ~7.3GB on first run). # The official jinja chat template doesn't parse in llama.cpp - the flags # below plus the raw prompt in pipeline/clients.py handle that. llama-server -hf bullerwins/translategemma-12b-it-GGUF:Q4_K_M \ --port 8089 --swa-full --ctx-size 4096 --no-jinja --chat-template gemma # 2. Tone model via Ollama ollama pull gemma4:12b-mlx # or any Gemma chat model; set TONE_MODEL in config.py ``` Python side: `pip install gradio` (plus `pytest` for tests). ## Workflow ```bash python convert.py # English/ -> English_JSON/ (once) python build_character_data.py # index character chat files (once) python build_character_wikis.py # build voice wikis via Ollama (once) python -m pipeline.build_file_context # FILE_MAPPING.md -> file_context.json python -m pipeline.translate_pack # translate + tone pass (resumable) python app.py # review tool at localhost:7860 python -m pipeline.export_pack # -> German_JSON/ ``` `translate_pack` is fully resumable (per-string records + shared translation cache) and supports incremental runs: ```bash python -m pipeline.translate_pack --dry-run # show pending work python -m pipeline.translate_pack --filter Initial/ # one unit at a time python -m pipeline.translate_pack --stage translate # stage 1 only (less RAM) python -m pipeline.translate_pack --stage tone # stage 2 only ``` The full pack is ~15,000 strings; expect an overnight run on a 24GB Apple Silicon machine. Export always produces a complete pack: reviewer-corrected text wins, then the character-toned draft, then the plain machine translation (pending/rejected strings are counted in the export report). ## Changing the target language Edit the three `TARGET_*` values (and `PACK_NAME`) at the top of `config.py` - e.g. `fr` / `French` / `French_JSON` - then rerun `translate_pack`, review, and export. TranslateGemma supports 55 languages. ## Repository map | Path | Purpose | |---|---| | `English/`, `convert.py`, `converter/` | source pack and docx/xlsx → JSON converter | | `English_JSON/` | converted source-of-truth strings | | `build_character_data.py`, `character_data/` | per-character file index | | `build_character_wikis.py`, `character_wikis/` | LLM-built character voice wikis | | `FILE_MAPPING.md`, `pipeline/build_file_context.py` | per-file context shown in review | | `config.py` | target language, paths, model endpoints | | `pipeline/` | rules, clients, translate/tone driver, exporter | | `translations//` | per-file review records (the pipeline's database) | | `app.py` | Gradio review tool (this Space's entrypoint) | | `German_JSON/` | exported language pack |