Move this a bit

This commit is contained in:
DazedAnon 2026-07-03 18:28:54 -05:00
parent f8f5bff8b2
commit 5269a6b27d
2 changed files with 14 additions and 13 deletions

View file

@ -327,7 +327,7 @@ Open the **Workflow** tab and choose **Wolf RPG (WolfDawn)** from the engine sel
| **0 Project** | Select the game folder, **Unpack** the `.wolf` archives into a loose `Data/` folder, then **Extract text** (maps, common events, databases, `Game.dat`, external event text, and the project-wide name glossary). Everything is staged into `files/` for translation, including `names.json` (translated later in Phase 0 only). Extraction also snapshots the pristine (untranslated) binaries into `wolf_json/originals/` so Step 4 can inject idempotently. **Set up git tracking** by copying the `gameupdate/` folder (updater scripts, `patch.sh`/`patch.ps1`, and a `.gitignore` that excludes the original game files) into the game root, so the translation project can be tracked with git and later shipped as a git-based patch players apply themselves. Finally, **Format extracted JSON** (dazedformat) normalises `wolf_json/` and `files/` to the same layout the translator writes back (`json.dump`, indent 4) — run it once and commit it as your baseline so later injects produce clean, line-level git diffs instead of reformatting whole files. |
| **1 Glossary** | Build `vocab.txt` before translating: copy the WOLF-tailored prompt into Cursor/Copilot with the extracted `files/` JSON, let it discover character names, speech registers, and lore terms, then paste the result into the in-tab editor and save (the shared `vocab.txt` is used by every translation batch to keep names and voice consistent). Item/skill/enemy value names (`names.json`) are curated in Step 2 and harvested into `vocab.txt` automatically during Phase 0 — do not list them here. |
| **2 Names** | Curate `names.json` (item/skill/enemy/variable value names). **Translating all of them breaks the game** - many WOLF value names double as logic keys (compared by value, used as variable/file/event names), so by default none are translated. WolfDawn tags each name with its WOLF database **category** (the `note` field), so instead of judging thousands of names you pick which *categories* are safe. Copy the **names-safety prompt** into a repo-aware AI (Cursor/Copilot with `files/` open); it groups names by category, checks how each is used, and returns a JSON list of the safe categories in a code block. Paste that list and click **Apply** to tick the matching rows (or tick them by hand - each row shows the category, its name count, and an example), then **Save** to `data/wolf_safe_notes.json`. Pick the **Translation mode** here (Normal or Batch - Batch uses the Anthropic Batches API, ~50% cheaper, Claude only); the same choice applies to all later phases. Run **Translate safe names (Phase 0)** once categories are saved - this is the first translation step and harvests item/skill/term names into `vocab.txt`. |
| **3 Translate** | Run the `Wolf RPG (WolfDawn)` module in three ordered phases (RPG Maker's DB-first strategy): **Phase 0 · Names → vocab.txt** translates only the safe name categories from Step 2 and harvests them into `vocab.txt` (grouped by bilingual category headers such as `Weapon · 武器`); **Phase 1 · Database text** translates item/skill/state descriptions and system messages from `DataBase.project.json` / `CDataBase.project.json`; **Phase 2 · Dialogue & events** translates maps (`.mps`), `CommonEvent.dat.json`, `Game.dat`, and `Evtext`. Run them in order so later phases benefit from the glossary seeded in Phase 0. **Speaker handling** and **Text wrap width** sit under Phase 2 because they only affect dialogue: speaker attribution is automatic for real nameplates (face window → name → line, reshaped to `[Speaker]: line` for the prompt and restored to WOLF's `Speaker⏎line` on inject); copy the **speaker-format prompt** so a repo-aware AI can recommend whether to enable low-confidence first-line names. Text wrap re-flows translated dialogue to fit WOLF's message box (`wolfWrap` / `wolfWidth` in `.env`; nameplate lines stay separate). Only the `text` fields are filled in; `source` is preserved so injection can verify each line. |
| **3 Translate** | Run the `Wolf RPG (WolfDawn)` module in three ordered phases (RPG Maker's DB-first strategy): **Phase 0 · Names → vocab.txt** translates only the safe name categories from Step 2 and harvests them into `vocab.txt` (grouped by bilingual category headers such as `Weapon · 武器`); **Phase 1 · Database text** translates item/skill/state descriptions and system messages from `DataBase.project.json` / `CDataBase.project.json`; **Phase 2 · Maps / events** translates map scripts (`.mps`), `CommonEvent.dat.json` (common events and UI/objective text), `Game.dat`, and `Evtext`. Run them in order so later phases benefit from the glossary seeded in Phase 0. **Speaker handling** and **Text wrap width** sit under Phase 2 because they apply to dialogue-like lines in maps and events: speaker attribution is automatic for real nameplates (face window → name → line, reshaped to `[Speaker]: line` for the prompt and restored to WOLF's `Speaker⏎line` on inject); copy the **speaker-format prompt** so a repo-aware AI can recommend whether to enable low-confidence first-line names. Text wrap re-flows translated dialogue to fit WOLF's message box (`wolfWrap` / `wolfWidth` in `.env`; nameplate lines stay separate). Only the `text` fields are filled in; `source` is preserved so injection can verify each line. |
| **4 Inject** | Write the translations back into the game's `Data/` binaries **and** refresh the git-tracked `wolf_json/` with the translated JSON, so the game project's git diff shows both the JSON source and the injected binaries. Injection always reads from a **pristine snapshot** of the original binaries (`wolf_json/originals/`, captured during Step 0 extraction and rebuilt from the `.wolf`/`.wolf.bak` archives if missing) and writes the result into the live `Data/` file. This keeps injection **idempotent** - WolfDawn locates each Japanese source string in the original, so re-injecting after fixing a few lines actually updates the binary instead of silently no-op'ing (the old in-place inject broke once a file had already been translated). Toggle `--en-punct` (convert Japanese punctuation to ASCII) and `--allow-code-drift` (relax the inline-code guard) as needed, and use **Check name consistency** to catch names translated differently across files. **Quick inject** lists the files you've translated so far (present in `translated/`) so you can tick just a few, inject them straight into `Data/`, and review the git diff / test in-game - ideal for iterating. **Inject all translations** writes every document, including the safe name values from Phase 0, across `Data/`. |
| **5 Package** | Either run from the loose `Data/` folder (backs up `Data.wolf``Data.wolf.bak`), or **Repack** a fresh `Data.wolf`, inheriting the original archive's encryption. |
| **6 Saves** | *(Optional)* Update existing `.sav` files so old Japanese saves load cleanly in the translated build. Originals are backed up automatically. |

View file

@ -22,9 +22,9 @@ Mirrors the RPGMaker WorkflowTab, driven by the vendored WolfDawn ``wolf`` CLI
name translations into vocab.txt
Phase 1 Database - item/skill/state descriptions and system
messages (DataBase/CDataBase.project)
Phase 2 Dialogue - maps, CommonEvent, Game.dat, Evtext;
speaker handling and text-wrap settings
live under this phase in Step 3
Phase 2 Maps / events - .mps maps, CommonEvent, Game.dat,
Evtext; speaker handling and text-wrap
settings live under this phase in Step 3
Step 4 Inject - inject translations + curated names back into the Data/ binaries
and refresh the git-tracked wolf_json/ with the translated
JSON; quick-inject picks just a few translated files for
@ -96,10 +96,10 @@ WORK_DIR_NAME = "wolf_json"
# Translation phases, keyed by the manifest ``kind`` of each extracted file.
# Mirrors RPGMaker's DB-first strategy: translate names first (they seed the
# glossary), then database descriptions, then the bulk dialogue.
# glossary), then database descriptions, then maps and event scripts.
PHASE_NAMES_KINDS = {"names"}
PHASE_DB_KINDS = {"db"}
PHASE_DIALOGUE_KINDS = {"map", "common", "gamedat", "txt", "txt-dir"}
PHASE_MAPS_EVENTS_KINDS = {"map", "common", "gamedat", "txt", "txt-dir"}
# WolfDawn's inject commands print e.g. "applied 91 translation(s) (0 untranslated,
# 0 drifted); wrote <path>". We parse the counts to distinguish a real inject from a
@ -1089,7 +1089,7 @@ class WolfWorkflowTab(QWidget):
"(WolfDawn) module. Only the 'text' fields are filled in; 'source' is preserved so "
"injection can verify each line. Run the phases in order: Phase 0 translates the safe "
"names and writes them into vocab.txt, so Phases 1 and 2 translate descriptions and "
"dialogue with consistent item / skill / character names (RPGMaker's DB-first strategy)."
"in-engine text with consistent item / skill / character names (RPGMaker's DB-first strategy)."
))
self._add_phase_buttons(layout)
@ -1122,17 +1122,18 @@ class WolfWorkflowTab(QWidget):
layout.addWidget(p1)
layout.addWidget(_make_hr())
layout.addWidget(self._subheading("Phase 2 · Dialogue & events"))
layout.addWidget(self._subheading("Phase 2 · Maps / events"))
layout.addWidget(self._desc(
"The bulk of the script: map events (.mps), CommonEvent, Game.dat and Evtext. Run last "
"so it benefits from the names and terms translated in the earlier phases. Speaker "
"handling and text wrap below apply only to this phase."
"Map scripts (.mps), common events (CommonEvent.dat), Game.dat, and Evtext - story "
"dialogue, UI/objective strings, and other event text. Run last so it benefits from "
"the names and terms translated in the earlier phases. Speaker handling and text wrap "
"below apply to the dialogue-like lines in this phase."
))
self._add_speaker_options(layout)
self._add_wrap_options(layout)
p2 = self._register(_make_btn("▶ Phase 2 · Translate dialogue & events", "#00a86b"))
p2 = self._register(_make_btn("▶ Phase 2 · Translate maps / events", "#00a86b"))
p2.clicked.connect(
lambda: self._navigate_to_translation(kinds=PHASE_DIALOGUE_KINDS, auto_start=True)
lambda: self._navigate_to_translation(kinds=PHASE_MAPS_EVENTS_KINDS, auto_start=True)
)
layout.addWidget(p2)