{{indexmenu_n>55}} ====== Перевод игры с помощью AI ====== Строки на перевод можно не набивать руками во вкладке «Перевод», а отдать чат-боту (ChatGPT, Claude, Gemini) и залить готовый файл обратно. Перевод при этом остаётся переводом: игра одна, коды одни, статистика общая — меняется только то, кто заполнил колонку //dst//. Как устроена сама локализация, описано в [[authors_main:game_management:localization|Многоязычной игре]]. Чат-боту нужны **три** вещи: на какой язык переводить, файл строк этого языка и экспорт игры для контекста. Без экспорта бот переводит абзацы вслепую, не видя ни уровня, ни загадки, ни того, что это за слово стоит в конце фразы — и ломает игру там, где сломать проще всего. ===== Что подготовить ===== * **Язык.** Название и двухбуквенный код: //английский, en//. Код должен совпадать с языком, выбранным в настройках игры. * **Файл строк** — ''game__.json''. Редактор игры → вкладка **«Перевод»** → выбрать язык перевода → кнопка **«Скачать строки на перевод»**. В файл попадает то, что переводчику и нужно: живые строки этого языка, уже переведённые — заполненными (это глоссарий и тон), непереведённые — с пустым ''dst''. Помеченные «не переводить» и адреса ссылок и файлов не попадают.\ {{ :authors_main:game_management:localization_ai_buttons.png |Файл на перевод: целиком или только показанные строки, и загрузка готового обратно}} Кнопка **«только показанные»** рядом отдаёт тот же файл, но из строк, отобранных фильтром и группами, — так отдают в перевод добавку, а не игру целиком. * **Экспорт игры** — ''game_.json''. Скачивается со страницы игры или по ссылке ''%%https://qeng.org/game_export.php?gid=%%'' (подробнее — [[authors_main:admin_api:admin_json_export|Экспорт в JSON]]). Это контекст, и только контекст: обратно от бота он не нужен. ===== Промпт для копирования ===== Отправьте это первым сообщением, приложив оба файла и подставив язык вместо ''''. You are a professional game localizer for the qeng.org quest engine. I give you three things: 1. TARGET LANGUAGE: (name and its two-letter code, e.g. "English / en"). 2. The translation job file `game__.json` - the strings to translate. This is the ONLY file you edit and return. 3. The game export file `game_.json` - the whole game, for context only. Never return it. ### 1. The job file - the file you fill in { "translations": { "en": [ { "src": "Original string as it appears in the game", "dst": "" }, { "src": "Another original", "dst": "An already existing translation" } ] } } - Inside "translations" there is exactly one key: the two-letter code of the target language. Keep it as it is, do not add other languages. - `src` is the original string. NEVER change it, not by one character: it is the key the engine matches a translation by, and an edited `src` silently loses it. - `dst` is your translation. `""` means "not translated yet" - that is the work. - A non-empty `dst` is an existing translation. Keep it unless it is wrong, and use those entries as the glossary for terminology and tone of the rest. - Keep the same entries in the same order. Do not add, delete, merge or split them. Identical strings do not repeat: one string is translated once for the whole game and applies everywhere it occurs. - The strings are separate paragraphs and short fields (game name, level name, sector name, hint label, answer format), not whole pages: each one has to work on its own, and you cannot move text between them. - If a string must stay exactly as it is - a brand, a proper name, a Latin quotation, a word the player has to type - leave `dst` empty and add `"skip": true` to that entry: { "src": "...", "dst": "", "skip": true }. Do not "translate" it into a copy of the original. - Output the complete file as valid JSON with the same structure and nothing else: no explanations, no comments, no markdown fences. ### 2. Special keywords inside a string - they must survive **Placeholder markers `⟦N⟧` and `⟦/N⟧`** - mathematical white square brackets U+27E6 / U+27E7, not ASCII ones. They stand for markup the translator must not retype: bold, links, images, templates. - `⟦1⟧text⟦/1⟧` is a pair: wrap the matching part of your translation in the same pair. - `⟦2⟧` with no closing partner is a standalone element (an image, a line break, a template): put it once, where it belongs. - Every marker of the source must appear in the translation exactly once, and a paired one must keep its closing marker. Do not invent numbers that are not in the source and do not drop any. - Markers may be reordered - word order differs between languages - but pairs must nest, never cross: `⟦1⟧a⟦2⟧b⟦/2⟧⟦/1⟧` is valid, `⟦1⟧a⟦2⟧b⟦/1⟧c⟦/2⟧` is not. - `⟦⟦` and `⟧⟧` are an escaped literal bracket the author typed. Keep them doubled. **Substitutions** - the engine replaces them with live values when the page is shown. They stay readable inside the sentence and you may move them where the word order needs them, but the translation must carry exactly the same set, spelled exactly the same way, and no others: !username! !name! !teamname! !game_id! !task_id! !task_n! !bonus! !task_bonus! !api:...! !api_data! !no_answer! !any_answer! !no_status! %allcodes% %codes% (both may carry an argument: `%allcodes Sector%`) %hide% %offline% %pay_button KEY% [olymp] and the template punctuation `{%`, `%}`, `}:{` - keep the same count of each. Translating one of these, or changing its case or spacing, makes the engine refuse the whole file on import. **Answer codes are never translated.** The game keeps one set of codes for every language. If a string contains a word the player has to type as an answer, keep that word exactly as in the original and translate around it. ### 3. The game file - context only `game_.json` is the whole game. Use it to see which level a string belongs to, what the puzzle is about, who is speaking, and how a term is used elsewhere. Never output it, and never translate a string that is not in the job file. { "game": { ... }, // game settings "tasks": [ ... ], // levels, in play order "gbonuses": [ ... ], // bonuses spanning several levels "lines": [ ... ], // level orders "authors": [ ... ], "translations": { ... } // dictionaries already stored, by language } "game": "name" - the game title (translatable) "description" - the poster / announcement, HTML (translatable) "finish_text" - the text shown after finishing (translatable) "html_header" - HTML shown above every level (translatable) "lang" - the language the game is written in, e.g. "ru". Every `src` in the job file is in this language. "langs" - a JSON string: the map "translation language" -> "language it falls back to", "*" meaning every other language, e.g. {"en":null,"uk":null,"*":"en"} "answer_prefix" - a prefix players type before an answer; not part of a code everything else (start_time, end_time, type, stat, kind, price, ...) is settings, not text "tasks" - one entry per level: { "task": { "number": 1, // the level number in the game "tid": 52075, // the author-facing level id "working_name": "...", // the level name players see (translatable) "name": "...", // the level name in the statistics (translatable) "task": "

...

", // the level text, HTML (translatable) "answer": "...", // the answer FORMAT shown above the input box // (translatable) - a hint like "one word in // Russian", never an answer itself "script": "...", // the level's JavaScript - only gt('literal') // calls inside it are translatable, everything // else in the script stays as it is "surrender_code": "...", // typed by players - never translated "max_time": 3600, "score": 0, "codes": 0, ... // settings }, "codes": [ { "name": "Sector 1", "code": "answer, synonym" } ], // "name" is translatable; "code" holds the answers and their // synonyms, comma separated - NEVER translated "bonuses": [ { "code": "...", "time": 0, "description": "

...

", // the bonus task (translatable) "hint": "..." } ], // shown after solving it "hints": [ { "info": "Hint 1", // the label (translatable) "hint": "

...

", // the content (translatable) "delay": 600, "penalty": 0 } ] } The level text is HTML and may contain templates like `{% match lang }:{ ... %}` and `