Skip to content

How to create a new translation

Kelsey Higham edited this page Aug 26, 2024 · 14 revisions

Although Link’s Awakening was released in four different languages (Japanese, English, French, German), numerous fan translations popped up over the years.

Usually these translations resorted on binary hacking, Having a disassembly makes translating the game much easier.

This is a work in progress. Until this guide is completed, you can also browse Kelsey's translation guide and notes.

1. Setup

First, for your new target language, choose a two-letters code (ex. Esperanto -> EO)

Editing the Makefile

In the Makefile, duplicate the section for your source language. If you're editing the English version, duplicate the French or German version instead.

In this new section, replace every mention of your source language with your new language.

You'll typically want to replace:

  • The target name (ex. azlf.gbc -> azleo.gbc)
  • The language code (ex. -DLANG=FR -> -DLANG=EO)
  • The path to the directory containing localized resources (ex. revisions/G0/ -> revisions/E0)

Notes:

  • These compile flags set header values which aren't displayed in the game: --non-japanese, --title "ZELDA", --game-id "AZLX". They might get displayed by some emulators. You can change them, or leave them alone.
  • If you want, you can change the version. It gets passed to src/options.asm.
  • Once you've verified that everything works, you can delete the azlx-r1_LDFLAGS line. it just fills unused space with garbage data from another language's ROM, to match the checksum of the original release. Same for the filename at the end of the src/main.azlx-r1.o: line.

Editing src/options.asm

src/options.asm contains (among others) build options relevant to each language.

Copy-paste one of these blocks, and replace the original two-letters language code with your own (ex. ELIF ("{LANG}" == "FR") -> ELIF ("{LANG}" == "EO")).

Copying language-specific resources

Go to the revisions/ folder, and duplicate a directory (ex. revisions/F0 -> revisions/E0).

If you're translating from English, you can then copy the dialog files from src/text/*.asm to revisions/E0/src/text/: this will make a good base to work on.

Notes:

  • Even if you start from the English translation, basing your revisions/XX folder on an existing one will give you a good idea of the different elements to localize.

Compiling

Now make azleo.gbc should compile without errors. Let's get translating!

2. Translation

General structure

The source-code uses several ways to localize content:

  • Language-specific resources. These are files in the revisions/XX/ folders. A file present in the proper revisions/ folder automatically override the same file in the main source code. This is the main way to translate text or graphics.
  • Compile-time options. These are the options declared in src/options.asm. They tune a localized version in a specific way.
  • Ifdefs statements. These are IF "{LANG}" == "XX" statements in the assembly code files. They allow for a lot of fine tuning, but can get messy if used too much.

A localization will mostly make use of language-specific resources; but you may find the need to use the other available mechanisms.

Translating the main script

Simply edit the files in revisions/src/text/dialog_**.asm with your favorite text editor.

If you start from English, to make the localization process easier, the script mentions the speaker name before each dialog line.

Notes:

  • There are (almost) no restrictions on the script size. However, if your target language has way more words than English, the dialog files might excess the bank max size (4 Ki each). In that case, you'll probably want to add an extra dialog file.

    Try to use dialog5.asm first (it is only used in the Japanese version, and is empty in all other locales, but the space is available). Otherwise, add another file in an unused bank at the end of the ROM.

Translating the end credits

TODO

Translating the menus

The menus (file selection, name picker, save screen, game over, etc.) do not use strings stored as text. Instead they use directly tilemaps referencing the font tiles.

This means you'll need to:

  • translate the menu tiles (in src/gfx/menus/*.png),
  • then edit the tilemap for the different menus (in src/data/backgrounds/menu_*.tilemap.encoded).

See src/data/backgrounds/README.txt for how to decode the tilemaps, edit them, and re-encode them.

Notes:

  • You can also do binary hacking instead, and edit the raw encoded commands of the tilemaps. Depending on your programming background, this may be easier than setting up a tilemap editor.

Translating the other graphics

Many small localized graphics are scattered in the game:

  • Shop signs,
  • Map legend,
  • Printing UI,
  • etc.

These are mostly in revisions/XX/src/gfx/, and shouldn't be hard to localize: just edit the relevant PNG file.

Debugging

TODO: explain how to use the built-in language debugger.

3. Advanced modifications

Adding new characters to the dialogs font

The main font is stored in src/gfx/fonts/font.cgb.png. You can add new characters in the space available.

You'll then need to edit the dialogs charmap to be able to use your need character in the script (see src/constants/charmaps/dialogs.asm).

TODO: expand on this.

Adding new characters to the player name selection screen

The charmap is a little different: you'll need to to edit src/constants/charmaps/name_entry.asm.

You'll also need to add your new characters to the tilemap of the name picker menu.

TODO: explain how to do this.

Using the built-in diacritics support

The text engine supports the display of two different diacritics above the letters. By default, the Japanese version uses these for dakuten, and the German version for ümlauts. Enabling diacritics can be useful either to display real diacritics above a letter (like ~), or to display a letter or symbol to tall to fit in a single tile.

Compile with __DIACRITICS_SUPPORT__ = TRUE to enable support for diacritics.

By default, two diacritics are available. To use them, you should:

  1. Tweak the diacritic graphics to suit your needs.

    The diacritic tiles are stored three times, in three different tilesets:

    • inventory_overworld_items.dmg/cgb,
    • inventory_indoor_items.cgb,
    • ending_1.cgb (in the middle of the water splash tiles)
  2. Edit the charmap, to select which diacritic should be displayed over which letter.

    For this refer to the localized CodepointToDiacritic in codepoints_to_diacritic.asm.

Adding extra diacritics

Adding extra diacritics (to have more than the two available slots) is doable, but requires a bit more tweaking.

If you need more than two diacritics, you'll need to:

  • Edit the assembly code that uses CodepointToDiacritic, so that it can handle values other than 0, 1 and 2;
  • Add the new diacritic tile in a tileset, picking one that is always loaded when a dialog is present (not a lot of space is available there),
  • Add the new diacritic to the credits tileset (to use it in the Windfish dialog, if you ever need it).

The "Link's Awakening: Turbo Français" mod adds a new diacritic by swapping dynamically a tile used in the inventory. You can have a look at the diacritics-swapping commits – or find another solution; other ways are probably possible.

4. Reference projects

Here are some localization projects based on the disassembly. You can look at them for inspiration or reference.