diff --git a/gui/workflow_tab.py b/gui/workflow_tab.py index 1fa567c..6ede557 100644 --- a/gui/workflow_tab.py +++ b/gui/workflow_tab.py @@ -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" + "\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" + "\n" + "\n" + "\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" + "\n" + "\n" + "--- attach your game files here before continuing ---\n" + "\n" + "\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 or \\\\k 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 or \\\\k 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" + "\n" "\n" - "## Flags that MAY need to be enabled\n" + "\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" + "\n" + "The speaker name is embedded at the start of a 401 line directly before 「, " + "with no intervening markup or brackets.\n" + "\n" + "{ \"code\": 401, \"parameters\": [\"エレナ「今日は晴れですね。\"] }\n" + "\n" + "Enable if the game has dialogue lines matching this pattern.\n" + "\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" + "\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" + "\n" + "{ \"code\": 101, \"parameters\": [\"\", 0, 0, 2] }\n" + "{ \"code\": 401, \"parameters\": [\"衛兵さん\"] } ← plain name, no color or brackets\n" + "{ \"code\": 401, \"parameters\": [\"「……起きたか」\"] }\n" + "\n" + "Enable if ANY speakers in the game use this pattern, even if others use an always-on format.\n" + "\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" + "\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" + "\n" + "{ \"code\": 101, \"parameters\": [\"face_alice\", 0, 0, 2, \"\"] }\n" + "\n" + "If you recommend this, you MUST list every unique face filename found in parameters[0] " + "of code 101 across all attached files.\n" + "\n" + "\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" + "\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 1–2 found no flag-requiring patterns AND no always-on format " + "→ consider FACENAME101.\n" + "\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" + "\n" + "Provide exactly four sections:\n" "\n" - "Step 3 — Only if no flag-requiring patterns were found in Steps 1–2, 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 — \n" - " FIRSTLINESPEAKERS : ENABLE / SKIP — \n" - " FACENAME101 : ENABLE / SKIP — \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 — \n" + " FIRSTLINESPEAKERS : ENABLE / SKIP — \n" + " FACENAME101 : ENABLE / SKIP — \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" + "\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" + "\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" + "\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" + "\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" + "\n" + "\n" + "\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 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" + "\n" + "\n" + "\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" + "\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." + "\n" + "\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" + "\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" + "\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 (~40–50% 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" + "\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 (~40–50% 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" + "\n" "\n" - "Do not show calculations. Just give me the final answer in this exact format:\n" + "\n" + "Output only the final values — do not show calculations:\n" "\n" "```\n" "width=\n" @@ -1023,104 +1002,91 @@ class WorkflowTab(QWidget): "```\n" "\n" "Followed by one sentence of assumptions if anything was estimated.\n" + "\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" + "\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" + "\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" + "\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" + "\n" "\n" - "CRITICAL — translating the following will break the game:\n" + "\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" + "\n" "\n" - "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" - "## HOW TO IDENTIFY SAFE STRINGS\n" - "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" + "\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" + "\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" + "\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: \n" " Parameter: \n" " Before: \n" " After: \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" + "\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" + "\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" + "\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" + "\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" + "\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" + "\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: