Community localization support for Beat Saber and its mods. Created by @nicoco007 and @Auros.
Requires SiraUtil 3.0.0 or greater.
The community has unofficially translated the base game into the following languages:
- Chinese (Simplified)
- Chinese (Traditional)
- Dutch
- French
- German
- Hebrew
- Hungarian
- Italian
- Japanese
- Korean
- Portuguese (Brazilian)
- Russian
- Swedish
See CONTRIBUTORS for a list of everyone who has helped make SiraLocalizer possible!
Since SiraLocalizer is built on top of the game's regular localization system, you can change the language in-game normally by going to Options > Settings > Others. There are additional settings made available to manage translation updates.
Translation contributors and information regarding which mods are supported is given under the language selection dropdown. The example below shows information for the French translation:
See CONTRIBUTING.
This section is under construction!
Beat Saber uses a customized version of the Polyglot Unity package for translations. It uses translation keys as unique identifiers for translated text across the game. Therefore, wherever there is text in your mod, it should be replaced with something that can convert a translation key into localized text.
BeatSaberMarkupLanguage now supports translating various text elements with the -key
suffix (e.g. text-key
for text, tab-name-key
for tabs, etc.). More documentation regarding this is coming soon. If you are displaying text through other means, you can use the Polyglot.Localization.Get(string)
and Polyglot.Localization.GetFormat(string, params object[])
methods to get localized strings in the current language.
Here are some guidelines for creating good translation keys:
- A translation key should succinctly describe the text it represents. There is no hard limit on length, but it shouldn't just be the whole sentence.
- By convention, translation keys should be in SCREAMING_SNAKE_CASE (uppercase letters, words separated by underscores).
- Context is very important when translating. Avoid re-using the same key at multiple places even if the English text is the same unless the context is identical.
- To avoid collisions with base game keys and other mods' keys, all the keys you add should have a prefix that uniquely identifies your mod.
Polyglot's file format is very straightforward: the first column is the translation key, the second column is context to help translators, and the rest of the columns are translations following the order in the Locale enum.
If you plan on using SiraLocalizer for translations, this is what your mod's CSV file should look like:
Polyglot,100,,,,,,,,,,,,,,,,,,,,,,,,,,,,
"KEY_NAME_1","Context for 1 if necessary","English String 1",,,,,,,,,,,,,,,,,,,,,,,,,,,
"KEY_NAME_2","Context for 2 if necessary","English String 2",,,,,,,,,,,,,,,,,,,,,,,,,,,
The first line is required for Polyglot to properly identify the file. Also, note the trailing commas – these are important since Polyglot expects exactly 28 languages and will not fall back to the English text if these commas are not present and translations are missing. Therefore, there should be at least 27 commas after the English text.
Below is an example of how to add your CSV file to Polyglot.
[HarmonyPatch(typeof(LocalizationAsyncInstaller), "LoadResourcesBeforeInstall")]
internal class LocalizationLoader
{
public static void Prefix(IList<TextAsset> assets)
{
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Assembly.Path.To.Your.translations.csv"))
using (StreamReader reader = new StreamReader(stream))
{
string content = reader.ReadToEnd();
assets.Add(new TextAsset(content));
}
}
}
If everything works properly, translations keys should now show up as the English text you wrote in the CSV file.
Registering your mod to be translated by the SiraLocalizer team is simple. First, fill out this request form (coming soon). If it the first time you request translations, you will be given an ID for your mod. Once you have this ID, simply add this JSON object to your manifest's features
object:
"SiraLocalizer.LocalizedPlugin": {
"id": "your-mod-id",
"resourcePath": "Assembly.Path.To.Your.translations.csv"
}
Once translations are available, they will automatically be downloaded by SiraLocalizer.