Translating the game
A guide for translators, no programming needed: export the game's text from your own disc into a plain text file, write your translation next to each line, and apply the file back onto a copy of your disc - in your browser or on the command line. This page covers what you need, both paths, how much room each line has, and why a line can stay English. The technical details live in the translation reference.
What you need
- Your own copy of Legend of Legaia (USA) (
SCUS-94254) as a.binimage (Mode 2/2352), or its.cuesheet. Packs are keyed to the USA disc, so they do not apply to the European or Japanese discs. You can still export those discs to read their script next to yours: a Japanese export gives every line of the original Japanese dialog as readable text. - A text editor that saves UTF-8 - Notepad++, VS Code, Kate, or TextEdit in plain-text mode. The pack is a YAML file: plain text with indentation.
- A way to apply the pack: the ROM patcher page, which runs in your browser and uploads nothing, or the
legaia-patcherprogram from a release archive (getting started). - An emulator to play the result.
How a translation works
The game's text is spread across the disc: item and spell names in the main program, dialog inside each scene's data, menu labels inside the menu code. The tools collect all of it into one file, a language pack. Each piece of text becomes one entry:
- key: 'scus:str:0x80012260' # where the text lives on the disc
context: 'item 0x79' # a hint for you
source: 'Healing Berry' # the English text
translation: '' # you write here
budget: 13 # how many bytes fit here
You only ever edit translation:. Leave key, source and budget alone. An entry you leave empty stays English, so a half-finished pack is always playable.
The disc was never meant to be edited, so every piece of text has a fixed amount of room - its budget. How strict that is depends on the kind of text; how much room a line has explains it.
Working pack and shareable pack
| Pack | Contains | Share it? |
|---|---|---|
| Working pack | the English text from your disc (source:) beside your translations - the one you edit | No - it holds the game's own script |
| Shareable pack | only your translations, each tied to its place on the disc by its key | Yes - anyone who owns the disc can apply it |
You turn a working pack into a shareable one with Make a shareable pack on the ROM patcher page, or translate strip on the command line.
Path A · in your browser
The ROM patcher page does everything in the tab. Your disc is read on your machine and never uploaded.
- Choose your discUnder Disc image, then open the Language section at the top of the form.
- Export a starter packWith Language set to None, press Export a starter pack from my disc: you get
legaia_en.working.yaml, everytranslation:empty. To continue an existing translation, choose that language (or Import my own pack) first - the button becomes Export a working copy of this pack. - Edit the packSet the
language:line to your code (fr,pt-BR, ...), add yourself undercontributors:, fill intranslation:fields. The markup table lists what to keep. - Load itSet Language to Import my own pack (.yaml) and pick your file.
- Check pack against my discRuns the whole import in memory and reports, per section, how many lines land and why the others would not. Nothing is written.
- Fix skipped linesDownload skipped lines (.csv): one row per line with its
key, areasonand the fullmessage; see the troubleshooting table. - PatchOptionally tick Give translated dialog more room (below), then Patch & download. Combines with any randomizer options. The patched image is for your own play only.
- Make a shareable packMake a shareable pack (.yaml, no English) - the file to pass around.
Editing in the workbench
Steps 3 to 7 can also happen on the translation workbench page instead of in a text editor. Pick your disc there, then load a published pack, your own .yaml, or start fresh. Every line is listed with its English, a box for your translation, and live feedback as you type:
- its size in bytes against its room (for a name, also the free bytes it could move into), with any character the game cannot draw highlighted and the reason beside it, plus one-click fixes (fold the accents, or switch the pack to the accent font);
- its width on screen in the game's own font, against the width its box or menu column allows, and a picture of the dialog box as the game draws it;
- a moment after you stop typing, whether its scene still fits.
An Accents panel sets how accented letters reach the disc (see accents), shows how many lines still hold a character the game will not draw, and has a character palette per language that types into the line you are editing. Beside it, a Symbols palette shows every button and icon the game can draw inside text, taken from your own disc; click one to insert it (see buttons and icons). A dashboard shows where the room is: per section, per name table, per menu pool, and every scene from the fullest down. Click a row to list its lines. Check against my disc runs the full check. Your edits are saved in the browser as you type, and the page offers to resume them next time. Download the working pack to keep your own copy, and the shareable pack to share. The workbench does not patch a disc; load the shareable pack on the ROM patcher page for that.
Path B · on the command line
The same work in six steps with legaia-patcher. A .cue works wherever a .bin does.
- Exportthe disc's text into a working pack (once).
- Initan empty pack for your language;
--resume site/lang/fr.yamlstarts from a published pack. - Translatein your editor. Team?
init --chunk 500splits the pack;mergeputs the pieces back. - Statschecks the pack against your disc; nothing is written.
- Stripmakes the shareable pack.
- Importonto a copy of your disc, plus a PPF patch.
legaia-patcher translate export --input "Legend of Legaia (USA).bin" -o legaia_en.yamllegaia-patcher translate init --lang fr --from legaia_en.yaml --contributor "Your Name" -o legaia_fr.yamllegaia-patcher translate merge --base legaia_fr.yaml --pack legaia_fr.001.yaml --pack legaia_fr.002.yaml -o legaia_fr.yamllegaia-patcher translate stats --pack legaia_fr.yaml --input "Legend of Legaia (USA).bin"legaia-patcher translate strip --pack legaia_fr.yaml -o fr.yamllegaia-patcher translate import --input "Legend of Legaia (USA).bin" --pack legaia_fr.yaml --output legaia_fr.bin --patch legaia_fr.ppfstats and import print skipped lines grouped by reason; --verbose lists every line with its key. The tool never writes to your original image: --output is a new patched image for your own play, and --patch is a small PPF file that turns a clean disc into the translated one - a PPF is safe to share. Every flag: CLI reference.
How much room does a line have?
The budget: field is the number of bytes a translation may take in place. A plain letter is one byte; a markup token such as {c1:00} is two. What happens when you go over depends on the kind of text.
Names
Item, item-type, spell, art and accessory names (and their descriptions) sit one after another, each in a slot rounded up to a multiple of 4 bytes. So the spare room depends on how long the English happens to be: Potion has one spare byte, Antidote three, Medicine none. That is why two names of the same length can have different budgets.
A name longer than its slot moves automatically: the tools pack the names tighter, collect the bytes shorter translations give up, and place the longer names there. Nothing to switch on. It fails only when the whole table has run out of room (no free run) - then shorten that name or others in the same table.
Monster names grow their record instead, up to 15 bytes, the longest name the game already uses. Party names (9 bytes) and world-map place names (31 bytes) are fixed fields. A name that fits in bytes can still be too wide on screen: an item list has a fixed quantity column.
Menu and battle labels
Menu commands, battle messages and system prompts are reached straight from the game code. A translation longer than its slot moves automatically: the tools find every place in the code that points at the label and point it at the new copy. The room comes from other labels in the same part of the game that your translation made shorter, and for the pause, shop and save menus from a block of spare bytes kept for translations (no mod uses it). A few labels cannot move; for those the slot is a hard limit, so abbreviate. The translation workbench's Room per category card and legaia-patcher translate space show how much room each category has left.
Dialog
For dialog the budget on each line is only a hint. The real limit is the scene: each scene's dialog is stored compressed, and on the USA disc each compressed scene fills its space exactly.
So one line longer than the English usually still fits - the tools move the rest of the scene along to make room. What cannot grow is the scene as a whole, and translated text compresses a little worse than English, so a scene can overflow even when no line got longer. When it does, the tools put some of its lines back in English, starting with the ones that cost the most room, and report each. Shorten them (or other lines of the same scene) and check again.
Giving dialog more room
Give translated dialog more room on the site, --allow-relayout on the command line, removes the scene limit: an overflowing scene gets extra 2048-byte sectors and the rest of the disc shifts along, so every line fits at full length. The official European discs were mastered the same way. It affects only dialog, and it costs three things:
- The disc image grows, usually by a few KB.
- No PPF. A PPF only describes same-size changes, so you get the patched image only.
- Save states break. A save state made on another layout no longer matches; start from a fresh boot or a memory-card save.
Room on screen
Fitting in bytes is not the same as fitting on screen. The game never wraps text for you: a dialog row breaks only where you put a | (or where a new line starts), and a row wider than the box simply runs past its edge. Names have the same limit sideways - an item name much wider than the English ones runs into the quantity column of the item list.
Rough widths, measured in the game's own proportional font: a dialog row holds about 244 pixels (three rows per box), an item name in the pause menu or a shop about 104. Narrow letters (i, l) take far less room than wide ones (M, W), so count pixels, not characters. The full table is in line width and wrapping.
The workbench measures each line as you type and draws it in the game's font. From the command line, legaia-patcher translate space --input DISC.bin --pack my_pack.yaml reports a whole pack's room.
Every room rule, per section: budgets in the reference.
Why did my line stay English?
A line stays English when its translation: is empty, or when the importer skipped it. Every skip comes with a message; the groups below are the ones the coverage report and the CSV's reason column use. N and M stand for numbers.
| Message | What it means | What to do |
|---|---|---|
| Over budget | ||
translation needs N bytes but the in-place budget is M (shorten the text) | a label, fixed field or line cannot grow | shorten to M bytes or fewer |
... and the scene MAN could not be grown to fit it | no room could be made in this scene | shorten, or give dialog more room |
... and the script walk does not reach this line, so it cannot be relocated | this line can only be replaced in place | keep it at or under its English length |
| Scene dialog does not recompress into its footprint | ||
scene N: rolled back - the scene's dialog no longer recompresses into its N byte footprint | the scene was full, so this line went back to English | shorten it or other lines of the scene, or give dialog more room |
| Name longer than the name tables have room for | ||
... the name tables have no free run that long to move it into | every free byte of the table is used | shorten this name or others in the same section |
| Monster name longer than 15 bytes | ||
monster N: name needs N bytes but a monster name holds at most 15 | the game's limit for enemy names | shorten to 15 bytes |
| Not encodable in the retail glyph set | ||
translation not encodable: 'é' is not in the retail NTSC font - fold it to 'e', or turn on the accent font | the pack is in the default accent mode | set accents: font (the letter draws) or accents: fold (it becomes e); see accents |
translation not encodable: 'Ж' (U+0416) is not in the retail glyph set and has no fold | no font here can draw it | write it with Latin letters |
translation not encodable: malformed escape / stray '}' | a brace that is not a valid token | fix the token; write literal braces as {7b} / {7d} |
translation not encodable: 0xNN is not a 2-byte opcode | a {xx:yy} token with the wrong first byte | copy the token exactly from source: |
pack source doesn't encode (corrupted pack?) | the source: field was changed | restore it, or re-export |
| Not on this disc (wrong image or conflicting patch) | ||
disc bytes don't match the pack source | the disc does not hold the expected text | use a clean, unpatched USA disc |
this disc's text is N bytes but the pack expects M - the pack was not built for this image | the same, for a shareable pack | use a clean, unpatched USA disc |
| Other | ||
PROT entry N: M other line(s) of this scene no longer sit where the pack expects them | the disc was already patched, so the scene moved | import onto a fresh copy of the original disc |
segment framing not found at the keyed offset | the line is not where the key says | import onto a fresh copy; do not edit keys |
the text framing at this offset is a coincidence inside a decoded instruction's operands | the entry was never real dialog | leave it empty |
PROT entry N is not a dialog carrier on this disc | the entry was never real dialog | leave it empty, or re-export |
party name must fit 9 bytes | the party-name field is fixed | shorten to 9 bytes |
a monster name takes printable glyphs only | enemy names take plain characters, apart from their badge | use plain letters; keep the {5e:xx} badge and $N suffix as in source: |
growing the record for a N-byte name would make it larger than any retail record | this enemy's record cannot grow that far | shorten the name |
unrecognized key shape | the key: was edited | restore the key |
no NUL-terminated string at this VA, no named monster record at this id, scene MAN not found, ... | the key does not match this disc | use the USA disc and unedited keys |
Text markup quick reference
Most text is written as-is. A few special forms keep the game's formatting working:
| Write | Means | Rule |
|---|---|---|
| | a new line inside the text box | move it to where your sentence should break |
{c1:00} | a character's name | keep it; it may move within the sentence |
{c2:..} {c3:..} {c5:..} | an item / magic / art name | keep it |
{cf:..} | a colour change | keep it, around the same words |
{ce:..} | a button, icon or number, such as {ce:00} = the X button | keep it, or add one; see buttons and icons |
other {xx:yy} | spacing and control codes | keep it |
{xx} | one special byte ({01} = item icon) | keep it |
{7b} / {7d} | a literal { / } | use these instead of typing braces |
The substituted names come from the tables you are also translating, so write sentences that stay grammatical whichever name appears.
Buttons and icons
{ce:NN} draws a picture inside the text: a controller button ({ce:00} is the X button), a gold or target badge, an equipment-slot icon, an element icon, or a number. Each has a name you can type instead, which reads better and imports as exactly the same bytes: {btn:x}, {btn:circle}, {icon:gold}, {icon:legs}, {icon:fire}, {icon:fire2}, and so on. On the workbench, the Symbols palette shows every one as your disc draws it (hover for its name) and inserts it where your cursor is; the dialog preview draws them in place. The full list, with every name, is in the pack format reference.
Accents
The game's own font draws plain English letters only. Type accents as you normally would and pick, once per pack, what happens to them:
- Draw them (
accents: fontin the pack, Draw them on the workbench): the patch adds accented letters to the game's font, built from your disc's own letters, and your text shows as typed. It covers the Western European accents (é è ê ë à â ä á ã å ç ñ í ì î ï ó ò ô ö õ ú ù û ü ÿ ß æ œ ¿ ¡ °and their capitals). - Fold to plain letters (
accents: fold):Épéeis writtenEpee. - Report them (the default): every accent is listed until you fold it or switch modes.
Letters outside that set (Polish ł, Czech č) fold to plain letters in both modes. Cyrillic, Greek, Chinese, Japanese and Korean cannot be drawn at all. The command-line import takes --accents font (or fold) to override the pack. Details: markup and encoding.
Automatic folding. A few characters word processors and AI tools like to insert are replaced for you: curly quotes become ' and ", en and em dashes and the minus sign become -, the ellipsis becomes ..., and a non-breaking space becomes a plain space. Anything else outside the font is reported, character by character.
Testing your translation
- Start from a fresh boot or a memory-card save. An emulator save state holds the memory of the disc it was made on, text included. Loaded onto your patched disc it shows the old text, or breaks if the disc was relaid out.
- Test on a copy. Keep your original image untouched; the tools never write to it.
- Read a scene's lines together. A text box shows up to three lines, and consecutive dialog entries in the pack are consecutive rows of the same box.
- Watch lists and labels. Byte room is not screen width; a long item name can run into the quantity column.
Glossary
- Language pack
- the YAML file holding the text and your translations
- Working pack
- a pack with the English
source:text; for your own use only - Shareable pack
- only your translations and keys; safe to share (also called a distributable pack)
- Key
- where a piece of text lives on the disc, such as
man:4:0x210 - Budget
- how many bytes a translation may take in place
- Byte
- one letter, digit or punctuation mark; a
{xx:yy}token is two - Scene / footprint
- one area of the game, and the fixed space its compressed dialog occupies on the disc
- Relayout
- growing a scene by whole sectors, shifting the rest of the disc
- PPF
- a small patch file that turns a clean disc into the patched one
- Token
- a
{...}code standing for a name, colour, icon or special byte
FAQ
- Is there a flag to let names grow?
- No - there is no
--relocate-names. A name longer than its slot moves automatically on every import. - Can I test with a save state?
- No. Boot the patched disc fresh, or load a memory-card save.
- What may I share publicly?
- The shareable pack and a PPF patch. Never a working pack, a lifted pack, or a patched disc image - they contain the game's own text and data.
- Can I use accents?
- Yes. Set the pack to Draw them (
accents: font) and the patch adds the accented letters to the game's font; see accents. - Russian, Greek, Japanese, Chinese, Korean?
- Not yet. Those scripts need far more letters than the game's font page holds, which these tools do not attempt.
- Can I start from someone else's pack?
- Yes: choose it and press Export a working copy of this pack, or pass
--resume their-pack.yamltotranslate init. - With the randomizer?
- Yes - pick a language and any randomizer options and patch once. Dialog is applied before the randomizer and names after it, so neither disturbs the other.
- My line is fine but still reported?
- Dialog is limited per scene, not per line; another line of the same scene may have used the room.
- The European disc?
- Packs are keyed to the USA disc. If you own a European or fan-translated disc, Translation from another disc I own turns its text into a pack for the USA disc (translations from another disc).
- The title-screen logo?
- Text drawn as a picture needs replacement artwork (text baked into textures).