PokéRogue's localization team puts immense effort into making the game accessible around the world, supporting over 12 different languages at the time of writing this document.
As a developer, it's important to help maintain global accessibility by effectively coordinating with the Translation Team on any new features or enhancements.
This document aims to cover everything you need to know to help keep the integration process for localization smooth and simple.
Before you continue, this document assumes:
#pokerogue-dev and related channels via #select-roles.
This is the easiest way to keep in touch with both the Translation Team and other like-minded contributors!pokerogue-locales submodulePokéRogue's translations are managed under a separate dedicated repository, pokerogue-locales.
This repository is integrated into the main one as a git submodule within the locales folder.
In essence, a submodule is a way for one repository (i.e. pokerogue) to use another repository (i.e. pokerogue-locales) internally.
The parent repo (the "superproject") houses a cloned version of the 2nd repository (the "submodule") inside it, making locales effectively a "repository within a repository", so to speak.
Many popular IDEs have integrated git support with special handling around submodules:
The following command will initialize your branch's assets and locales repository and update its HEAD:
pnpm update-locales
This command is run automatically after cloning, merging or changing branches, so you should rarely have to run it manually.
If you EVER run into issues with the locales submodule, try deleting the .git/modules/locales and locales folders before re-initializing it again.
This project uses the i18next library to integrate translations from locales into the source code.
The basic process for fetching translated text goes roughly as follows:
globalScene.phaseManager.queueMessage(
i18next.t("fileName:keyName", { arg1: "Hello", arg2: "an example", ... })
);
// from "en/file-name.json"...
{
"keyName": "{{arg1}}! This is {{arg2}} of translated text!"
}
If the key doesn't exist for the given language, the game will default to an appropriate fallback (usually the corresponding English key)."Hello! This is an example of translated text!"
If you have a feature or enhancement that requires additions or changes to in-game text, you will need to make a fork of the pokerogue-locales repo and submit your text changes as a pull request in addition to your pull request to the main project.
Since these two PRs aren't technically linked, it's important to coordinate with the Translation Team to ensure that both PRs are integrated safely into the project.
DO NOT HARDCODE PLAYER-FACING TEXT INTO THE CODE!
One perk of submodules is you don't actually need to clone the locales repository to start contributing - git already does that for you on initialization.
Given pokerogue-locales is a full-fledged git repository inside pokerogue, making changes is roughly the same as normal, merely using locales as your root directory.
Make sure to checkout or rebase onto upstream/main (pnpm update-locales:remote) BEFORE creating a locales PR!
The checked-out commit is based on the superproject's SHA-1 by default, so hastily making changes may see you basing your commits on last week's HEAD.
When a new feature or enhancement requires adding a new locales key without changing text in existing keys, we have the following workflow with regards to localization:
i18next key pointing to where you plan to add it into the locales repository.pokerogue-locales repository — adding a new entry with text for each key you added to your main PR.
pokerogue-locales.[^2]: For those wondering, the reason for choosing English specifically is due to it being the master language set in Pontoon (the program used by the Translation Team to perform locale updates). If a key is present in any language except the master language, it won't appear anywhere else in the translation tool, rendering missing English keys quite a hassle.
The Dev and Translation teams have strict requirements for ensuring consistency of newly added locales entries.
PRs failing these requirements will not be mergeable into locales!
kebab-case. Example: trainer-names.jsoncamelCase. Example: aceTrainersnake_case for the context extension[^3]. Example: aceTrainer_male[^3]: If your PR introduces a new context extension not already used in the codebase, the validation workflow will be unable to detect it and flag it as invalid.
To fix this, update the i18nextKeyExtensions array with the new entries.
PRs that modify existing text have different risks with respect to coordination between development and translation, so their requirements are slightly different:
beta.After making a PR involving any outwards-facing behavior (but especially locales-related ones), it's generally considered good practice to attach proof of those changes working in-game.
The basic procedure is roughly as follows:
git integration support doing this from the GUI, cd locales
git checkout your-branch-name-here
overrides.ts to values corresponding to the interactions being tested.pnpm start:dev) and open localhost in your browser.[^4]: For those lacking a dedicated screen capture software, OBS Studio is a popular open-source option, available on all major OSes.
For those aiming to film their changes, bear in mind that GitHub has a hard 10mB limit on uploaded media content. If your video is too large, consider making it shorter or downscaling the quality.
Put simply, stating that a PR exists makes it much easier to review and merge.
The easiest way to do this is by pinging the current Head of Translation in the community Discord (ideally in #pokerogue-dev or similar).
The current Head of Translation is:
@lugiadrien (@Adri1 on GitHub)
If you have any questions about the developer process for localization, don't hesitate to ask! Feel free to contact us on Discord - the Dev Team and Translation Team will be happy to answer any questions.