diff --git a/data/skills/project_setup.md b/data/skills/project_setup.md index 61b45a0..9c376a1 100644 --- a/data/skills/project_setup.md +++ b/data/skills/project_setup.md @@ -8,10 +8,12 @@ Work in the game repository. Scan files; do not invent content you did not see. ## Task In **one pass**, discover everything needed for translation setup and emit the labeled output blocks below. -Do **not** translate the game. Do **not** rewrite formatting codes, wrap widths, or tool pipeline settings. +Do **not** translate the game or edit its files. Recommend formatting and pipeline settings only in +the designated configuration block. -Default: emit **all four** blocks. -Regenerate mode: if the user asks for only one block (`glossary`, `speakers`, `translation_quirks`, or `game_skill`), emit **only** that block using the same schema and exclusivity rules. +Default: emit every block specified for the selected engine. +Regenerate mode: if the user asks for only one block, emit **only** that block using the same +schema and exclusivity rules. --- @@ -23,6 +25,7 @@ Regenerate mode: if the user asks for only one block (`glossary`, `speakers`, `t | `speakers` | Tool flag ENABLE/SKIP + short evidence | Character bios; quirks; full glossary | | `translation_quirks` | Cross-cutting voice rules (battle-log person, global dialect, item-description style, **unusual** honorific habits) | Per-character register; "always keep -san" (tool base prompt already does); codes/wrap/line counts; speaker flags | | `game_skill` | **Translation Frame** for the API (theme / era / register / naming / optional myth) saved at `skills/game.md` | File inventories; quirks bullets; glossary; per-character register; IDE scaffolding; restating base honorific/formatting policy | +| `rpgmaker_config` (RPG Maker only) | Code-408 Phase 1 decision + measured wrap/font recommendations | Translation prose; glossary; voice rules; speculative settings without evidence | Hard rules: 1. Per-character voice → `glossary` only. @@ -30,6 +33,7 @@ Hard rules: 3. Default honorifics policy is owned by the tool base prompt - only note **unusual** honorific habits in quirks. 4. `game_skill` is the title's Translation Frame for the translation API - keep it compact; do not reprint quirks or glossary. 5. `speakers` is config, not lore. +6. `rpgmaker_config` is measured setup advice, not content to merge into the translation prompt. --- @@ -39,7 +43,7 @@ Map / event files can be huge. Do **not** read them sequentially end-to-end. 1. Read small DB files in full first (richest, always small). 2. For large event/map files: **search/grep**; sample early story maps; stop when patterns stabilize. -3. One scan feeds all four blocks - do not rescan from scratch per block. +3. One scan feeds every output block - do not rescan from scratch per block. @@ -54,6 +58,11 @@ Map / event files can be huge. Do **not** read them sequentially end-to-end. - Prefer code `401` dialogue + nearby `101` speaker/name params; `405` scrolling text when present - Speaker markup evidence: `【Name】`, `[Name]`, `Name:`, `\\n`, `\\k`, colour-wrapped name lines +**Runtime/UI evidence:** +- `js/plugins.js` plus source for enabled plugins in `js/plugins/` +- `js/rpg_windows.js`, `js/rpg_scenes.js`, `js/rpg_managers.js`, or MZ equivalents +- `System.json` resolution/font fields, custom fonts, window skins, and relevant image dimensions + --- attach your game data files / open the game repo before continuing --- ### Speakers analysis (for `speakers` block) @@ -119,6 +128,68 @@ Do **not** include: - Quirks (API): ``skills/quirks.md`` (never ``translation_quirks.txt``) - Optional custom API overlays: other ``skills/*.md`` except those two +### Phase 1 and layout analysis (for `rpgmaker_config` block) + +#### Code 408 + +Code `408` is a continuation of an editor comment. It is normally internal, but plugins can parse +`108`/`408` comment blocks and display their contents to players. + +1. Inventory code-408 values and group them with their preceding code-108 command. +2. Search enabled plugin sources and event-handling code for the discovered comment tags, + prefixes, or parsing APIs. Do not infer runtime visibility from Japanese text alone. +3. Choose `ENABLE` only when evidence shows that code-408 content is rendered or otherwise shown + to players. Show representative plugin + event locators and an affected count. +4. Choose `SKIP` when values are editor notes, disabled-plugin metadata, or have no runtime + consumer. If evidence is inconclusive, choose `SKIP` and state what must be playtested. +5. Tell the user to set the **Translate code 408 plugin/comment text** checkbox in Phase 1 to the + recommended state. This is a user choice; do not edit tool configuration yourself. + +#### Window geometry, wrapping, and fonts + +Calculate recommendations separately for `Dialogue`, `List/Help`, and `Notes`. Use actual game +geometry rather than generic RPG Maker defaults whenever project code is available. + +1. Resolve the game resolution and each relevant window's outer width/height, padding, text inset, + line height, columns, face/portrait reservation, icons, and plugin-added margins. +2. Resolve the actual font face and base size plus runtime changes such as `\\{`, `\\}`, + `\\FS[n]`, custom font codes, bold/outline changes, and plugin-specific scaling. Treat icons and + inline images as pixel width, not zero-width text. +3. Calculate usable pixels: inner window size minus padding, portraits/faces, columns, icons, and + other fixed reservations. Derive visible row capacity from usable height and the largest + applicable line height. +4. Convert usable pixels to DazedTL's character-count wrap setting by measuring representative + English glyphs in the real font when possible. Otherwise use a conservative documented average + glyph width. Never copy a pixel width directly into `width`, `listWidth`, or `noteWidth`. +5. Test representative short, median, long, control-code-heavy, icon-heavy, and font-changed values. + Use the largest effective font when one shared setting must cover several variants. +6. For dialogue, verify the recommendation against the actual message-row limit, commonly four. + If a long message cannot fit without unreadable font reduction or horizontal overflow, flag it + for pagination/manual reflow instead of forcing an unsafe four-line wrap. +7. Recommend one conservative shared width and one readable font size for each category. If the + current font should remain unchanged, say `keep current` and report its measured size. Cite the + files/functions/plugin parameters supporting every recommendation and give a confidence level. + +Emit this additional RPG Maker-only block: + +### Block `rpgmaker_config` + +Label the fence language as `rpgmaker_config`. Inside: + +```text +CODE408 : ENABLE|SKIP - + +Dialogue : width= ; font= ; rows= +List/Help: listWidth= ; font= ; rows= +Notes : noteWidth= ; font= ; rows= + +Evidence: +- + +Exceptions / playtests: +- +``` + diff --git a/data/skills/rpgmaker_translation_qa.md b/data/skills/rpgmaker_translation_qa.md index a76fa4c..d9d24a5 100644 --- a/data/skills/rpgmaker_translation_qa.md +++ b/data/skills/rpgmaker_translation_qa.md @@ -53,7 +53,8 @@ present. - For event code 102, pair each `_original[index]` choice with `parameters[0][index]`. - For scalar event-command `_original` values, resolve the live value by command shape: - 401, 405, 657, 356, 108: visible text in `parameters[0]`. - - 408: internal editor comment in `parameters[0]`; it is not player-facing text. + - 408: comment continuation in `parameters[0]`; classify its runtime visibility from the + preceding 108 block and enabled plugin code before treating it as internal or player-facing. - 101: visible name field in `parameters[4]`, or `parameters[0]` for the variable-name form. - 122: translated inner quoted/backticked string in `parameters[4]`, excluding its script wrapper and trailing semicolon. @@ -72,8 +73,9 @@ Check every resolvable pair for: counts, empty output, or accidental type changes. 2. Japanese or other source-language residue, unchanged source copied as translation, truncation, mojibake, model commentary, refusal text, Markdown fences, or JSON fragments inside player text. - Do not count unchanged code-408 editor comments as player-facing residue or actionable findings. - Report their coverage separately only when the user requests editor-facing localization. + Do not count unchanged code-408 values as player-facing residue when they are editor-only. + When enabled plugin code consumes a 108/408 comment block and displays its content, audit that + content as player-facing text. Report uncertain code-408 groups separately instead of guessing. 3. Lost, added, duplicated, reordered, malformed, or altered runtime tokens. Include RPG Maker control codes such as `\C[n]`, `\N[n]`, `\V[n]`, `\I[n]`, `\{`, `\}`, `\.`, `\|`, `\!`, `\>`, `\<`, and `\^`; custom backslash codes; `__PROTECTED_n__`; printf-style placeholders; diff --git a/gui/config_integration.py b/gui/config_integration.py index ec1beae..eb5ea2a 100644 --- a/gui/config_integration.py +++ b/gui/config_integration.py @@ -269,7 +269,7 @@ class ConfigIntegration: "CODE405": "Show Text (Scrolling) - Longer dialogue", "CODE102": "Show Choices - Player choice options", "CODE101": "Character Names - Turn on when names exist in 101", - "CODE408": "Comments - WARNING: Can inflate costs significantly", + "CODE408": "Comment continuations - enable only for plugin-displayed player text", "CODE122": "Control Variables - Text stored in variables", "CODE355655": "Scripts - Text within script commands", diff --git a/gui/rpgmaker_tab.py b/gui/rpgmaker_tab.py index 28ac2e2..242ecf0 100644 --- a/gui/rpgmaker_tab.py +++ b/gui/rpgmaker_tab.py @@ -323,9 +323,11 @@ class RPGMakerTab(QWidget): # Extended Content in column 2 col2.addWidget(create_section_label("📝 Extended Content")) - self.code408_cb, layout = self._create_checkbox_with_description( - "Comments (408)", "⚠️ Plugin text in comments (costly!)", "Plugin dialogue in comment text." - ) + self.code408_cb, layout = self._create_checkbox_with_description( + "Comment Text (408)", + "⚠️ Enable only when a plugin displays it", + "Continuation lines from 108/408 comment blocks; usually internal, sometimes player-facing.", + ) self.code408_cb.setStyleSheet("QCheckBox { font-size: 11px; color: #ffaa66; }") col2.addLayout(layout) @@ -678,8 +680,11 @@ class RPGMakerTab(QWidget): warnings.append("No Main Codes are enabled. You may not get any translated content.") # Check for high-cost options - if self.code408_cb.isChecked(): - warnings.append("CODE 408 (Comments) is enabled. This can significantly increase translation costs!") + if self.code408_cb.isChecked(): + warnings.append( + "CODE 408 (comment continuation text) is enabled. Confirm an enabled plugin " + "shows it to players; otherwise this can significantly increase translation costs!" + ) # Check for conflicting options if self.brflag_cb.isChecked() and self.fixtextwrap_cb.isChecked(): diff --git a/gui/workflow_tab.py b/gui/workflow_tab.py index 3a315ef..4f16e50 100644 --- a/gui/workflow_tab.py +++ b/gui/workflow_tab.py @@ -99,7 +99,9 @@ PHASE1_CONFIG = { "CODE401": True, "CODE405": True, "CODE102": True, - "CODE408": True, + # Comment continuations are project-dependent: plugins sometimes display + # them, but most games use them only as internal editor notes. + "CODE408": False, # Risky codes OFF "CODE122": False, "CODE355655": False, @@ -488,6 +490,9 @@ _STEP_HELP: dict[int, str] = { "(skills/quirks.md)
" "• game_skill → Game skills → translation tab " "(skills/game.md - Translation Frame, merged into the API prompt)

" + "• rpgmaker_config → apply the code-408 checkbox recommendation in " + "Phase 1 and the measured wrap widths in Step 3; review its font recommendations " + "against the game UI

" "Optional: + on Game skills adds custom skills/*.md " "overlays (also merged into the API prompt - can hurt quality; use sparingly).

" "Use one game folder per translation run so frame/quirks stay in the prompt cache." @@ -495,7 +500,8 @@ _STEP_HELP: dict[int, str] = { 3: ( "Step 3 - TL Phase 1

" "Safe dialogue / database translation.

" - "• Set text-wrap widths if needed (or copy the wrap analysis prompt)
" + "• Apply Project Setup's measured dialogue, list/help, and note wrap widths
" + "• Set the code-408 checkbox from Project Setup's runtime/plugin evidence
" "• Phase 0 - database names/descriptions
" "• Phase 1 - dialogue / choices
" "• Phase 1b - build the code 111 variable-translation cache

" @@ -1546,7 +1552,7 @@ class WorkflowTab(QWidget): copy_btn.setFixedHeight(32) copy_btn.setToolTip( "Clipboard skill for the game repo IDE. Returns glossary, speakers, " - "translation_quirks, and game_skill code blocks." + "translation_quirks, game_skill, and RPG Maker configuration recommendations." ) copy_btn.clicked.connect(self._copy_project_setup_prompt) actions.addWidget(copy_btn) @@ -1737,7 +1743,8 @@ class WorkflowTab(QWidget): wrap_inner.setSpacing(4) wrap_hint = QLabel( - "Adjust if lines overflow or wrap too early in-game, then click Apply to write to .env." + "Use Project Setup's measured rpgmaker_config recommendations, then apply the three " + "wrap widths to .env. Font recommendations describe the game UI and are not applied here." ) wrap_hint.setWordWrap(True) wrap_hint.setStyleSheet("color:#9d9d9d;font-size:13px;") @@ -1820,12 +1827,28 @@ class WorkflowTab(QWidget): p1_inner.setContentsMargins(10, 8, 10, 8) p1_inner.setSpacing(4) p1_desc = QLabel( - "Codes ON: 101 (Name), 401 (Show Text), 405 (continued), 102 (Choices), 408 (extra lines). " - "Speaker lines in the log should look like [Speaker]: Dialogue." + "Codes ON: 101 (Name), 401 (Show Text), 405 (Scrolling Text), 102 (Choices). " + "Code 408 is optional because it may be internal comments or plugin-displayed text. " + "Speaker lines in the log should look like [Speaker]: Dialogue." ) p1_desc.setStyleSheet("color:#9d9d9d;font-size:13px;") p1_desc.setWordWrap(True) p1_inner.addWidget(p1_desc) + self._phase1_code408_cb = QCheckBox( + "Translate code 408 plugin/comment text" + ) + saved_408 = self._setting("phase1_code408", False) + if isinstance(saved_408, str): + saved_408 = saved_408.strip().casefold() in {"1", "true", "yes", "on"} + self._phase1_code408_cb.setChecked(bool(saved_408)) + self._phase1_code408_cb.setToolTip( + "Enable only when Project Setup finds an enabled plugin that displays text from " + "108/408 comment blocks. Leave off for ordinary editor comments." + ) + self._phase1_code408_cb.stateChanged.connect( + lambda state: self._save_setting("phase1_code408", bool(state)) + ) + p1_inner.addWidget(self._phase1_code408_cb) p1_row = QHBoxLayout() p1_row.setSpacing(10) self._run_p1_btn = _make_btn("► Run Phase 1", "#007acc") @@ -3916,7 +3939,11 @@ class WorkflowTab(QWidget): label = "Phase 0 (core DB files)" + (" — batch" if batch else "") file_preset = "db" elif phase == 1: - config = PHASE1_CONFIG + config = dict(PHASE1_CONFIG) + config["CODE408"] = bool( + getattr(self, "_phase1_code408_cb", None) + and self._phase1_code408_cb.isChecked() + ) label = "Phase 1 (safe codes)" + (" — batch" if batch else "") file_preset = "events" elif phase == "1b": diff --git a/tests/test_workflow_prompts.py b/tests/test_workflow_prompts.py index 40b0a99..765044f 100644 --- a/tests/test_workflow_prompts.py +++ b/tests/test_workflow_prompts.py @@ -3,7 +3,7 @@ import unittest from pathlib import Path -from util.skills import load_clipboard_skill +from util.skills import load_clipboard_skill, load_project_setup ROOT = Path(__file__).resolve().parents[1] @@ -41,7 +41,7 @@ class WorkflowTranslationPromptTests(unittest.TestCase): self.assertIn("mechanically check 100%", lowered) self.assertIn("deterministic stratified sample", lowered) self.assertIn("control-code scope and placement", lowered) - self.assertIn("do not count unchanged code-408 editor comments", lowered) + self.assertIn("enabled plugin code consumes a 108/408 comment block", lowered) self.assertIn("do not edit during the first pass", lowered) self.assertIn("stop and wait for approval", lowered) self.assertIn("never modify or remove `_original`", lowered) @@ -52,6 +52,30 @@ class WorkflowTranslationPromptTests(unittest.TestCase): ): self.assertIn(placeholder, prompt) + def test_rpgmaker_project_setup_recommends_408_and_layout_geometry(self): + prompt = load_project_setup("rpgmaker") + lowered = prompt.casefold() + + self.assertIn("code408 : enable|skip", lowered) + self.assertIn("translate code 408 plugin/comment text", lowered) + self.assertIn("dialogue : width=", lowered) + self.assertIn("list/help: listwidth=", lowered) + self.assertIn("notes : notewidth=", lowered) + self.assertIn("face/portrait reservation", lowered) + self.assertIn("applicable line height", lowered) + self.assertIn("pagination/manual reflow", lowered) + + wolf_prompt = load_project_setup("wolf") + self.assertNotIn("code408 : enable|skip", wolf_prompt.casefold()) + + def test_phase1_code408_is_user_controlled(self): + from gui.workflow_tab import PHASE1_CONFIG + + self.assertFalse(PHASE1_CONFIG["CODE408"]) + workflow_source = (ROOT / "gui/workflow_tab.py").read_text(encoding="utf-8") + self.assertIn("Translate code 408 plugin/comment text", workflow_source) + self.assertIn('config["CODE408"] = bool(', workflow_source) + def test_static_clipboard_prompts_live_under_data_skills(self): expected = ( "wrap_config.md",