Small adjustments
This commit is contained in:
parent
0df4dbf3ed
commit
944b03c0c7
2 changed files with 48 additions and 49 deletions
10
README.md
10
README.md
|
|
@ -324,16 +324,16 @@ Open the **Workflow** tab and choose **Wolf RPG (WolfDawn)** from the engine sel
|
|||
|
||||
| Step | Action |
|
||||
|------|--------|
|
||||
| **0 Project** | Select the game root folder (browse or Enter — detection also runs when you reopen the tab). If `wolf_json/` does not exist yet, the tool automatically unpacks `.wolf` archives when needed and extracts text into the game's `wolf_json/` folder (maps, common events, databases, `Game.dat`, Evtext, and `names.json`). A checklist lists every JSON file in `wolf_json/`; tick the ones you want and click **Import** (or leave Step 0 — checked files auto-import into the tool's `files/` folder, matching the RPG Maker workflow). Extraction snapshots pristine binaries into `wolf_json/originals/` for idempotent inject in Step 6. |
|
||||
| **0 Project** | Select the game root folder (browse or Enter — detection also runs when you reopen the tab). If `wolf_json/` does not exist yet, the tool automatically unpacks `.wolf` archives when needed and extracts text into the game's `wolf_json/` folder (maps, common events, databases, `Game.dat`, Evtext, and `names.json`). A checklist lists every JSON file in `wolf_json/`; tick the ones you want and click **Import** (or leave Step 0 — checked files auto-import into the tool's `files/` folder, matching the RPG Maker workflow). Extraction snapshots pristine binaries into `wolf_json/originals/` for idempotent inject in Step 7. |
|
||||
| **1 Pre-process** | Optional: **dazedformat** normalises JSON in `wolf_json/` and `files/` (`json.dump`, indent 4) for clean git diffs; **Copy gameupdate/** installs the updater scripts, patch scripts, and `.gitignore` into the game root for git-based patching. Paths auto-fill from Step 0. |
|
||||
| **2 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. Item/skill/enemy value names (`names.json`) are translated in Step 3 and harvested into `vocab.txt` automatically during Phase 0 — do not list them here. |
|
||||
| **3 Names** | Translate `names.json` (item/skill/enemy/map value names). WolfDawn tags each name with a per-entry **safety** badge (`safe`, `refs`, or `verify`). Phase 0 translates only `safe` entries; `refs` and `verify` names stay Japanese so inject skips them. Review the category breakdown for this game, pick **Translation mode** (Normal or Batch), and run **Translate safe names (Phase 0)**. |
|
||||
| **4 Database** | Review the **discovery summary** to see where this game's text lives (standard RPG sheets vs custom dialogue tables). Database sheets are classified as foundation (items, skills, descriptions — translate first) or narrative (custom event/profile sheets — translate after foundation). Use **Translate foundation DB** then **Translate narrative DB**, or tick specific sheets and run **Translate checked sheets only**. Optional: copy the **DB structure prompt** for an AI audit and import the returned JSON into `wolf_json/db_profile.json`. |
|
||||
| **5 Maps/Events** | Translate map scripts (`.mps`), common events (`CommonEvent.dat`), `Game.dat`, and Evtext. Run after Steps 3–4 so vocab and database terms are consistent. Configure speaker handling for low-confidence nameplate guesses. Batch mode is recommended for large `CommonEvent.dat` files. |
|
||||
| **6 Inject** | Tick translated JSON files from `translated/`, then **Inject selected** or **Inject all**. Each file is reported individually; failures open a dialog with details. Uses pristine originals from `wolf_json/originals/`. |
|
||||
| **7 Fix wrap** | Paste overflowing in-game text to **search** `translated/` JSON and jump to the database sheet and row (sheet names match Step 4 and `names.json` notes, e.g. `├■街の噂(MOB)`). Edit the line, set wrap width, **Wrap this row** or **Wrap all overflowing rows in this sheet**, save, then **Inject this file** (usually `DataBase.project.json`). Per-sheet widths are remembered in `wolf_json/wrap_profile.json`. **Advanced:** **wolf relayout** for event message boxes (maps/CommonEvent only — not bulletin-style DB UI) and **wolf desc-relayout** for standard 説明 description fields. |
|
||||
| **8 Package** | Run from loose `Data/` (backs up `Data.wolf` → `.bak`) or repack `Data.wolf`. |
|
||||
| **9 Saves** | *(Optional)* Update existing `.sav` files for the translated build. |
|
||||
| **6 Precheck** | Dry-run selected JSON for safety-guard skips; fix those lines before writing binaries. |
|
||||
| **7 Inject** | Tick translated JSON files from `translated/`, then **Inject selected** or **Inject all**. Each file is reported individually; failures open a dialog with details. Uses pristine originals from `wolf_json/originals/`. |
|
||||
| **8 Package** | Run from loose `Data/` (backs up `Data.wolf` → `.bak`) or repack `Data.wolf` so you can playtest and see overflow in-game. Optionally rewrite existing `.sav` files so old Japanese saves load in the translated build. |
|
||||
| **9 Fix wrap** | After packaging, paste overflowing in-game text to **search** `translated/` JSON and jump to the database sheet and row (sheet names match Step 4 and `names.json` notes, e.g. `├■街の噂(MOB)`). Edit the line, set wrap width, **Wrap this row** or **Wrap all overflowing rows in this sheet**, save, then **Inject this file** (usually `DataBase.project.json`) and re-package to verify. Per-sheet widths are remembered in `wolf_json/wrap_profile.json`. **Advanced:** **wolf relayout** for event message boxes (maps/CommonEvent only — not bulletin-style DB UI) and **wolf desc-relayout** for standard 説明 description fields. |
|
||||
|
||||
### Recommended order by game layout
|
||||
|
||||
|
|
|
|||
|
|
@ -19,16 +19,17 @@ Mirrors the RPGMaker WorkflowTab, driven by the vendored WolfDawn ``wolf`` CLI
|
|||
lines before writing binaries
|
||||
Step 7 Inject - inject translations into Data/ binaries and refresh
|
||||
wolf_json/; quick-inject picks a few files or all
|
||||
Step 8 Fix wrap - search translated JSON by in-game text; Relayout
|
||||
Step 8 Package - run from a loose Data/ folder or repack Data.wolf;
|
||||
optional save rewrite for existing .sav files
|
||||
Step 9 Fix wrap - search translated JSON by in-game text; Relayout
|
||||
(names-wrap / cell geometry) or Manual (width + font);
|
||||
inject the edited file
|
||||
Step 9 Package - run from a loose Data/ folder, or repack Data.wolf
|
||||
Step 10 Saves - fix baked strings in existing .sav files (optional)
|
||||
inject the edited file, then re-package to verify
|
||||
|
||||
names.json is staged into files/ but is NOT translated in the bulk phases - WolfDawn
|
||||
tags each name safe / refs / verify and Phase 0 translates only safe entries
|
||||
(per-name, not per-category), harvests them into vocab.txt, and Step 7 injects the
|
||||
result. All text wrapping lives in Step 8.
|
||||
result. Package (Step 8) makes the build playable; Fix wrap (Step 9) is the
|
||||
playtest feedback loop.
|
||||
|
||||
The extracted JSON is staged in ``<game_root>/wolf_json/`` (a manifest maps each
|
||||
file back to its base binary), then imported into ``files/`` for the shared
|
||||
|
|
@ -620,9 +621,8 @@ class WolfWorkflowTab(QWidget):
|
|||
("5 Maps/Events", self._build_step5_maps_events),
|
||||
("6 Precheck", self._build_step6_precheck),
|
||||
("7 Inject", self._build_step4_inject),
|
||||
("8 Fix wrap", self._build_step7_relayout),
|
||||
("9 Package", self._build_step5_package),
|
||||
("10 Saves", self._build_step6_saves),
|
||||
("8 Package", self._build_step5_package),
|
||||
("9 Fix wrap", self._build_step7_relayout),
|
||||
]
|
||||
self._step_labels = [label for label, _ in _tab_defs]
|
||||
|
||||
|
|
@ -2599,18 +2599,19 @@ class WolfWorkflowTab(QWidget):
|
|||
|
||||
layout.addWidget(_make_hr())
|
||||
layout.addWidget(self._desc(
|
||||
"English text is often longer than Japanese. Step 8 (Fix wrapping): paste "
|
||||
"overflowing in-game text to find the sheet, wrap, and re-inject."
|
||||
"Next: Step 8 (Package) so you can playtest, then Step 9 (Fix wrapping) "
|
||||
"to paste overflowing in-game text, wrap, and re-inject."
|
||||
))
|
||||
self._refresh_inject_list()
|
||||
|
||||
def _build_step7_relayout(self, layout: QVBoxLayout):
|
||||
"""Search-first fix wrapping: find sheet by in-game text, wrap, re-inject."""
|
||||
layout.addWidget(_make_section_label("Step 8 · Fix wrapping"))
|
||||
layout.addWidget(_make_section_label("Step 9 · Fix wrapping"))
|
||||
layout.addWidget(self._desc(
|
||||
"Paste overflowing in-game text to find it in translated JSON. "
|
||||
"Relayout uses cell width + max lines (names.json → wolf names-wrap). "
|
||||
"Manual uses wrap width + body font; emphasis \\f[N] scales with the body."
|
||||
"After packaging and playtesting, paste overflowing in-game text to find "
|
||||
"it in translated JSON. Relayout uses cell width + max lines "
|
||||
"(names.json → wolf names-wrap). Manual uses wrap width + body font; "
|
||||
"emphasis \\f[N] scales with the body. Re-inject, then re-package to verify."
|
||||
))
|
||||
|
||||
search_row = QHBoxLayout()
|
||||
|
|
@ -3566,9 +3567,8 @@ class WolfWorkflowTab(QWidget):
|
|||
"Maps",
|
||||
"Precheck",
|
||||
"Inject",
|
||||
"Wrap",
|
||||
"Package",
|
||||
"Saves",
|
||||
"Wrap",
|
||||
)
|
||||
name = short_names[idx] if 0 <= idx < len(short_names) else str(idx)
|
||||
mark = "✓" if done else ""
|
||||
|
|
@ -3901,13 +3901,14 @@ class WolfWorkflowTab(QWidget):
|
|||
|
||||
self._run_task(task, on_done=_after)
|
||||
|
||||
# ── Step 5: Package ────────────────────────────────────────────────────────
|
||||
# ── Step 8: Package (+ optional saves) ─────────────────────────────────────
|
||||
|
||||
def _build_step5_package(self, layout: QVBoxLayout):
|
||||
layout.addWidget(_make_section_label("Step 9 · Package the Translated Game"))
|
||||
layout.addWidget(_make_section_label("Step 8 · Package the Translated Game"))
|
||||
layout.addWidget(self._desc(
|
||||
"Choose how the translated build runs. A loose Data/ folder is simplest for "
|
||||
"playtesting; repacking rebuilds a single Data.wolf archive for distribution."
|
||||
"Make the injected build playable so you can spot overflow in-game, then "
|
||||
"fix wrapping in Step 9. A loose Data/ folder is simplest for playtesting; "
|
||||
"repacking rebuilds a single Data.wolf archive for distribution."
|
||||
))
|
||||
|
||||
loose_btn = self._register(_make_btn("Use loose Data/ folder (back up archives)", "#007acc"))
|
||||
|
|
@ -3928,6 +3929,28 @@ class WolfWorkflowTab(QWidget):
|
|||
"archive's encryption where possible (--like the backed-up original)."
|
||||
))
|
||||
|
||||
layout.addWidget(_make_hr())
|
||||
layout.addWidget(self._subheading("Update existing saves (optional)"))
|
||||
layout.addWidget(self._desc(
|
||||
"WOLF .sav files bake in the game title and some strings at save time. Rewrite "
|
||||
"them so old Japanese saves load cleanly in the translated build. Only needed "
|
||||
"for players who already have saves, or to test against one. A timestamped "
|
||||
"backup is made automatically."
|
||||
))
|
||||
|
||||
row = QHBoxLayout()
|
||||
self.save_edit = QLineEdit()
|
||||
self.save_edit.setPlaceholderText("Save folder or .sav file…")
|
||||
row.addWidget(self.save_edit, 1)
|
||||
browse_btn = self._register(_make_btn("Browse…", "#3a3a3a"))
|
||||
browse_btn.clicked.connect(self._browse_saves)
|
||||
row.addWidget(browse_btn)
|
||||
layout.addLayout(row)
|
||||
|
||||
run_btn = self._register(_make_btn("Update saves", "#007acc"))
|
||||
run_btn.clicked.connect(self._update_saves)
|
||||
layout.addWidget(run_btn)
|
||||
|
||||
def _package_loose(self):
|
||||
if not self._require_root():
|
||||
return
|
||||
|
|
@ -3979,30 +4002,6 @@ class WolfWorkflowTab(QWidget):
|
|||
|
||||
self._run_task(task)
|
||||
|
||||
# ── Step 10: Saves ─────────────────────────────────────────────────────────
|
||||
|
||||
def _build_step6_saves(self, layout: QVBoxLayout):
|
||||
layout.addWidget(_make_section_label("Step 10 · Update Existing Saves (optional)"))
|
||||
layout.addWidget(self._desc(
|
||||
"WOLF .sav files bake in the game title and some strings at save time. This rewrites "
|
||||
"them so old Japanese saves load cleanly in the translated build. It is only needed "
|
||||
"for players who already have saves, or to test against one. A timestamped backup is "
|
||||
"made automatically."
|
||||
))
|
||||
|
||||
row = QHBoxLayout()
|
||||
self.save_edit = QLineEdit()
|
||||
self.save_edit.setPlaceholderText("Save folder or .sav file…")
|
||||
row.addWidget(self.save_edit, 1)
|
||||
browse_btn = self._register(_make_btn("Browse…", "#3a3a3a"))
|
||||
browse_btn.clicked.connect(self._browse_saves)
|
||||
row.addWidget(browse_btn)
|
||||
layout.addLayout(row)
|
||||
|
||||
run_btn = self._register(_make_btn("Update saves", "#007acc"))
|
||||
run_btn.clicked.connect(self._update_saves)
|
||||
layout.addWidget(run_btn)
|
||||
|
||||
def _browse_saves(self):
|
||||
start = self.save_edit.text() or (str(Path(self._game_root) / "Save") if self._game_root else str(Path.home()))
|
||||
folder = QFileDialog.getExistingDirectory(self, "Select Save Folder", start)
|
||||
|
|
|
|||
Loading…
Reference in a new issue