Переклад гри за допомогою AI
Рядки на переклад можна не набивати руками у вкладці «Переклад», а віддати чат-боту (ChatGPT, Claude, Gemini) і залити готовий файл назад. Переклад при цьому лишається перекладом: гра одна, коди одні, статистика спільна — змінюється лише те, хто заповнив колонку dst. Як влаштована сама локалізація, описано в Багатомовній грі.
<note important>Чат-боту потрібні три речі: якою мовою перекладати, файл рядків цієї мови і експорт гри для контексту. Без експорту бот перекладає абзаци наосліп, не бачачи ні рівня, ні загадки, ні того, що це за слово стоїть у кінці фрази — і ламає гру саме там, де зламати найлегше.</note>
Що підготувати
- Мова. Назва і дволітерний код: англійська, en. Код має збігатися з мовою, вибраною в налаштуваннях гри.
- Файл рядків —
game_<id>_<lang>.json. Редактор гри → вкладка «Переклад» → вибрати мову перекладу → кнопка «Завантажити рядки на переклад». У файл потрапляє те, що перекладачеві й потрібно: живі рядки цієї мови, уже перекладені — заповненими (це глосарій і тон), неперекладені — з порожнімdst. Позначені «не перекладати» та адреси посилань і файлів не потрапляють.\
Кнопка «тільки показані» поруч віддає той самий файл, але з рядків, відібраних фільтром і групами, — так віддають у переклад додачу, а не гру цілком. - Експорт гри —
game_<id>.json. Завантажується зі сторінки гри або за посиланнямhttps://qeng.org/game_export.php?gid=<id>(докладніше — Експорт у JSON). Це контекст, і тільки контекст: назад від бота він не потрібен.
Промпт для копіювання
Надішліть це першим повідомленням, доклавши обидва файли й підставивши мову замість <TARGET LANGUAGE>.
You are a professional game localizer for the qeng.org quest engine.
I give you three things:
1. TARGET LANGUAGE: <TARGET LANGUAGE> (name and its two-letter code, e.g. "English / en").
2. The translation job file `game_<ID>_<lang>.json` - the strings to translate.
This is the ONLY file you edit and return.
3. The game export file `game_<ID>.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_<ID>.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": "<p>...</p>", // 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": "<p>...</p>", // the bonus task (translatable)
"hint": "..." } ], // shown after solving it
"hints": [ { "info": "Hint 1", // the label (translatable)
"hint": "<p>...</p>", // the content (translatable)
"delay": 600, "penalty": 0 } ]
}
The level text is HTML and may contain templates like `{% match lang }:{ ... %}`
and `<script>` blocks. In the job file all of that is already gone or replaced
by `⟦N⟧` markers: you only ever see plain text plus markers and substitutions.
Never add HTML tags to a translation.
A fragment marked `translate="no"` in the HTML never becomes a string at all. If
a phrase you see in the game is missing from the job file, that is usually why,
and it is deliberate.
### 4. How to translate
- Translate into <TARGET LANGUAGE>, keeping the register of the original: quest
text is usually informal and playful, settings-like strings are neutral.
- Keep roughly the same length: the text goes into the same layout, often on a
phone screen.
- Keep terminology consistent across the whole file - the same term gets the
same translation everywhere. Read the already filled `dst` entries first.
- Riddles and wordplay: if the puzzle depends on the letters or the sound of a
word, keep that word and translate around it rather than solving the puzzle
away.
- Numbers, proper names, URLs and file names stay as they are.
- A string that is nothing but a substitution or a marker is not translated:
leave its `dst` empty.
Now translate the file into <TARGET LANGUAGE> and output the complete JSON.
Як залити результат назад
- Збережіть відповідь бота у файл
.json. - Редактор → вкладка «Переклад» → та сама мова → «Завантажити переклади з файлу».
- Перегляньте зміни у вікні збереження — там вони видні порядково — і збережіть.
Файл лягає в чернетку мовчки і поверх: це файл цієї гри, який пішов порожнім і повернувся заповненим, а правка наявного перекладу — саме те, заради чого його віддавали.
Пропущено — це нормально, і ось через що рядок потрапляє в це число:
dstпорожній (і немаєskip) — бот цей рядок не переклав. Порожній переклад нічого не стирає: наполовину заповнений файл означає «переклали поки стільки», а не «решту прибрати».- такий переклад уже є — правкою це не вважається;
srcу грі більше немає — бот його підправив, або завдання встигли змінити після вивантаження;- мова у файлі не та, яка перекладається.
Якщо пропущено підозріло багато — майже напевно бот переписав src: перепитайте його, попросивши повернути вихідні рядки без жодної зміни.
Велика гра
Гра на сотні абзаців в одну відповідь бота не влізе. Ріжте масив на шматки по 100–200 рядків, повторюючи в кожному шматку обгортку — translations і код мови:
{ "translations": { "en": [ ...перші 150 рядків... ] } }
Файли завантажуються по черзі й доповнюють одне одного: кожен пише лише свої рядки. Порядок шматків значення не має.
Що перевірити після
- Плейсхолдери й підстановки. Якщо бот їх поламав, рядок не збережеться: редактор підсвітить його, а імпорт відмовиться цілком із текстом «переклад не зберігає плейсхолдери ⟦N⟧ або підстановки оригіналу». Це не прискіпливість — така пара все одно ніколи б не застосувалася, і гравець побачив би базовий текст.
- Коди. Переконайтеся, що кодові слова всередині тексту лишилися як були. Автоматично перекладене кодове слово ламає гру найтихіше.
- Вичитку. Увімкніть групу «перекладені» в таблиці і пройдіть очима: машина помиляється не там, де чекаєш, — у жартах, у звертаннях на «ти/ви» і в термінах, які в цій грі означають своє.
- Саму гру — з явною мовою:
https://qeng.org/game/1234/?lang=en.
