Rework prompts a bit

This commit is contained in:
dazedanon 2026-03-31 12:12:33 -05:00
parent c16d61498a
commit b2baa5e463

View file

@ -779,10 +779,25 @@ class WorkflowTab(QWidget):
# ── Copilot prompt templates ────────────────────────────────────────────
_SPEAKER_PROMPT = (
"# RPGMaker MV/MZ Speaker Format Detection Prompt\n"
"You are an expert RPGMaker MV/MZ analyst helping configure a Japanese game translation tool.\n"
"\n"
"Look at a sample of the game's event files (Map*.json, CommonEvents.json, "
"Troops.json) and determine which speaker name format the game uses.\n"
"<task>\n"
"Examine the game's event files (Map*.json, CommonEvents.json, Troops.json) and determine "
"which speaker name format(s) the game uses. Output flag recommendations based on what you find.\n"
"</task>\n"
"\n"
"<context>\n"
"Code 101 opens the text window. Code 401 is a dialogue line. Multiple 401s in a row form "
"one message box. The translation tool needs to know how character names appear in the event "
"data so it can extract and translate them correctly.\n"
"</context>\n"
"\n"
"--- attach your game files here before continuing ---\n"
"\n"
"<always_on_formats>\n"
"The following formats are detected and translated automatically — no flag is needed. "
"If the game uses any of these, do NOT enable a flag for lines matching that exact pattern. "
"However, continue scanning to check whether other speakers use a flag-requiring pattern.\n"
"\n"
"## How dialogue commands work\n"
"\n"
@ -796,176 +811,145 @@ class WorkflowTab(QWidget):
"However, **DO NOT STOP** — continue checking whether other speakers in the same game "
"use a different format that requires a flag.\n"
"\n"
" • 101 param[4] name — { \"code\": 101, \"parameters\": [\"\", 0, 2, 2, \"るな\"] }\n"
"\\\\n<Name> or \\\\k<Name> escape code anywhere in a 401 line\n"
" • 【Name】 alone on a line, or 【Name】dialogue on the same line\n"
" • [Name] alone on a line (square brackets), or [Name]dialogue on the same line\n"
"\\\\c[N]Name\\\\c[0] color-wrapped name on its own 401 line\n"
" • Name line ending with a full-width colon\n"
"\n"
"---\n"
" 101 param[4] name { \"code\": 101, \"parameters\": [\"\", 0, 2, 2, \"るな\"] }\n"
" \\\\n<Name> or \\\\k<Name> escape code anywhere inside a 401 line\n"
" 【Name】 alone on a line, or 【Name】dialogue on the same line\n"
" [Name] alone on a line, or [Name]dialogue on the same line\n"
" \\\\c[N]Name\\\\c[0] color-wrapped name on its own 401 line\n"
" Name line ending with a full-width colon\n"
"</always_on_formats>\n"
"\n"
"## Flags that MAY need to be enabled\n"
"<flags>\n"
"Only enable these when at least some speakers do NOT use an always-on format.\n"
"\n"
"Only set these if at least SOME speakers do NOT already use an always-on format above.\n"
"<flag name=\"INLINE401SPEAKERS\">\n"
"The speaker name is embedded at the start of a 401 line directly before 「, "
"with no intervening markup or brackets.\n"
"<example>\n"
"{ \"code\": 401, \"parameters\": [\"エレナ「今日は晴れですね。\"] }\n"
"</example>\n"
"Enable if the game has dialogue lines matching this pattern.\n"
"</flag>\n"
"\n"
"### INLINE401SPEAKERS\n"
"The speaker name is embedded at the start of the 401 text directly before 「 "
"with NO intervening markup or brackets.\n"
"Example:\n"
" { \"code\": 401, \"parameters\": [\"エレナ「今日は晴れですね。\"] }\n"
"→ ENABLE only if the game has dialogue lines matching this pattern.\n"
"<flag name=\"FIRSTLINESPEAKERS\">\n"
"The very first 401 in a message group is a short standalone name (under 40 chars), "
"and the following 401 starts with 「 \" ( * [. This commonly appears for NPCs even "
"in games where the protagonist uses an always-on format. The 101 command for these "
"lines typically has an empty face image (parameters[0] == \"\").\n"
"<example>\n"
"{ \"code\": 101, \"parameters\": [\"\", 0, 0, 2] }\n"
"{ \"code\": 401, \"parameters\": [\"衛兵さん\"] } ← plain name, no color or brackets\n"
"{ \"code\": 401, \"parameters\": [\"「……起きたか」\"] }\n"
"</example>\n"
"Enable if ANY speakers in the game use this pattern, even if others use an always-on format.\n"
"</flag>\n"
"\n"
"### FIRSTLINESPEAKERS\n"
"The very first 401 in a message group is a short standalone name (<40 chars), "
"and the following 401 starts with 「 \" ( * [.\n"
"This pattern commonly appears for NPCs/side characters even in games where the "
"protagonist uses an always-on format (e.g. \\\\c[N]Name\\\\c[0]).\n"
"The 101 command for these NPC lines typically has an empty face image (parameters[0] == \"\").\n"
"Example:\n"
" { \"code\": 101, \"parameters\": [\"\", 0, 0, 2] }\n"
" { \"code\": 401, \"parameters\": [\"衛兵さん\"] } ← plain name, no color or brackets\n"
" { \"code\": 401, \"parameters\": [\"「……起きたか」\"] }\n"
"→ ENABLE if ANY speakers in the game use this pattern, even if other speakers "
"(e.g. the protagonist) use an always-on format.\n"
"<flag name=\"FACENAME101\" priority=\"last_resort\">\n"
"Enable ONLY when: (a) the game has no always-on format, AND (b) neither INLINE401SPEAKERS "
"nor FIRSTLINESPEAKERS applies, AND (c) the 101 code has a face image filename in "
"parameters[0] while parameters[4] is empty.\n"
"<example>\n"
"{ \"code\": 101, \"parameters\": [\"face_alice\", 0, 0, 2, \"\"] }\n"
"</example>\n"
"If you recommend this, you MUST list every unique face filename found in parameters[0] "
"of code 101 across all attached files.\n"
"</flag>\n"
"</flags>\n"
"\n"
"### FACENAME101 ⚠ LAST RESORT ONLY\n"
"Enable this ONLY when:\n"
" (a) the game has NO always-on speaker format, AND\n"
" (b) neither INLINE401SPEAKERS nor FIRSTLINESPEAKERS applies, AND\n"
" (c) the 101 code has a face image filename in parameters[0] while parameters[4] is empty.\n"
"Example:\n"
" { \"code\": 101, \"parameters\": [\"face_alice\", 0, 0, 2, \"\"] }\n"
"→ ENABLE only as a last resort. If you recommend this, you MUST also list every "
"unique face filename found in parameters[0] of code 101 across the attached files, "
"so the user knows which names to map.\n"
"<instructions>\n"
"Follow these steps in order:\n"
"\n"
"---\n"
"1. Scan ALL 101→401 blocks across the sample files.\n"
" (a) List every always-on pattern found — these need no flag.\n"
" (b) List every flag-requiring pattern found separately.\n"
" A game may use both simultaneously (e.g. protagonist via \\\\c[N]Name\\\\c[0], "
"NPCs via plain standalone name lines). Do not stop after finding one pattern.\n"
"\n"
"## Decision process\n"
"2. For each flag-requiring pattern from step 1:\n"
" - INLINE401SPEAKERS → ENABLE if name「 inline pattern exists\n"
" - FIRSTLINESPEAKERS → ENABLE if plain standalone name line exists\n"
" Both may be enabled together if both patterns exist.\n"
"\n"
"Step 1 — Scan ALL 101→401 blocks across the sample files.\n"
" Identify every distinct speaker pattern present:\n"
" (a) Always-on patterns (list them — they need no flag)\n"
" (b) Flag-requiring patterns (list them separately)\n"
" A game may have BOTH simultaneously (e.g. protagonist via \\\\c[N]Name\\\\c[0],\n"
" NPCs via plain FIRSTLINESPEAKERS). Do not stop after finding one pattern.\n"
"3. Only if steps 12 found no flag-requiring patterns AND no always-on format "
"→ consider FACENAME101.\n"
"</instructions>\n"
"\n"
"Step 2 — For each flag-requiring pattern found in Step 1:\n"
" • INLINE401SPEAKERS → ENABLE if name「 inline pattern exists\n"
" • FIRSTLINESPEAKERS → ENABLE if plain standalone name line exists\n"
" These can both be enabled together if both patterns exist.\n"
"<output_format>\n"
"Provide exactly four sections:\n"
"\n"
"Step 3 — Only if no flag-requiring patterns were found in Steps 12, AND\n"
" no always-on format was found, → consider FACENAME101.\n"
"\n"
"---\n"
"\n"
"Please examine a sample of the event commands in the attached files and output:\n"
"\n"
" 1. Which pattern(s) were detected for each speaker type (protagonist, NPCs, signs/narration)\n"
" 2. For each flag — ENABLE or SKIP, with a one-line reason:\n"
" INLINE401SPEAKERS : ENABLE / SKIP — <reason>\n"
" FIRSTLINESPEAKERS : ENABLE / SKIP — <reason>\n"
" FACENAME101 : ENABLE / SKIP — <reason>\n"
" 3. A short concrete example from the files confirming each detected pattern\n"
" 4. If FACENAME101 is ENABLE: list every unique face filename found in "
"code 101 parameters[0] so the user can build the name mapping\n"
"1. Patterns detected — one entry per speaker type (protagonist, NPCs, signs/narration)\n"
"2. Flag decisions:\n"
" INLINE401SPEAKERS : ENABLE / SKIP — <one-line reason>\n"
" FIRSTLINESPEAKERS : ENABLE / SKIP — <one-line reason>\n"
" FACENAME101 : ENABLE / SKIP — <one-line reason>\n"
"3. A short concrete example from the actual files for each detected pattern\n"
"4. (Only if FACENAME101 is ENABLE) Every unique face filename from parameters[0] of code 101\n"
"</output_format>\n"
)
_PROMPT_GLOSSARY = (
"You are helping me build a complete translation glossary for a Japanese RPGMaker game.\n"
"You are an expert Japanese RPGMaker game analyst building a translation glossary.\n"
"\n"
"⚠️ FILE SIZE WARNING: Map files and CommonEvents.json can be extremely large "
"(hundreds of thousands of lines). Do NOT attempt to read them in full — you will "
"hit context limits and miss content. Instead, use this strategy:\n"
"<task>\n"
"Extract named characters and lore-specific worldbuilding terms from this game's data files. "
"Produce a structured glossary in the exact format specified below. It will be loaded directly "
"into a translation tool, so strict format compliance is required.\n"
"</task>\n"
"\n"
" 1. Read the small structured DB files IN FULL first — these are the richest "
"source of names and are always small:\n"
" Actors.json, Classes.json, Troops.json, Skills.json, Items.json, "
"Armors.json, Weapons.json, States.json, System.json\n"
"--- attach your game data files here before continuing ---\n"
"\n"
" 2. For large files (CommonEvents.json, Map*.json), do NOT read sequentially. "
"Instead, SEARCH (grep) for:\n"
" - Named character patterns: 【, \\\\n<, \\\\k< at the start of dialogue lines\n"
" - Unique proper nouns: capitalised katakana clusters or kanji compound nouns "
"in \"message\" or \"parameters\" fields\n"
" Scan Map001.json through Map010.json at most — early maps have the most "
"story-critical dialogue.\n"
"<file_strategy>\n"
"Map files and CommonEvents.json can be extremely large. Do NOT read them sequentially — "
"you will hit context limits. Use this strategy:\n"
"\n"
" 3. Stop adding entries once you stop finding new names/terms — do not pad.\n"
"1. Read these small DB files IN FULL first — richest source of names, always small:\n"
" Actors.json, Classes.json, Troops.json, Skills.json, Items.json,\n"
" Armors.json, Weapons.json, States.json, System.json\n"
"\n"
"Produce TWO sections of output.\n"
"2. For large files (CommonEvents.json, Map*.json), SEARCH (grep) for named character "
"patterns only:\n"
" - 【, \\\\n<, \\\\k< patterns in parameters fields\n"
" - Capitalised katakana clusters or kanji compound proper nouns in message/parameters fields\n"
" Scan Map001.json through Map010.json at most — early maps have the most story content.\n"
"\n"
"Output the results EXACTLY in the format shown below, including the category headers "
"starting with #. Do not add any other text, preamble, or explanation outside the entries.\n"
"3. Stop once you stop finding new names or terms. Do not pad the output.\n"
"</file_strategy>\n"
"\n"
"<rules>\n"
"Apply to both sections:\n"
"- Separator: use a plain hyphen-minus (-). Never use — or . "
"The translation tool only recognises the plain hyphen.\n"
"- Descriptions must be entirely in English. Refer to other characters by English name only "
"(write 'her sister Ruin was kidnapped', not 'her sister ルイン was kidnapped').\n"
"- Never give two spelling options (e.g. 'Sylfia / Sylphia' is wrong). Commit to one translation.\n"
"\n"
"# Game Characters — rules:\n"
"- If a <known_speakers> list was provided, output entries for ONLY those names. "
"Skip unnamed NPCs, generic enemies, and narration-only entries.\n"
"- If no list was provided, discover named characters from the files, but still skip "
"unnamed NPCs and generic enemy types.\n"
"- For each character include: gender, role, speech register, personality, and whether "
"the name is player-chosen (check Actors.json ID 1).\n"
"\n"
"# Worldbuilding Terms — rules:\n"
"- Include: faction/organisation names, locations mentioned in dialogue but not on maps, "
"unique magic systems, lore titles, recurring in-universe concepts.\n"
"- Exclude: skill names, item names, weapon names, armour names (the tool handles those). "
"Skip generic RPG words (\u30dd\u30fc\u30b7\u30e7\u30f3, \u30ec\u30d9\u30eb, \u30b9\u30c6\u30fc\u30bf\u30b9, etc.). "
"Do not repeat character names here.\n"
"</rules>\n"
"\n"
"<output_format>\n"
"Output EXACTLY two sections with these headers. Do not add any preamble, explanation, "
"or text outside the entries.\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"# Game Characters\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"Identify every NAMED CHARACTER that appears in dialogue or descriptions.\n"
"If a 'Known speakers' list was provided above, use ONLY those names — do not add\n"
"characters that are not on that list, and skip any unnamed NPCs or generic enemies.\n"
"If no list was provided, discover named characters from the files yourself, but still\n"
"skip unnamed NPCs, generic enemy types, and narration-only entries.\n"
"For each character provide:\n"
" - Japanese name (katakana/kanji as it appears in-game)\n"
" - English transliteration or translation\n"
" - Gender (Male / Female / Unknown) — infer from speech patterns or pronouns\n"
" - Role (protagonist, antagonist, NPC, etc.)\n"
" - Speech register and personality notes — how they speak, their tone, any nicknames, "
"whether their name is player-chosen, etc.\n"
"\n"
"⚠️ IMPORTANT: In all descriptions, ALWAYS refer to other characters by their "
"ENGLISH name, never their Japanese name. "
"For example, write \"her sister Ruin was kidnapped\" not "
"\"her sister ルイン was kidnapped\". "
"The description text must be entirely in English with no Japanese characters "
"except inside the leading Japanese (English) name tag.\n"
"\n"
"Format — the header line, then one entry per line:\n"
"# Game Characters\n"
"\u30b7\u30ed (Shiro) - Female; protagonist; player-controlled (Actors.json ID 1); "
"speaks in a flustered, cute register with feminine speech markers; "
"her partner is Kurone\n"
"\u30af\u30ed\u30cd (Kurone) - Female; antagonist; cold and terse; speaks in short cutting sentences; "
"pursues Shiro throughout the story\n"
"\n"
"Rules:\n"
" - If a Known speakers list was provided, only output entries for names on that list.\n"
" - If a character has a player-chosen name (e.g. Actors.json id 1), note it explicitly.\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"# Worldbuilding Terms\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"Identify lore-specific terms that appear in dialogue, descriptions, or narration "
"but do NOT have a dedicated database file — i.e. terms the translation tool will NOT "
"auto-populate from Skills.json, Items.json, Armors.json, Weapons.json, etc.\n"
"\n"
"Target specifically:\n"
" - Faction / organisation names (kingdoms, guilds, cults, nations)\n"
" - Location names mentioned in dialogue but not map titles\n"
" - Unique magic systems, schools of magic, or power classifications\n"
" - Lore titles and honorifics unique to this setting\n"
" - Recurring in-universe concepts or proper nouns with no English equivalent\n"
"Entry format: Japanese (English) - description\n"
"\n"
"Format — the header line, then one entry per line:\n"
"# Worldbuilding Terms\n"
"\u9b54\u4e16\u754c (Demon World) - The demonic realm referenced in NPC dialogue; not a named map\n"
"\u8056\u5263\u6559\u56e3 (Holy Blade Order) - Antagonist faction controlling the eastern territories\n"
"\n"
"Rules:\n"
" - Do NOT list skill names, item names, weapon names, armour names — the tool handles those.\n"
" - Skip generic RPG words (\u30dd\u30fc\u30b7\u30e7\u30f3, \u30ec\u30d9\u30eb, \u30b9\u30c6\u30fc\u30bf\u30b9, etc.).\n"
" - Do NOT repeat character names here.\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"COMPLETE EXAMPLE OUTPUT\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"Below is what a correct, well-formed response looks like.\n"
"Your output should follow this structure exactly:\n"
"\n"
"```\n"
"<example>\n"
"# Game Characters\n"
"アリア (Aria) - Female; protagonist; player-chosen name (Actors.json ID 1); "
"speaks cheerfully in casual feminine speech; nicknamed アリアちゃん by her sister\n"
@ -980,40 +964,35 @@ class WorkflowTab(QWidget):
"appears in story cutscenes\n"
"裁定者 (Arbiter) - Title held by the ruling council; lore-specific rank with no "
"real-world equivalent\n"
"```\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"GLOBAL RULES (apply to both sections)\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
" - NEVER give two options for any term (e.g. 'Sylfia / Sylphia' is wrong). "
"Always commit to a single best translation. If multiple transliterations exist, "
"pick the most etymologically accurate or natural-sounding one and use only that.\n"
" - Use a plain hyphen-minus (-) as the separator between the Japanese entry and "
"its description. Never use an em dash (\u2014) or en dash (\u2013) \u2014 the "
"translation tool only recognises the plain hyphen."
"</example>\n"
"</output_format>\n"
)
_WRAP_PROMPT = (
"You are helping me configure text-wrap widths for a Japanese RPGMaker MV/MZ translation tool.\n"
"You are an expert RPGMaker MV/MZ configuration analyst.\n"
"\n"
"The tool wraps translated English text using a character-count limit (not pixels).\n"
"I need three values:\n"
"<task>\n"
"Calculate the correct text-wrap width settings for a Japanese-to-English RPGMaker MV/MZ "
"translation tool. The tool wraps translated English using character-count limits (not pixels). "
"I need three values: width, listWidth, and noteWidth.\n"
"</task>\n"
"\n"
" width — main dialogue / message box (Show Text)\n"
" listWidth — item / skill / help description windows\n"
" noteWidth — database note fields (item, weapon, armour, skill descriptions)\n"
"--- attach System.json and js/plugins.js here before continuing ---\n"
"\n"
"To calculate them:\n"
" 1. Read screenWidth and fontSize from System.json.\n"
" Check js/plugins.js for any MessageCore or Window plugin that overrides these.\n"
" 2. For each window type, estimate its pixel width, subtract ~48px padding, then:\n"
" chars = floor(content_px / (font_size × 0.58))\n"
" listWidth window is usually full or half screen width.\n"
" noteWidth window is usually the narrowest description pane (~4050% screen width).\n"
" 3. If the font size is above 26px and reducing it would meaningfully increase\n"
" characters per line, note where to change it (System.json or plugin parameter).\n"
"<instructions>\n"
"1. Read screenWidth and fontSize from System.json.\n"
" Check js/plugins.js for any MessageCore or Window plugin that overrides these values.\n"
"2. For each window type, estimate its pixel width, subtract ~48px padding, then calculate:\n"
" chars = floor(content_px / (font_size × 0.58))\n"
" - width: main dialogue/message box (Show Text) — typically full screen width\n"
" - listWidth: item/skill/help description windows — typically full or half screen width\n"
" - noteWidth: database note fields — typically the narrowest pane (~4050% screen width)\n"
"3. If font size is above 26px and reducing it would meaningfully increase characters per line, "
"note where to change it (System.json or the relevant plugin parameter).\n"
"</instructions>\n"
"\n"
"Do not show calculations. Just give me the final answer in this exact format:\n"
"<output_format>\n"
"Output only the final values — do not show calculations:\n"
"\n"
"```\n"
"width=<N>\n"
@ -1023,104 +1002,91 @@ class WorkflowTab(QWidget):
"```\n"
"\n"
"Followed by one sentence of assumptions if anything was estimated.\n"
"</output_format>\n"
)
_PLUGINS_JS_TRANSLATE_PROMPT = (
"You are helping me translate a Japanese RPGMaker MV/MZ game.\n"
"I need you to translate visible Japanese strings inside js/plugins.js\n"
"without breaking any game logic or plugin functionality.\n"
"You are an expert RPGMaker MV/MZ localisation engineer.\n"
"\n"
"A vocab.txt glossary file has been attached. Use it as your primary reference\n"
"for character names, worldbuilding terms, and their approved English translations.\n"
"Any Japanese name or term that appears in the glossary must be translated\n"
"exactly as specified there — do not invent alternative spellings.\n"
"<task>\n"
"Translate visible Japanese strings inside js/plugins.js without breaking any game logic "
"or plugin functionality. A vocab.txt glossary is attached — use it as your primary reference. "
"Any name or term that appears in the glossary must be translated exactly as shown there.\n"
"</task>\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## WHAT TO TRANSLATE\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"--- attach js/plugins.js and vocab.txt here before continuing ---\n"
"\n"
"Only translate string values that are directly shown to the player at runtime.\n"
"These are typically plugin parameters with Japanese text such as:\n"
" - Menu/button labels displayed in-game UI (e.g. \"決定\", \"キャンセル\")\n"
" - Scene/window title text (e.g. \"アイテム\", \"スキル\", \"装備\")\n"
" - In-game popup, tooltip, or notification messages\n"
" - Default NPC names or pronouns used in UI display\n"
" - Help or description text shown in help windows\n"
" - Battle log messages or status effect messages\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## WHAT MUST NOT BE TRANSLATED\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"<translate>\n"
"Only translate string values directly shown to the player at runtime:\n"
"- Menu/button labels in-game UI (e.g. 決定, キャンセル)\n"
"- Scene/window title text (e.g. アイテム, スキル, 装備)\n"
"- In-game popup, tooltip, or notification messages\n"
"- Default NPC names or pronouns used in UI display\n"
"- Help or description text shown in help windows\n"
"- Battle log messages or status effect messages\n"
"</translate>\n"
"\n"
"CRITICAL — translating the following will break the game:\n"
"<do_not_translate>\n"
"Translating the following WILL BREAK THE GAME:\n"
"\n"
" 1. Plugin parameter KEYS (object property names).\n"
" Example: { \"CommandName\": \"セーブ\" }\n"
" → translate \"セーブ\" but NOT \"CommandName\"\n"
"1. Plugin parameter keys (object property names).\n"
" { \"CommandName\": \"セーブ\" } → translate セーブ but NOT CommandName\n"
"\n"
" 2. Strings used as internal identifiers or lookup keys:\n"
" - Switch/variable names that match System.json entries\n"
" - Actor, skill, item, weapon, armour names if they are used\n"
" as keys inside other plugin parameters (e.g. skill filtering lists)\n"
" - Strings passed as plugin command arguments that the engine looks up\n"
"2. Strings used as internal identifiers or lookup keys:\n"
" - Switch/variable names matching System.json entries\n"
" - Actor, skill, item, weapon, armour names used as keys inside other plugin parameters\n"
" - Strings passed as plugin command arguments that the engine looks up\n"
"\n"
" 3. File paths, filenames, URLs, colour codes, font names, icon indices.\n"
" Example: \"img/faces/Actor1\" or \"#ffffff\" — do NOT translate.\n"
"3. File paths, filenames, URLs, colour codes, font names, icon indices.\n"
" (e.g. img/faces/Actor1 or #ffffff)\n"
"\n"
" 4. Plugin names and script identifiers:\n"
" - The \"name\" property at the top of each plugin block\n"
" (e.g. { \"name\": \"YEP_CoreEngine\" }) — never translate\n"
" - Function identifiers, class names, JS event names\n"
"4. Plugin names and script identifiers:\n"
" - The \"name\" property at the top of each plugin block (e.g. { \"name\": \"YEP_CoreEngine\" })\n"
" - Function identifiers, class names, JS event names\n"
"\n"
" 5. Any string that also appears in the game data files (Actors.json,\n"
" Skills.json, Items.json, etc.) AND is used as a lookup key in the\n"
" plugin — changing it here would desync it from the data file.\n"
"5. Any string in the game data files (Actors.json, Skills.json, Items.json, etc.) that is "
"also used as a lookup key in the plugin — changing it here would desync it from the data file.\n"
"\n"
" 6. Boolean strings, numeric strings, regex patterns.\n"
"6. Boolean strings, numeric strings, regex patterns.\n"
"</do_not_translate>\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## HOW TO IDENTIFY SAFE STRINGS\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"<safety_check>\n"
"Before translating any string, confirm all three are true:\n"
"- It is displayed directly to the player as visible text\n"
"- It is purely a UI label, not used as a key anywhere else\n"
"- Nothing in the codebase compares this exact string to another value\n"
"When in doubt, skip it — untranslated Japanese is better than a broken game.\n"
"</safety_check>\n"
"\n"
"Before translating a string, ask yourself:\n"
" ✔ Is this value ever displayed directly to the player as text?\n"
" ✔ Is it purely a UI label, not a key used anywhere else?\n"
" ✔ Does nothing in the codebase compare this exact string to another value?\n"
"<output_format>\n"
"Provide the translated file as a complete replacement of js/plugins.js. Only change the "
"string values identified above. Preserve all original formatting, indentation, comments, and structure.\n"
"\n"
"If all three are YES, it is safe to translate.\n"
"When in doubt, SKIP IT — untranslated Japanese is better than a broken game.\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## OUTPUT FORMAT\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"\n"
"Provide the translated file as a complete replacement of js/plugins.js.\n"
"Only change the string values identified above.\n"
"Preserve all original formatting, indentation, comments, and structure.\n"
"\n"
"After the file, output a translation summary:\n"
"After the file, output a summary:\n"
"\n"
"### Translations Made\n"
"List each change in this format:\n"
" Plugin: <plugin name>\n"
" Parameter: <parameter key>\n"
" Before: <original Japanese>\n"
" After: <English translation>\n"
"\n"
"### Skipped (Ambiguous or Internal)\n"
"List any Japanese strings you detected but chose NOT to translate, with a one-line reason.\n"
"List any Japanese strings you detected but did not translate, with a one-line reason.\n"
"</output_format>\n"
)
_ACE_SCRIPTS_TRANSLATE_PROMPT = (
"You are helping me translate a Japanese RPGMaker Ace (VX Ace) game.\n"
"The game's scripts are in the ace_json/scripts/ folder as .rb files.\n"
"I need you to translate visible Japanese strings inside these Ruby scripts\n"
"without breaking any game logic or script functionality.\n"
"You are an expert RPGMaker VX Ace (Ruby) localisation engineer.\n"
"\n"
"<task>\n"
"Translate visible Japanese strings inside the game's Ruby scripts (ace_json/scripts/*.rb) "
"without breaking any game logic or script functionality. A vocab.txt glossary is attached — "
"use it as your primary reference. Any name or term in the glossary must be translated exactly as shown.\n"
"</task>\n"
"\n"
"--- attach the .rb script files and vocab.txt here before continuing ---\n"
"\n"
"A vocab.txt glossary file has been attached. Use it as your primary reference\n"
"for character names, worldbuilding terms, and their approved English translations.\n"
"Any Japanese name or term that appears in the glossary must be translated\n"
"exactly as specified there — do not invent alternative spellings.\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## WHAT TO TRANSLATE\n"
@ -1159,50 +1125,44 @@ class WorkflowTab(QWidget):
"\n"
" 6. Any string that is read back elsewhere in the scripts with an exact match.\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## HOW TO IDENTIFY SAFE STRINGS\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"<safety_check>\n"
"Before translating any string, confirm all three are true:\n"
"- It is displayed directly to the player as visible text\n"
"- It is purely a display string, not compared or looked up anywhere\n"
"- Changing it would break no conditional logic or data lookup\n"
"When in doubt, skip it — untranslated Japanese is better than a broken game.\n"
"</safety_check>\n"
"\n"
"Before translating a string, ask yourself:\n"
" \u2714 Is this value ever displayed directly to the player as text?\n"
" \u2714 Is it purely a display string, not compared or looked up anywhere?\n"
" \u2714 Would changing it break no conditional logic or data lookup?\n"
"\n"
"If all three are YES, it is safe to translate.\n"
"When in doubt, SKIP IT — untranslated Japanese is better than a broken game.\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## OUTPUT FORMAT\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"\n"
"For each .rb file that needed changes, provide the full translated file content.\n"
"Only change the string values identified as safe above.\n"
"<output_format>\n"
"For each .rb file that needed changes, provide the full translated file content. "
"Only change string values identified as safe. "
"Preserve all Ruby syntax, indentation, comments, and structure exactly.\n"
"\n"
"After all files, output a translation summary:\n"
"After all files, output a summary:\n"
"\n"
"### Translations Made\n"
"List each change in this format:\n"
" File: <script filename.rb>\n"
" Before: <original Japanese>\n"
" After: <English translation>\n"
"\n"
"### Skipped (Ambiguous or Internal)\n"
"List any Japanese strings you detected but chose NOT to translate, with a one-line reason.\n"
"List any Japanese strings you detected but did not translate, with a one-line reason.\n"
"</output_format>\n"
)
_PLUGIN_PROMPT = (
"You are helping me safely translate a Japanese RPGMaker MV/MZ game.\n"
"Before I run Phase 2, I need you to audit several optional code types and tell me\n"
"(a) which ones contain player-visible Japanese text that needs translation, and\n"
"(b) for code 122, exactly which variable ID ranges carry display text vs internal keys.\n"
"You are an expert RPGMaker MV/MZ event system analyst.\n"
"\n"
"Attach the game's event files (CommonEvents.json, Troops.json, Map*.json)\n"
"and js/plugins.js before running this prompt.\n"
"<task>\n"
"Audit several optional event code types and report: (a) which contain player-visible "
"Japanese text that needs translation, and (b) for code 122, exactly which variable ID "
"ranges carry display text versus internal keys.\n"
"</task>\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## AUDIT 1 — Code 122 (Control Variables) — which variable IDs carry display text\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"--- attach CommonEvents.json, Troops.json, Map*.json, and js/plugins.js here ---\n"
"\n"
"<audit_1 code=\"122\">\n"
"Code 122 — Control Variables — which variable IDs carry display text\n"
"\n"
"A code 122 entry looks like:\n"
" { \"code\": 122, \"parameters\": [startVarId, endVarId, 0, 4, \"\\\"some string\\\"\"] }\n"
@ -1220,13 +1180,12 @@ class WorkflowTab(QWidget):
"Summarise translatable variable IDs as compact numeric ranges,\n"
"e.g. 'Translate IDs: 5, 10-18, 42'. Separately list any DO NOT TRANSLATE IDs\n"
"with the reason. The ranges will be entered as min/max in the translation tool.\n"
"</audit_1>\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## AUDIT 2 — Plugin codes with visible text (357 / 356 / 355-655 / 657 / 320 / 324 / 325 / 108)\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"\n"
"For EACH of the following code types, scan all events and report whether any\n"
"instance contains Japanese text that is visible to the player at runtime.\n"
"<audit_2>\n"
"Plugin codes with visible text — 357 / 356 / 355-655 / 657 / 320 / 324 / 325 / 108\n"
"For each code type below, scan all events and report whether any instance contains "
"Japanese text visible to the player at runtime.\n"
"\n"
"--- Code 357 (MZ Plugin Commands) ---\n"
"parameters[0] = plugin header; parameters[3] = data dict.\n"
@ -1287,11 +1246,9 @@ class WorkflowTab(QWidget):
" info:, ActiveMessage:, event_text, Menu Name, text_indicator\n"
"Do any 108 entries matching those patterns have Japanese visible to the player?\n"
"If yes: ENABLE CODE108 and list the patterns found. If no: SKIP CODE108.\n"
"</audit_2>\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## Required output format\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"\n"
"<output_format>\n"
"Reply with these exact sections:\n"
"\n"
"### Code 122 — Variable Translation Ranges\n"
@ -1325,11 +1282,9 @@ class WorkflowTab(QWidget):
"### Code 108 — Enable or Skip\n"
" ENABLE / SKIP — patterns found: <list>\n"
"\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"## GUI Action Summary\n"
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
"### GUI Action Summary\n"
"\n"
"After all audit sections above, output this final block so I can configure the GUI:\n"
"After all audit sections above, output this final block to configure the GUI:\n"
"\n"
"ENABLE CODES : <comma-separated CODE* keys to check, e.g. CODE357, CODE356>\n"
"SKIP CODES : <codes that have no visible text>\n"
@ -1338,6 +1293,7 @@ class WorkflowTab(QWidget):
"122 VAR RANGE : min=<N>, max=<M>\n"
"\n"
"If a field has nothing to fill in, write NONE.\n"
"</output_format>\n"
)
# ── Step 1 (Optional): Pre-process ────────────────────────────────
@ -2683,15 +2639,13 @@ class WorkflowTab(QWidget):
if speakers:
speaker_lines = "\n".join(f" {orig} ({tl})" for orig, tl in speakers)
known_block = (
"## Known speakers (identified by Parse Speakers)\n"
"\n"
"The following character names were already extracted from the game files.\n"
"For the '# Game Characters' section, focus ONLY on these names — do NOT add\n"
"extra characters that are not in this list.\n"
"<known_speakers>\n"
"These character names were extracted from the game files by the Parse Speakers tool.\n"
"For the '# Game Characters' section, output entries for ONLY these names.\n"
"Skip any unnamed NPCs, generic enemies, or narration-only entries.\n"
"\n"
+ speaker_lines
+ "\n\n---\n\n"
+ "\n</known_speakers>\n\n"
)
final_prompt = known_block + self._PROMPT_GLOSSARY
else: