Rework prompts a bit
This commit is contained in:
parent
c16d61498a
commit
b2baa5e463
1 changed files with 247 additions and 293 deletions
|
|
@ -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 1–2 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 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 — <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 (~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"
|
||||
"<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 (~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"
|
||||
"</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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue