188 lines
13 KiB
Markdown
188 lines
13 KiB
Markdown
# Enshrouded — русская озвучка записок
|
||
|
||
Русская озвучка всех **525 озвученных записок и мини-историй** (Ministory) Enshrouded. Голос — клон
|
||
английского диктора игры, текст — официальный русский перевод игры. Мод ставится через EML
|
||
(Enshrouded Mod Loader) и не трогает оригинальные файлы игры.
|
||
|
||
| | |
|
||
|---|---|
|
||
| Версия | 0.4.0 (игра 1.0, октябрь 2026) |
|
||
| Объём | 525 записок, 425 минут, 467 МБ |
|
||
| Синтез | Qwen3-TTS 1.7B, дообучение [`ru-stress-cf`](https://huggingface.co/siriusfreak/qwen3-tts-12hz-1.7b-ru-stress-cf) с ударениями, ICL-клон диктора |
|
||
| Контроль | автоматический, без прослушивания: ударения 99,9 % по всем кускам; WER 2,4 % и MOS 3,45 на выборке из 60 записок |
|
||
|
||
> Озвучка — синтез, а не запись актёра. Голос повторяет тембр английского диктора, тексты принадлежат
|
||
> Keen Games. Это любительский мод: не продавайте его и не выдавайте за официальный.
|
||
|
||
## Что в репозитории
|
||
|
||
```
|
||
mod/ru_voice_notes/ готовый мод: data/*.qoa (Git LFS), src/*.lua, mod.json
|
||
install.py установка и удаление мода (только стандартная библиотека Python)
|
||
run.py конвейер генерации по шагам (каждый шаг в своём окружении)
|
||
ensvoice/ ключевые скрипты конвейера
|
||
extract.py тексты и английский звук из файлов игры
|
||
refs.py референсы диктора, его тембр и паузы
|
||
segments.py текст для голоса: лексикон, ударения, нарезка по абзацам
|
||
lexicon.py ← главное место для правок: имена, ударения, сокращения
|
||
render.py, tts/ синтез (локальный GPU или сервер media-node)
|
||
qc.py, pick.py автоматическая проверка дублей и отбор лучшего
|
||
assemble.py, mod.py склейка записок, QOA, сборка мода
|
||
refbench.py сравнение референсов голоса по метрикам
|
||
env/ зависимости двух окружений
|
||
docs/GENERATION.md как устроена генерация и как её улучшать
|
||
config.example.toml пример настроек
|
||
```
|
||
|
||
В репозиторий не попадают данные, извлечённые из игры (`work/`), окружения (`.venv-*`), модели,
|
||
бинарники EML (`tools/`) и `config.toml`: всё это перечислено в `.gitignore`.
|
||
|
||
---
|
||
|
||
## Установка мода (для игрока)
|
||
|
||
Нужны Windows, Steam-версия Enshrouded, Python 3.11+, Git с Git LFS.
|
||
|
||
```bash
|
||
git clone https://git.shahovalov.ru/mikhail/enshrouded-ru-voice.git
|
||
cd enshrouded-ru-voice
|
||
git lfs pull
|
||
python install.py
|
||
```
|
||
|
||
В конце должна появиться строка `[ru_voice] replaced 525 notes, 0 failed`, затем `INSTALLED`.
|
||
Игру запускать как обычно, из Steam. Язык озвучки в игре оставить **английским**: мод подменяет
|
||
английскую дорожку записок, своего русского слота у озвучки в игре нет.
|
||
|
||
Удаление: `python install.py --uninstall` (или «Проверить целостность файлов» в Steam).
|
||
|
||
---
|
||
|
||
## Инструкция для агента: установка
|
||
|
||
Агент выполняет шаги по порядку. После каждого шага есть проверка: если она не прошла, агент не идёт
|
||
дальше и разбирает причину по таблице ниже. Команды даны для Git Bash или PowerShell 7 на Windows.
|
||
|
||
### A. Только поставить мод (без генерации)
|
||
|
||
1. **Проверить окружение.**
|
||
```bash
|
||
python --version
|
||
git lfs version
|
||
```
|
||
Ожидаемо: Python 3.11 или новее, git-lfs 3.x. Если Python нет, поставить `winget install Python.Python.3.12`;
|
||
если нет Git LFS, поставить `winget install GitHub.GitLFS`, затем выполнить `git lfs install`.
|
||
2. **Клонировать и скачать звук.**
|
||
```bash
|
||
git clone https://git.shahovalov.ru/mikhail/enshrouded-ru-voice.git
|
||
cd enshrouded-ru-voice
|
||
git lfs pull
|
||
```
|
||
Проверка: в `mod/ru_voice_notes/data` лежат 525 файлов `.qoa`, все больше 1 КБ, вместе около 467 МБ.
|
||
Файлы меньше 1 КБ — это LFS-указатели: снова выполнить `git lfs pull`.
|
||
3. **Спросить пользователя**, закрыта ли игра и можно ли записать в папку игры `dbghelp.dll` и
|
||
`mods/ru_voice_notes`. Без согласия дальше не идти.
|
||
4. **Установить.**
|
||
```bash
|
||
python install.py
|
||
```
|
||
Если игра стоит не в библиотеке Steam, добавить `--game "<папка с enshrouded.kfc>"`.
|
||
Ожидаемо: строки `[ru_voice] replaced 525 notes, 0 failed` и `INSTALLED`.
|
||
5. Сообщить пользователю: игру запускать из Steam, язык озвучки оставить английским, записки читаются
|
||
по-русски. Откат: `python install.py --uninstall`.
|
||
|
||
### B. Поставить конвейер генерации (чтобы дорабатывать)
|
||
|
||
Требования: NVIDIA GPU с 12 ГБ VRAM и больше (проверено на RTX 5080 16 ГБ и Tesla V100 32 ГБ),
|
||
32 ГБ RAM, около 35 ГБ на диске (модели около 10 ГБ, рабочая папка около 15 ГБ), свежий драйвер NVIDIA
|
||
(CUDA 12.8), [uv](https://docs.astral.sh/uv/). Сначала выполнить раздел A до шага 2 включительно.
|
||
|
||
1. **Проверить GPU и uv.**
|
||
```bash
|
||
nvidia-smi
|
||
uv --version
|
||
```
|
||
Если `uv` нет: `winget install astral-sh.uv`.
|
||
2. **Создать два окружения.** Их два, потому что `qwen-tts` требует transformers 4.x, а модели контроля
|
||
качества требуют 5.x.
|
||
```bash
|
||
uv venv -p 3.12 .venv-tts
|
||
uv pip install -p .venv-tts/Scripts/python.exe torch torchaudio --index-url https://download.pytorch.org/whl/cu128
|
||
uv pip install -p .venv-tts/Scripts/python.exe -r env/tts.txt
|
||
uv venv -p 3.12 .venv-qc
|
||
uv pip install -p .venv-qc/Scripts/python.exe torch torchaudio --index-url https://download.pytorch.org/whl/cu128
|
||
uv pip install -p .venv-qc/Scripts/python.exe -r env/qc.txt
|
||
```
|
||
На Linux путь к интерпретатору — `.venv-tts/bin/python`.
|
||
3. **Настроить.** Скопировать `config.example.toml` в `config.toml` и заполнить:
|
||
- `paths.game` — папка игры (её нашёл `install.py`, путь напечатан в строке `game:`);
|
||
- `paths.work` — папка на **том же диске, что и игра** (см. «Ловушки»), с 15 ГБ свободного места;
|
||
- `tts.dtype` — `bfloat16` для RTX 30xx и новее, `float16` для RTX 20xx, GTX 16xx, V100.
|
||
4. **Инструменты EML.** Если `install.py` ещё не запускался, скачать их через него, ответив пользователю
|
||
по шагу A.3, либо взять `kfc-parser.exe` и `emm.exe` вручную из релиза
|
||
[Brabb3l/kfc-parser v0.2.0](https://github.com/Brabb3l/kfc-parser/releases/tag/v0.2.0) в `tools/`.
|
||
5. **Проверить установку.**
|
||
```bash
|
||
python run.py check
|
||
```
|
||
Ожидаемо: две строки с версией torch, `cuda True` и именем GPU, затем `CHECK_OK`.
|
||
6. **Пробный прогон на трёх записках**, около 15 минут. Модели (около 10 ГБ) скачиваются с Hugging Face
|
||
при первом запуске.
|
||
```bash
|
||
export ENSVOICE_NOTES=n016,n238,n363 # PowerShell: $env:ENSVOICE_NOTES="n016,n238,n363"
|
||
python run.py extract
|
||
python run.py refs
|
||
python run.py segments
|
||
python run.py render
|
||
python run.py qc
|
||
python run.py pick
|
||
python run.py assemble
|
||
```
|
||
Ожидаемо: после `extract` — `notes 525 EN minutes 488`; после `refs` —
|
||
`configured reference ... found`; после `pick` — `'segments': 16, 'picked': 16`;
|
||
после `assemble` — `ASSEMBLED 3 notes`. Готовые WAV для проверки лежат в `<work>/wav48/`.
|
||
**Не запускать** `python run.py mod` с переменной `ENSVOICE_NOTES`: собранный мод заменит в
|
||
`mod/ru_voice_notes` все 525 записок тремя.
|
||
7. Снять переменную (`unset ENSVOICE_NOTES`) и сообщить пользователю, что конвейер работает.
|
||
Полный прогон (`python run.py all`) на RTX 5080 занимает около суток (см. docs/GENERATION.md), его
|
||
запускают по просьбе пользователя.
|
||
|
||
### Ловушки и ошибки
|
||
|
||
| Симптом | Причина и что делать |
|
||
|---|---|
|
||
| `extract`: `EN minutes` не 488, а около 425 | В игре применён мод: EML пропатчил `enshrouded.kfc`, и прочиталась русская озвучка. `extract` сам берёт исходный индекс из `enshrouded.kfc.bak` через жёсткие ссылки — для этого `paths.work` должен быть на диске игры. Иначе: `tools/emm.exe restore -g "<игра>"` и повторить `extract`. |
|
||
| `install.py`: `close Enshrouded first`, `os error 32` | Игра запущена: закрыть её. |
|
||
| `.qoa` по 130 байт, `LFS pointers` | Не скачан LFS: `git lfs install`, затем `git lfs pull`. |
|
||
| `render`: `CUDA out of memory` | Уменьшить `tts.batch` до 4. Больше 8 не ставить: на RTX 5080 16 ГБ батч 16 упирается в видеопамять и работает в разы медленнее. |
|
||
| `bf16 is not supported` / NaN | GPU старше Ampere: `tts.dtype = "float16"`. |
|
||
| `qc` убит, `Killed`, MemoryError | Каждый процесс QC берёт 8–13 ГБ RAM: запускать меньше шардов. |
|
||
| `refs`: `configured reference ... NOT FOUND` | Другая версия игры: выбрать id из `<work>/refs.json` через `refbench`. |
|
||
| `extract`: `expected 525 voiced notes` | Обновление игры изменило записки: конвейер работает, но мод из репозитория может не подойти — собрать свой. |
|
||
|
||
---
|
||
|
||
## Как дорабатывать и делиться
|
||
|
||
Порядок работы и все приёмы описаны в [docs/GENERATION.md](docs/GENERATION.md). Коротко: правки идут в
|
||
`lexicon.py` или конфиг, затем по цепочке `segments → render → qc → pick → assemble → mod` (заново
|
||
считаются только изменённые куски) и `python install.py`.
|
||
|
||
Делиться результатом: ветка с изменениями кода, лексикона и обновлённым `mod/ru_voice_notes` плюс
|
||
pull request. В описании PR привести числа из `<work>/pick_report.json` до и после (`wer`, `stress`,
|
||
`mos`, `weak`): по ним видно, что правка улучшила озвучку, а не просто изменила её. Без доступа на запись
|
||
в этот Gitea — форк или patch-файл с `git format-patch`.
|
||
|
||
## Благодарности
|
||
|
||
[Brabb3l/kfc-parser](https://github.com/Brabb3l/kfc-parser) (распаковка и EML) ·
|
||
[Qwen3-TTS](https://github.com/QwenLM/Qwen3-TTS) ·
|
||
[siriusfreak/qwen3-tts-12hz-1.7b-ru-stress-cf](https://huggingface.co/siriusfreak/qwen3-tts-12hz-1.7b-ru-stress-cf) (ударения и meter2) ·
|
||
[RUAccent](https://github.com/Den4ikAI/ruaccent) ·
|
||
[GigaAM](https://github.com/salute-developers/GigaAM) ·
|
||
[UTMOSv2](https://github.com/sarulab-speech/UTMOSv2) ·
|
||
[WavLM](https://huggingface.co/microsoft/wavlm-base-plus-sv)
|
||
|
||
Код — MIT (см. `LICENSE`). Озвучка в `mod/` — производная от материалов игры и не покрывается
|
||
лицензией кода.
|