feat(rpgmaker): add project-aware layout and code 408 setup

This commit is contained in:
DazedAnon 2026-07-27 21:55:14 -05:00
parent ea45b3c626
commit c9bca5b66f
6 changed files with 151 additions and 22 deletions

View file

@ -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.
<!-- engine:rpgmaker -->
@ -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<Name>`, `\\k<Name>`, 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 - <runtime evidence, affected count, and confidence>
Dialogue : width=<DazedTL width> ; font=<px or keep current (measured px)> ; rows=<count>
List/Help: listWidth=<DazedTL width> ; font=<px or keep current (measured px)> ; rows=<count or varies>
Notes : noteWidth=<DazedTL width> ; font=<px or keep current (measured px)> ; rows=<count or varies>
Evidence:
- <resolution/window/font/plugin locator and calculation>
Exceptions / playtests:
- <variant windows, uncertain plugin behavior, or messages requiring pagination>
```
<!-- /engine:rpgmaker -->
<!-- engine:wolf -->

View file

@ -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;

View file

@ -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",

View file

@ -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():

View file

@ -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] = {
"(<code>skills/quirks.md</code>)<br>"
"• <code>game_skill</code> → Game skills → translation tab "
"(<code>skills/game.md</code> - Translation Frame, merged into the API prompt)<br><br>"
"• <code>rpgmaker_config</code> → 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<br><br>"
"Optional: <b>+</b> on Game skills adds custom <code>skills/*.md</code> "
"overlays (also merged into the API prompt - can hurt quality; use sparingly).<br><br>"
"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: (
"<b>Step 3 - TL Phase 1</b><br><br>"
"Safe dialogue / database translation.<br><br>"
"• Set text-wrap widths if needed (or copy the wrap analysis prompt)<br>"
"• Apply Project Setup's measured dialogue, list/help, and note wrap widths<br>"
"• Set the code-408 checkbox from Project Setup's runtime/plugin evidence<br>"
"• Phase 0 - database names/descriptions<br>"
"• Phase 1 - dialogue / choices<br>"
"• Phase 1b - build the code 111 variable-translation cache<br><br>"
@ -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":

View file

@ -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",